Upgrade-in-place: Drupal 8 with Build Tools
Upgrade a Pantheon Drupal 8 site with Build Tools to a Drupal 9 site with Build Tools
Contributors: Tom Stovall, Edward Angert, Carolyn Shannon.
Discuss in our Forum Discuss in SlackThis doc shows how to upgrade a Drupal 8 site that uses Build Tools to a Drupal 9 site that continues to use the Build Tools workflow.
About Build Tools
Build Tools connects Pantheon with your CI service and external Git provider. See the Build Tools Guide for details on supported Git and CI services combinations.
Will This Guide Work for Your Build Tools Workflow?
Before you continue, confirm that your site meets the following criteria:
Code is managed using an external repository outside of Pantheon (GitHub, GitLab, Bitbucket, etc.).
The site is built through a service like Circle CI.
Build artifacts are pushed to your Pantheon repository.
Prepare the Local Environment
Review our documentation on Git, Composer, and Terminus, and have them installed and configured on your local computer. Pantheon requires Composer 2 at minimum.
Mac users can use Homebrew to install Git, Composer, and PHP 7.4, along with their required dependencies. Restart the shell or terminal environment after entering the following command:
brew install git composer php@7.4Windows users can install Composer and Git, and may need to install XAMPP or similar to satisfy some dependencies.
Install the Terminus Site Clone plugin.
This doc uses several commands that depend on the site name in the local command line environment.
To make this easier, set the temporary variable
$SITEin your terminal session to match the site name. Read the steps further in this doc to see which sites should be aliased (it may be more than one), then replaceanita-drupalin this example:export SITE=anita-drupal && echo "New alias set as $SITE"How to Use Terminus to Find the Site Name
Use
terminus site:listfor a list of sites you have access to:terminus site:list --------------------------- --------------------- ------------- ----------------------------------- -------------------- --------------------- ------------- ------------ Name ID Plan Framework Region Owner Created Memberships Is Frozen? --------------------------- --------------------- ------------- ------------------- ---------------- -------------------- --------------------- ------------- ------------ anita-drupal abdc80ce-286c-1234- Sandbox drupal8 Canada 3374708c-987e-1234 2020-12-15 19:40:42 d3ecc20c-395a false anita-wordpres abdc9954-fab2-1234- Sandbox wordpress United States c96ddb25-336a-1234 2020-09-02 07:18:51 d3ecc20c-395a falseThe site name is listed under
Name. In this example,anita-drupal.
Install the jq JSON processor and rsync on your local environment if they aren't already installed. On MacOS with Homebrew, run:
brew install jq rsyncPrepare a Local Copy of the Site for Upgrade
In the Dev tab of the site's Dashboard, set the Development Mode to Git, and clone the site locally.
Change into the
$SITEdirectory, then create a new branch based on the default:cd $SITE git checkout -b d9-upg-21Use Terminus and Drush to export the latest version of the config files from the production environment to
sites/default/files/config:terminus drush $SITE.live -- config:export --destination sites/default/files/configFor rsync, copy the sftp host information.
RSYNC_HOST=$(terminus connection:info $SITE.live --field=sftp_host)Use that host name to rsync from
config:export:rsync -rvlz --copy-unsafe-links --size-only --checksum --ipv4 --progress -e 'ssh -p 2222' "${RSYNC_HOST}:files/config" .If you do a
git statusit should show changed files in theconfigdirectory if there are any changed configurations in production.git status
Upgrade Site Components Locally
Use Composer to declare version requirements:
composer require \ drupal/upgrade_status:^3 \ drupal/devel:^4 \ drush/drush:^10 \ -W --no-update composer require \ phpunit/phpunit:"^8 | ^9 | ^10" \ phpstan/phpstan \ --dev -W --no-updateThe
pantheon-systems/drupal-integrationsproject now includes a patch that backports a bugfix from Drupal 9 to Drupal 8 to display the correct version of your MariaDB server. If this patch is not installed, then your database version will always be reported asMySQL 5.5.30.The
cweagans/composer-patchesComposer plugin will only install patches from dependencies if theenable-patchingproperty is set totrueincomposer.json.Enable deep patching to view the correct MariaDB version in the Dashboard:
composer config extra.enable-patching trueEdit
composer.jsonand remove--no-devfrom thescriptssection to allow the dev dependencies to be available in the integration environment.Do not remove the close quote,
":composer.json"scripts": { "build-assets": [ "@prepare-for-pantheon", "composer install --optimize-autoloader" ],Add
composer-patchesto therequirelist and runcomposer update:composer require cweagans/composer-patches drupal/upgrade_status --no-update composer update -W --optimize-autoloader --prefer-distIf the site doesn't already have a pantheon.yml file, create one with the following values (the comments
#are optional):pantheon.ymlapi_version: 1 # Move the DOCUMENT_ROOT of your site to the */web* folder: web_docroot: true # Drupal 9 requires PHP 7.3 or higher. If your code isn't ready for PHP 7.4 you may need to use 7.3 here: php_version: 7.4 # Drupal 9 requires a higher version of the DB. It will take a few minutes to complete the upgrade to 10.4 once you push this file: database: version: 10.4 # Drupal 9 prefers Drush 10. If you have written a lot of custom Drush commands you may need to go back to Drush 9 or 8: drush_version: 10An existing
pantheon.ymlfile may have more values than this in it, but these are the ones with which we are concerned. If the values already exist in thepantheon.ymlfile, change them to the values in this example.Commit and push the changes:
git add composer.json composer.lock pantheon.yml config/* git commit -m 'updating to drush 10/mariadb 10.4/config' git push origin d9-upg-21If all goes well, you will see something like the following:
remote: Resolving deltas: 100% (3/3), completed with 3 local objects. remote: remote: Create a pull request for 'd9-upg-21' on GitHub by visiting: remote: {{URL TO YOUR REPOSITORY}} remote:Copy the URL from the result (line 4 in the previous output) and use your local web browser to navigate to it to create a pull request. Creating a pull request will cause Build Tools to create an Integration Environment Multidev. This is called
$ENVin the next steps.After the build has finished without error, you will see a new environment in the Dashboard under Multidev named in reference to your pull request.
terminus env:info $SITE.$ENVUse Terminus Drush to create a one-time login to your site:
terminus drush $SITE.$ENV uli adminLog in to the site as admin and take a look under Reports at Upgrade Status. Any modules which Upgrade Status shows are incompatible will need to be updated in the next few steps. Take note of the versions Upgrade Status recommends. If your module is incompatible it will need to be removed from the Composer file.
Upgrade MariaDB in All Environments
Once you have confirmed that the MariaDB upgrade worked in the Multidev, push the changes to the Dev environment to ensure the other components upgrade smoothly.
The possible risks associated with the time it takes for the platform to upgrade the database are minimal, but you can use the following command to mitigate potential errors:
git push origin masterFrom the Dashboard, merge the code from Dev, through Test, to Live.
Or use Terminus, and replace the $ENV in this example with the target environment:
terminus env:deploy --sync-content --note "upgrade DB" --updatedb -- $SITE.$ENVCustom Module Code
Custom module code is outside the scope of this document. See drupal.org for getting your custom code updated with the new version numbers and any code deprecations.
Use Composer to Update Drupal Core
Temporarily add write access to protected files and directories:
chmod 777 web/sites/default find web/sites/default -name "*settings.php" -exec chmod 777 {} \; find web/sites/default -name "*services.yml" -exec chmod 777 {} \;Use Composer to remove
config_installerand add new requirements:composer remove drupal/config_installer --no-update composer require drupal/core-recommended:^9 \ drupal/core-composer-scaffold:^9 \ drupal/core-project-message:^9 \ drush/drush:^10 \ -W --no-update composer require phpunit/phpunit:^9 \ behat/behat:^3 \ drupal/drupal-extension:^4 \ --no-update -W --devIf you have
core-devinstalled, follow below (skip this step if you do not havecore-devinstalled):composer require drupal/core-dev:^9 \ --dev -W --no-updateIf the Upgrade Status under Reports displays obsolete modules, update the modules using the
--no-update -Wswitch to instruct Composer to check for all dependencies together rather than for each module. ReplaceOBSOLETE-MODULE-NAMEin this example with the module to update:composer require drupal/OBSOLETE-MODULE-NAME:^9 \ --dev -W --no-updateRepeat this step for each obsolete module in the project.
When you're done updating modules, run
composer update:composer update -W --optimize-autoloader --prefer-distIf this command returns an error, check the output for any incompatible modules or themes and check the Upgrade Status under Reports in the integration environment.
Next, edit
composer.jsonand add--no-devfrom thescriptssection, to exclude the dev dependencies when the build is deployed to production.composer.json"scripts": { "build-assets": [ "@prepare-for-pantheon", "composer install --optimize-autoloader --no-dev" ],Commit the changes and push them to the development environment:
git add composer.json composer.lock pantheon.yml git commit -m "upgrade core to d9" git push origin d9-upg-21
Confirm the MariaDB Version and Updates
Validate your database version with terminus drush:
echo 'SELECT VERSION();' | terminus drush $SITE.$ENV sqlq -Review the site and Launch Check Status tab to confirm the database version and any outstanding available updates.