Do you need an in depth, step-by-step walkthrough of how to deal with Umbraco version upgrades from version 7 to version 8? Then this is the post for you!
Over the last year, we have upgraded several of our clients from Umbraco version 7 to Umbraco version 8. With each upgrade we find small surprises that we get to work through. This post shares what we have learned so far.
Disclaimer: this post won't go into detail on a lot of the code changes that need to be made. We won't try to list or describe how to write custom Examine indexes in Umbraco 8 or how to convert an ApplicationStarting event handler in Umbraco 7 to Umbraco 8 Composers and Compositions. Instead, this is more of a roadmap to an Umbraco 8 upgrade that focuses on solving problems upgrading the database without losing data.
Umbraco 8 upgrades are complex and every Umbraco site is different. You will almost certainly have to add your own steps throughout the process and will run into unique challenges, but we think the following steps will get you close.
Things to know before you get started
What is a Migration?
In Umbraco 7.3.9, Umbraco introduced the concept of Migrations. A Migration in Umbraco is a one-off process that is run automatically when the site starts up. Umbraco uses Migrations to apply database changes during Umbraco upgrades. The executions of these migrations are tracked in the database, so Umbraco is able to tell which migrations have already been run.
Developers can write their own, custom Umbraco Migrations to automate any one-off process. ProWorks uses migrations to help migrate from one datatype to another without data loss. We created an Umbraco 7 package called Our.Umbraco.Migration to help developers bootstrap their own migrations into an Umbraco site. It comes with built in migration base classes which convert Content, Media, and Member pickers from id pickers to udi pickers. We also wrote a Skrift article about using Migrations: Skrift: Umbraco Migrations Made Easy
Important Umbraco Version Thresholds
These are important Umbraco version "thresholds" to be mindful of when upgrading Umbraco sites. Some of these are breaking changes that have bit us in the past. Others are just versions where important features are released.
When upgrading past Umbraco 7.3.0
Make sure any and all public access settings at "/App_Data/access.config" are present on disk at the time of the upgrade. The public access settings are migrated to the database at this time and if the settings are not present at /App_Data/access.config, you will miss your chance to have all of the public access settings migrated automatically.
This is where the "umbracoMigrations" table is introduced. From this point forward, Umbraco is better able to handle the database components of Umbraco upgrades. Once an Umbraco site reaches this point, developers can begin to write custom migrations of their own.
When upgrading past Umbraco 7.6.0
Umbraco added Udis to the database in Umbraco 7.6.0. The primary way to uniquely identify Umbraco nodes changed from the node id to the Udi. New versions of the Content, Media, and Member Picker property editors were created to pick these nodes by Udi instead of node id. At this point, migrations can be written to convert any and id pickers to Udi pickers. The migrations do not need to be added immediately, but this is the earliest that they can be added.
When upgrading past Umbraco 7.7.0
Umbraco changed the member role system from being user based to role/group based. The user specific permissions that the content editors are familiar with will be converted to role based permissions. You will notice new "migrated section access" groups. One of these new groups is created for each combination of specific user permissions. This is an important change to inform content editors of.
Umbraco.NestedContent was added to the Umbraco core. At this point, migrations can be written to convert any and all Our.Umbraco.NestedContent data to the new, core Umbraco.NestedContent. The migrations do not need to be added immediately, but this is the earliest that they can be added.
When upgrading past Umbraco 7.14.0
The Umbraco.MultiUrlPicker was added to the Umbraco core. At this point, migrations can be written to convert any and all RJP.MultiUrlPicker data to the new, core Umbraco.MultiUrlPicker. The migrations do not need to be added immediately, but this is the earliest that they can be added.
When upgrading past Umbraco 7.15.0
Umbraco released the following fix: issues/3869. The purpose is to handle cases where content editors upload new images to existing media items that are picked in rich text editors. In these cases, the data in the rich text editors would still point to the old media file. This new feature updates the media path at render time using the "data-udi" property on the <img> tag. This is a great feature. However, we have found that some content editors who are more familiar with html will sometimes edit the img src manually. If content editors are in the habit of doing this, when the site is upgraded past Umbraco 7.15.0, the images edited this way could display the wrong file.
When upgrading past Umbraco 8.0.0
There is a bug during the Umbraco 8 upgrade that will cause published nodes to become unpublished when those nodes have versions in the database that are saved but not published. A migration must be added to tweak the database and fix each of these unpublished nodes.
Overview of Upgrade Process
This is the birds eye view to all of the steps that go into an Umbraco 7 to Umbraco 8 upgrade. To help conceptualize an Umbraco upgrade, I find it helps to separate the upgrade of the database from the upgrade of the files in my mind. I'll list the upgrade steps for each separately below.
Upgrade the Umbraco database
Umbraco is getting better and better about supporting upgrades, but some of the earlier v7 upgrades are a still little more rough. When Upgrading to latest v7 and v8, there are some intermediate upgrades that must be completed first. You have to take a pit stop at each of these on your way to the latest and greatest. Below is a list of the intermediate upgrades and a short description of why we need to stop at each of these.
For each of the "Upgrade Umbraco database" steps below, you can point a vanilla Umbraco site of the new version at the existing Umbraco database and run through the upgrade wizard. This allows you to focus on the database upgrade without spending time moving and merging config files. Step #4 where the custom migrations run is the most complex part of the database upgrade.
Upgrade the Umbraco database to 7.3.9Umbraco introduces Migrations
Upgrade the Umbraco database to 7.6.14Umbraco introduces UDIs. Stop here to prevent errors during the upgrade.
Upgrade the Umbraco database to 7.15.x (latest v7)
Run custom v7 Migrations to convert datatypes
- Node Id Pickers to Udi Pickers
- RJP.MultiUrlPicker (or other link picker) to Umbraco.MultiUrlPicker
- Our.Umbraco.NestedContent to Umbraco.NestedContent
- Our.Umbraco.StackedContent to Umbraco.BlockList
- Other datatypes that might need migration
- Upgrade the Umbraco database to the latest v8 with the ProWorks.Umbraco8.Migrations package
Run custom v8 Migrations as needed
Upgrade the files
This upgrade of the files can usually happen after the Umbraco database upgrade to v8 complete.
- Fix any custom code, so the site compiles. This includes an upgrade of the project to .NET Framework 4.7.2
- Fix the templates
- Deal with packages and extensions. Update/replace packages with v8 equivalents or remove them
Step By Step
Here it is. This is probably what everyone really wants to see. This is a step by step process to upgrading an Umbraco 7 site to an Umbraco 8 site.
Step 1: Upgrade the Umbraco database to 7.3.9
- Download a vanilla Umbraco 7.3.9 site
- Ensure that any public access data in your "/App_Data/access.config" is in place on the vanilla 7.3.9 site
- Point the vanilla 7.3.9 site at the Umbraco database you want to upgrade
- Run through the upgrade wizard
Step 2: Upgrade the Umbraco database to 7.6.14
- Download a vanilla Umbraco 7.6.14 site
- Point the vanilla 7.6.14 site at the Umbraco database you want to upgrade
- Run through the upgrade wizard
Step 3: Upgrade the Umbraco database to 7.15.6 (or latest)
- Download a vanilla Umbraco 7.15.6 site
- Point the vanilla 7.15.6 site at the Umbraco database you want to upgrade
- Run through the upgrade wizard
Step 4: Run v7 migrations to convert node id pickers to Udi pickers
Prior to Umbraco 7.6.0, the node pickers (Content Picker, Media Picker, Member Picker, Related Links, and Multinode Treepicker) all picked nodes by node id. New versions of these pickers that picked by udi have been introduced and before upgrading to Umbraco 8, all of the datatypes should be migrated to the new property editors and the data in the database should be converted to avoid data loss. ProWorks has written migrations to handle the following datatype conversions already:
- Umbraco.RelatedLinks to Umbraco.RelatedLinks2
- Umbraco.MultiNodeTreePicker to Umbraco.MultiNodeTreePicker2
- Umbraco.MultipleMediaPicker to Umbraco.MediaPicker2
- Umbraco.ContentPicker to Umbraco.ContentPicker2
- Umbraco.MediaPicker to Umbraco.MediaPicker2
- Umbraco.MemberPicker to Umbraco.MemberPicker2
We perform all of the above datatype migrations using the Our.Umbraco.Migrations package we created. To perform the above migrations using the Our.Umbraco.Migrations package follow these steps:
- Install the Our.Umbraco.Migrations package via nuget
- Add the following to the web.config
<configuration> <migrationResolvers> <add name="ProductMigrations" type="Our.Umbraco.Migration.ProductMigrationResolver, Our.Umbraco.Migration"> <add key="MonitoredProductNames" value="ProWorks.Default.IdToUdi" /> </add> </migrationResolvers> </configuration>
Step 5: Run v7 migration to convert link pickers to the Umbraco.MultiUrlPicker
In all of our Umbraco 7 sites, we installed and made use of the RJP.MultiUrlPicker package for our link pickers. In Umbraco 7.14.0, Umbraco pulled it into the core. If your site uses the RJP.MultiUrlPicker property editor, it will need to be converted to the Umbraco.MultiUrlPicker before you upgrade to Umbraco 8. There is no migration required. The values picked in the database are similar enough. You just need to locate the datatypes and select the new Umbraco.MultiUrlPicker property editor.
If your site makes use of a different 3rd party link picker. You should check to see if that link picker is supported in Umbraco 8. If not, consider writing a migration to convert the datatypes and data to the Umbraco.MultiUrlPicker.
Step 6: Convert Our.Umbraco.NestedContent to Umbraco.NestedContent
In Umbraco 7.7.0, Umbraco pulled the 3rd party Our.Umbraco.NestedContent property editor into the core. If your site uses the Our.Umbraco.NestedContent property editor, it will need to be converted to the Umbraco.NestedContent property editor before you upgrade to Umbraco 8. There is no migration required. The values picked in the database are similar enough. You just need to locate the datatypes and select the new Umbraco.NestedContent property editor.
If your site makes use of any other similar packages like Our.Umbraco.StackedContent, consider writing a migration to convert the datatypes and data to the Umbraco.NestedContent. In Umbraco 8, a new property editor called the Block List Editor was created. You could also wait until Umbraco 8 and attempt to migrate your data to the Block List Editor.
Step 7: Upgrade the Umbraco database to the latest version of Umbraco 8
Step 9: Nuget install Umbraco 8.x.x (latest) into your project
See the following nuget packages:
Step 10: Upgrade the projects to .NET Framework 4.7.2
Step 11: Convert Umbraco 7 code to Umbraco 8 so that the site compiles
In Umbraco 7, when you log errors you might make a call that looks like the following with the exception as the final argument of the method.
In Umbraco 8, when you log an error, the exception is the first argument. If you don't fix this, it won't throw any exceptions. It will just ruin your logs.
Step 12: Convert Umbraco 7 Views, Partial Views, and Macros to Umbraco 8
I won't go into detail here. See the Umbraco 8 documentation on rendering content.
I found a small breaking change with the ".Siblings()" method that I hadn't seen documented elsewhere, so I'm describing that here. In Umbraco 7, calling ".Siblings()" would retrieve a list of sibling nodes including self. In Umbraco 8, if you want the same effect, call ".SiblingsAndSelf()".
Step 13: Deal with packages and extensions. Update/replace packages with v8 equivalents or remove them
Step 14: Add custom v8 migrations as needed
You may encounter other issues not covered here with custom components and controls. You, or the package developer, may need to create custom migrations to convert the database content from the v7 version to their v8 version. You can see an example of how to do this in the source code for the ProWorks.Umbraco8.Migrations package. In particular, take a look at the ProWorksMigrationComponent and ProWorksMigrationPlan classes for examples of how to register and trigger your custom migrations.
Let us know in the comments if you have any questions or if we need to clear anything up!