Continuing on from the Drupal 9 to Drupal 10 upgrade outline written earlier... Upgrading Drupal 9 to Drupal 10. However, the point of difference is this article works through the actual action steps of the upgrade.
Planning and testing is critical for the Drupal to version 10 process to work successfully. As some of the environments that I work in are deployed via CD/CI pipelines.
Resource settings
Type | Version |
---|---|
Drush | 11.6.0 |
Drupal | 9.5.10 |
1. Download and enable the Upgrade Status
Run the following command to install the Upgrade Status module:
composer require 'drupal/upgrade_status:^4.0'
In the admin > extend area, enable the Upgrade Status module. Or if you want to work in Terminal then run the command
drush en upgrade_status
Upgrade Status error
Whilst attempting to add Upgrade Status you experience the following error
Your requirements could not be resolved to an installable set of packages.
Problem 1
- drupal/upgrade_status[4.0.0, ..., 4.1.0] require nikic/php-parser ^4.0.0 -> found nikic/php-parser[v4.0.0, ..., v4.19.1] but the package is fixed to v5.0.2 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
- Root composer.json requires drupal/upgrade_status ^4.0 -> satisfiable by drupal/upgrade_status[4.0.0, 4.1.0].
Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.
As outlined on Upgrade Status module page (https://www.drupal.org/project/upgrade_status), one option is to remove Drush and work through a re-install process. However, rather than follow this process, I opted to run the following
composer require 'drupal/upgrade_status:^4.0' --with-all-dependencies
This action resulted in a downgrade of the offending package. Plus installing
Downgrading nikic/php-parser (v5.0.2 => v4.19.1)
2. Review the current status of the Drupal environment
As the Upgrade Status module has been enabled, you can review the status of your environment. Go to
{path}/admin/reports/upgrade-status
Current overview
Gather data | Fix incompatibilities | Relax |
---|---|---|
|
Drupal core and hosting environment
Requirement | Status |
---|---|
Drupal core should be at least 9.4.x | Version 9.5.10. |
PHP version should be at least 8.1.0. Before updating to PHP 8, use $ composer why-not php 8.1 to check if any projects need updating for compatibility. Also check custom projects manually. |
Version 8.1.18 |
Database JSON support required | Supported. |
Invalid permissions will trigger runtime exceptions in Drupal 10. Permissions should be defined in a permissions.yml file or a permission callback. |
None found.
|
Deprecated or obsolete core extensions installed. These will be removed in the next major version. | Color (read more), HAL (read more), RDF (read more), Stable (read more) |
Modules to be removed as they're not installed
Module | Status | Version |
---|---|---|
Google Authenticator login (ga_login) | uninstalled | 8.x-1.0-alpha7 |
Search API Synonym (search_api_synonym) | uninstalled | N/A |
Webform (webform) | uninstalled | 6.1.5 |
Modules to be updated
Module | Status | Version |
---|---|---|
Menu Breadcrumb (menu_breadcrumb) | installed | 8.x-1.16 |
Title length (title_length) | installed | 8.x-1.2 |
3. Remove uninstalled modules
As noted above, the following modules need to be removed:
- Google Authenticator login (ga_login)
- Media Delete media (media_delete_all)
- Search API Synonym (search_api_synonym)
- Webform (webform)
If you have installed these using the correct method - that is using composer, then using the module alias references you can use Terminal. Run the composer remove command line
composer remove drupal/ga_login
composer remove drupal/media_delete_all
composer remove drupal/search_api_synonym
composer remove drupal/webform
4. Update flagged modules & themes
Modules that require upgrading
Update the contrib modules that were identified through the upgrade status module noted above:
- Menu Breadcrumb (menu_breadcrumb)
- Title length (title_length)
The following Drush commands were run to install the listed module
composer require 'drupal/menu_breadcrumb:^2.0@alpha' 'drupal/title_length:^2.0@RC'
Modules that need to be reviewed
By reviewed these modules either needed to be removed or upgraded.
- Color - will be removed as not required
- HAL
- RDF
Each of the above modules have been removed from core... and are available as contrib projects.
Module | Version | URL | Drupal version |
---|---|---|---|
Color | 1.0.3 | https://www.drupal.org/project/color | ^9.4 |
HAL | 2.0 | https://www.drupal.org/project/hal | ^10 |
RDF | ^2.1 | https://www.drupal.org/project/rdf | ^9.4 || ^10.0 |
In this instance, only HAL will be kept and therefore upgraded. But only when Drupal has been upgraded to 10 in this environment.
composer require 'drupal/hal:^2.0'
Command line uninstalling the others
drush pm:uninstall color
drush pm:uninstall hal
drush pm:uninstall rdf
Module that need to collaborate with maintainers
The modules that fall under this category are a couple of custom modules and one contrib module.
Module | Version | URL | Drupal version |
---|---|---|---|
Content import | 8.x-9.3 | https://www.drupal.org/project/contentimport | ^8.7.7 || ^9 |
Note on the page is this project is not covered by the security advisory policy. Given it's status and the requirement for it on the site is not required. It will be removed.
drush pm:uninstall contentimport
The Content Import module also needed to be removed
composer remove drupal/contentimport
Themes that need to be removed
The following themes need to be removed as they have been deprecated
- Bartik
- Stable
However, Stable in Drupal 10 is Stable9. Note, if any of your themes are dependant on either of these, you will to act on this first before you can uninstall the theme.
drush theme:uninstall bartik
drush theme:uninstall stable
5. Review the server environment
As completed earlier, cross check that the changes have removed the 'Deprecated or obsolete core extensions installed. These will be removed in the next major version' notice.
Requirement | Status |
---|---|
Drupal core should be at least 9.4.x | Version 9.5.10. |
PHP version should be at least 8.1.0. Before updating to PHP 8, use $ composer why-not php 8.1 to check if any projects need updating for compatibility. Also check custom projects manually. |
Version 8.1.18 |
Database JSON support required | Supported. |
Invalid permissions will trigger runtime exceptions in Drupal 10. Permissions should be defined in a permissions.yml file or a permission callback. |
None found.
|
Deprecated or obsolete core extensions installed. These will be removed in the next major version. | None installed. |
Notes:
- Compatible with next major Drupal core version: 73 projects
- Environment checks passed
Having completed the preliminary work, the site is ready to be upgraded to Drupal 10.
6. Preparation of the server directories
Now that you have prepared your site, your first step in the upgrade process is to temporarily add write access to protected files and directories:
chmod -R 777 sites/default
chmod 666 sites/default/*settings.php
chmod 666 sites/default/*services.yml
7. Update the composer.json file
composer require 'drupal/core-recommended:^10' 'drupal/core-composer-scaffold:^10' 'drupal/core-project-message:^10' --update-with-dependencies --no-update
As core-dev exists
composer require 'drupal/core-dev:^10' --dev --update-with-dependencies --no-update
8. Drush version
Check the current version of Drush being used, as Drupal 10 is best to run off Drush 12
drush --version
Response
Drush Commandline Tool 11.6.0
Prepare the update to version by
composer require 'drush/drush:^12' --no-update
9. Time to perform the update
With the preparation completed, let's run the update
composer update
Errors post running composer update
Your requirements could not be resolved to an installable set of packages.
Problem 1
- zendframework/zend-feed[2.11.0, ..., 2.12.0] require php ^5.6 || ^7.0 -> your php version (8.1.18) does not satisfy that requirement.
- laminas/laminas-feed[2.12.0, ..., 2.12.3] require php ^5.6 || ^7.0 -> your php version (8.1.18) does not satisfy that requirement.
- symfony-cmf/routing[1.4.0, ..., 1.4.1] require php ^5.3.9|^7.0 -> your php version (8.1.18) does not satisfy that requirement.
- drupal/core[8.9.11, ..., 8.9.20] require php ^7.0.8 -> your php version (8.1.18) does not satisfy that requirement.
- drupal/core[9.0.10, ..., 9.0.14] require php ^7.3 -> your php version (8.1.18) does not satisfy that requirement.
- laminas/laminas-feed[2.13.0, ..., 2.14.1] require php ^7.3 || ~8.0.0 -> your php version (8.1.18) does not satisfy that requirement.
- Root composer.json requires drupal/contentimport ^9.3 -> satisfiable by drupal/contentimport[9.3.0].
- drupal/core-recommended 10.0.2 requires drupal/core 10.0.2 -> satisfiable by drupal/core[10.0.2].
- Conclusion: don't install drupal/core 10.0.2 (conflict analysis result)
- drupal/core-recommended 10.0.3 requires drupal/core 10.0.3 -> satisfiable by drupal/core[10.0.3].
- Conclusion: don't install drupal/core 10.0.3 (conflict analysis result)
- drupal/core-recommended 10.0.4 requires drupal/core 10.0.4 -> satisfiable by drupal/core[10.0.4].
- Conclusion: don't install drupal/core 10.0.4 (conflict analysis result)
- drupal/core-recommended 10.0.5 requires drupal/core 10.0.5 -> satisfiable by drupal/core[10.0.5].
- Conclusion: don't install drupal/core 10.0.5 (conflict analysis result)
- drupal/core-recommended 10.0.6 requires drupal/core 10.0.6 -> satisfiable by drupal/core[10.0.6].
- Conclusion: don't install drupal/core 10.0.6 (conflict analysis result)
- drupal/core-recommended 10.0.7 requires drupal/core 10.0.7 -> satisfiable by drupal/core[10.0.7].
- Conclusion: don't install drupal/core 10.0.7 (conflict analysis result)
- drupal/core-recommended 10.0.8 requires drupal/core 10.0.8 -> satisfiable by drupal/core[10.0.8].
- Conclusion: don't install drupal/core 10.0.8 (conflict analysis result)
- drupal/core-recommended 10.0.9 requires drupal/core 10.0.9 -> satisfiable by drupal/core[10.0.9].
- Conclusion: don't install drupal/core 10.0.9 (conflict analysis result)
- drupal/core-recommended 10.0.10 requires drupal/core 10.0.10 -> satisfiable by drupal/core[10.0.10].
- Conclusion: don't install drupal/core 10.0.10 (conflict analysis result)
- drupal/core-recommended 10.1.0 requires drupal/core 10.1.0 -> satisfiable by drupal/core[10.1.0].
- Conclusion: don't install drupal/core 10.1.0 (conflict analysis result)
- drupal/core-recommended 10.1.1 requires drupal/core 10.1.1 -> satisfiable by drupal/core[10.1.1].
- Conclusion: don't install drupal/core 10.1.1 (conflict analysis result)
- drupal/core-recommended 10.1.2 requires drupal/core 10.1.2 -> satisfiable by drupal/core[10.1.2].
- Conclusion: don't install drupal/core 10.1.2 (conflict analysis result)
- drupal/core-recommended 10.1.3 requires drupal/core 10.1.3 -> satisfiable by drupal/core[10.1.3].
- Conclusion: don't install drupal/core 10.1.3 (conflict analysis result)
- drupal/core[8.4.0, ..., 8.9.10] require symfony-cmf/routing ^1.4 -> satisfiable by symfony-cmf/routing[1.4.0, 1.4.1].
- drupal/core[8.2.0, ..., 8.3.9] require symfony-cmf/routing ~1.4 -> satisfiable by symfony-cmf/routing[1.4.0, 1.4.1].
- drupal/core[8.8.0, ..., 8.8.12] require zendframework/zend-feed ^2.12 -> satisfiable by laminas/laminas-feed[2.12.0, ..., 2.19.0], zendframework/zend-feed[2.12.0].
- drupal/core-recommended 10.0.1 requires drupal/core 10.0.1 -> satisfiable by drupal/core[10.0.1].
- Conclusion: don't install drupal/core 10.0.1 (conflict analysis result)
- drupal/contentimport 9.3.0 requires drupal/core ^8 || ^9 -> satisfiable by drupal/core[8.0.0, ..., 8.9.20, 9.0.0, ..., 9.5.10].
- You can only install one version of a package, so only one of these can be installed: drupal/core[8.0.0, ..., 8.9.20, 9.0.0, ..., 9.5.10, 10.0.0, ..., 10.1.3].
- You can only install one version of a package, so only one of these can be installed: drupal/core[8.1.2, ..., 8.9.20, 9.0.0, ..., 9.5.10, 10.0.0, ..., 10.1.3].
- You can only install one version of a package, so only one of these can be installed: drupal/core[8.1.8, ..., 8.9.20, 9.0.0, ..., 9.5.10, 10.0.0, ..., 10.1.3].
- You can only install one version of a package, so only one of these can be installed: drupal/core[8.7.0, ..., 8.9.20, 9.0.0, ..., 9.5.10, 10.0.0, ..., 10.1.3].
- drupal/core-recommended 10.0.0 requires drupal/core 10.0.0 -> satisfiable by drupal/core[10.0.0].
- Root composer.json requires drupal/core-recommended ^10 -> satisfiable by drupal/core-recommended[10.0.0, ..., 10.1.3].
Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.
Solution to the above error
Whilst this didn't occur for this upgrade, an issue like this was based on not having removed a contrib module that couldn't be migrated to Drupal 10. Make sure you have worked through all of the modules being flagged as an issue via the upgrade status.
Whilst adding this, I also added the following new modules:
Module | Version | URL |
---|---|---|
Gin | 8.x-3.0-rc6 | https://www.drupal.org/project/gin |
To install the Gin theme use
composer require drupal/gin_toolbar:^1.0@rc drupal/gin:^3.0@rc
Back on track.
10. Update the database
Perform this action by running
drush updatedb
Response
------------------ ------------------------------- --------------- -------------------------------------------------------------------------------
Module Update ID Type Description
------------------ ------------------------------- --------------- -------------------------------------------------------------------------------
system 10100 hook_update_n 10100 - Remove the year 2038 date limitation.
block_content 10100 hook_update_n 10100 - Update entity definition to handle revision routes.
block_content 10200 hook_update_n 10200 - Remove the unique values constraint from block content info fields.
comment 10100 hook_update_n 10100 - Remove the year 2038 date limitation.
dblog 10100 hook_update_n 10100 - Remove the year 2038 date limitation.
dblog 10101 hook_update_n 10101 - Converts the 'wid' of the 'watchdog' table to a big integer.
history 10100 hook_update_n 10100 - Remove the year 2038 date limitation.
migrate 10100 hook_update_n 10100 - Remove the year 2038 date limitation.
redirect 8109 hook_update_n 8109 - Enable reset button for Redirect View.
title_length 8002 hook_update_n 8002 - Activate node_title_length submodule for active projects.
tracker 10100 hook_update_n 10100 - Remove the year 2038 date limitation.
user 10000 hook_update_n 10000 - Remove non-existent permissions created by migrations.
block_content block_library_view_permission post-update Update block_content 'block library' view permission.
block_content move_custom_block_library post-update Moves the custom block library to Content.
block_content sort_permissions post-update Update permissions for users with "administer blocks" permission.
editor image_lazy_load post-update Enable filter_image_lazy_load if editor_file_reference is enabled.
file add_permissions_to_roles post-update Grant all non-anonymous roles the 'delete own files' permission.
media oembed_loading_attribute post-update Add the oEmbed loading attribute setting to field formatter instances.
responsive_image image_loading_attribute post-update Add the image loading settings to responsive image field formatter instances.
responsive_image order_multiplier_numerically post-update Re-order mappings by breakpoint ID and descending numeric multiplier order.
system enable_password_compatibility post-update Enable the password compatibility module.
system linkset_settings post-update Add new menu linkset endpoint setting.
system timestamp_formatter post-update Update timestamp formatter settings for entity view displays.
text allowed_formats post-update Add allowed_formats setting to existing text fields.
views boolean_custom_titles post-update Update Views config schema to make boolean custom titles translatable.
views fix_revision_id_part post-update Fix '-revision_id' replacement token syntax.
views oembed_eager_load post-update Add eager load option to all oembed type field configurations.
views responsive_image_lazy_load post-update Add lazy load options to all responsive image type field configurations.
views timestamp_formatter post-update Update timestamp formatter settings for views.
------------------ ------------------------------- --------------- -------------------------------------------------------------------------------
Reset the permissions that were altered earlier
If completed, then change the permissions that were altered at the start
chmod -R 755 sites/default
chmod 644 sites/default/*settings.php
chmod 644 sites/default/*services.yml
Review the Status Report
If you have any issues, read through the Errors / issues below. You might be experiencing similar issues to us.
Otherwise, if all going well, then let's cross check status report (Admin > Reports > Status Report).
Status Report - Errors
The first batch of errors:
Area | Notes or details |
---|---|
Search API | The following search servers are not available: General, Related |
Solr Server General | Solr not reachable Solr server General is not reachable. |
Solr Server Related | Solr not reachable Solr server Related is not reachable. |
The Solr errors I'll leave as there related to the server.
Status Report - warnings
Area | Notes or details | Solution |
---|---|---|
Color Field library: jQuery Simple Color |
Missing If you want to use the Simple Color widget, you must download the jQuery Simple Color library and copy it to /app/web/libraries/jquery-simple-color/ |
Download library from https://github.com/recurser/jquery-simple-color |
Color Field library: Spectrum |
Missing If you want to use the Spectrum widget, you must download the Spectrum Library and copy it to /app/web/libraries/spectrum/ |
Download the library from https://github.com/bgrins/spectrum |
Configuration files |
Protection disabled
|
The permissions noted above are correct. If you see this error, then check if hardening has been activated. If so, you'll need to add to your settings.php file the following line
|
Deprecated modules enabled | Deprecated modules found: Activity Tracker. | Uninstall listed modules |
Media | It is potentially insecure to display oEmbed content in a frame that is served from the same domain as your main Drupal site, as this may allow execution of third-party code. You can specify a different domain for serving oEmbed content here. | |
SameSite cookie attribute |
Not set This attribute should be explicitly set to Lax, Strict or None. If set to None then the request must be made via HTTPS. See PHP documentation |
|
Transaction isolation level |
REPEATABLE-READ The recommended level for Drupal is "READ COMMITTED". See the setting MySQL transaction isolation level page for more information. |
Errors / issues
Theme issue
When working on updating a custom theme from Drupal 9 to Drupal 10, the theme used Stable as a base theme. However, this needs to be changed to Stable9 to work in Drupal 10. However, I came across a curious issue I had the following error.
Drupal\Core\Theme\MissingThemeDependencyException: Base theme stable9 has not been installed. in Drupal\Core\Theme\ThemeInitialization->getActiveThemeByName() (line 122 of core/lib/Drupal/Core/Theme/ThemeInitialization.php)
To resolve this error, I manually installed Stable9 using Drush
drush theme:enable stable9
Response
[success] Successfully installed theme: stable9