The time has finally come! I’ve been waiting to do this for a couple of months now (ever since I wrote about the update for the Drupal4Gov site back in July) and since the conference has concluded, it’s time to do it! Let’s update GovCon to D9.
Overview
First and foremost, a friendly reminder that you need to think carefully about updating to Drupal 9. Should you? Yes! Should you RIGHT NOW? Maybe / maybe not.
For us on Drupal GovCon the issue was our conference. COULD we have updated DGC back in July when we updated D4G? ABSOLUTELY. Would it have been ok? Probably? I just didn’t want to take the chance right before the conference.
There were quite a few pull requests to finally get us to D9, but here’s the one that actually had the composer change.
What I did do in the intervening space was perform a number of updates for key contributed modules that I knew needed to be updated for D9 compatibility. Thankfully I had knew about many of these from my experience on D4G. Some examples include:
devel
recaptcha
google analytics
etc.
You can see an example of this in a recent pull request. How did I know what to upgrade? I downloaded and ran the Upgrade Status module! Basically, download it, turn it on, and run the following drush command to check all your contrib modules (obviously, you’ll also need to test your custom code but I did that months ago):
drush upgrade_status:analyze --all --ignore-custom
Warning: this will take a long time. But when it’s done it will tell you all the modules you need to upgrade (if any) that aren’t compatible. I’ve found a number of things on DGC at this point in the process (as of October) I have no patches in my codebase to make module D9 compatible (although, I do have a couple of dev versions to resolve issues).
Notable Changes
As with D4G we’re using Lightning and BLT on this project so this required some tweaking:
Update to Lightning 5.x
Update to BLT 12.x
Re-adding “missing” BLT functionality, notably:
PHPCS
Behat
Disable modules not needed in 9.x and remove associated config AND uninstall them from all environments
Libraries
Context
Confirm that my composer.json file aligns with the current recommendations in acquia/drupal-recommended-project (this is the successor to acquia/blt-project)
Add the MySQL Driver as documented by Acquia since we are hosting there
Update additional modules to get to D9 “green across the board”
config ignore (running 2.x-dev for now)
r4032login required swapping to Matthew Grasmick’s fork as there is no D9 stable release (see https://www.drupal.org/project/r4032login/issues/3042799).
linkicon
extlink (recently stablized)
webform
Update configuration after module updates (webform had some notable changes, that was about all though)
Issues
I actually ran into a few additional issues on DGC then I have on other projects. This was expected given the size and complexity of the site. Let’s dig into them!
Behat Test Failures
The first thing I hit was a random Behat failure after updating. This one really surprised me given what was failing and how it was failing. I opened an issue over on the Lightning Workflow queue for this one: https://www.drupal.org/project/lightning_workflow/issues/3173735
Warning: call_user_func() expects parameter 1 to be a valid callback, function 'drupal_get_user_timezone' not found or invalid function name in /mnt/tmp/local.prod/source/docroot/modules/contrib/lightning_workflow/modules/lightning_scheduler/tests/contexts/SchedulerContext.behat.inc line 33
This was so surprising because the context file actually wrapped the deprecated function (as of 8.8.x) in a check to make sure that the function existed before it tried to call it. This wasn’t actually blowing up when I loaded the site but it did kill my behat tests.
Remediation: Thankfully the Lightning team has already fixed this (as of the above issue) but you may need to update to the dev version of Lightning Workflow to get the fix depending on when you are doing this.
Action Config Import Failures
Next up was some super funky config import failures. I actually got bit by this one TWICE (once in my local after the update and once in the cloud after I fixed the first issue).
TLDR Drupal updated the plugins behind some of the system actions back in Drupal 8.5 - https://www.drupal.org/node/2919303. Apparently this update either didn’t get run on DGC or we missed the config change. Regardless, once we updated to 9.x the config imports blew up with 4x of these errors:
Unexpected error during import with operation update for system.action.node_delete_action: The "node_delete_action" plugin does not exist.
The actions in question that were broken for us were:
system.action.node_delete_action.yml
system.action.node_publish_action.yml
system.action.node_save_action.yml
system.action.node_unpublish_action.yml
Basically, this was a simple update to replace an old style plugin (e.g. node_delete_action) with the new style (entity:delete_action:node).
Remediation: Easy enough to fix. HOWEVER the thing that bit me here a second time was that, much like removing a module, once I updated to D9 I couldn’t “fix” this on my existing sites (because the old plugins were gone). So I actually had to make this config update in D8 and then update to D9. For me I just did this manually by importing the 4 config actions in question in my prod environment, but you could certainly deploy these changes and import config then do the update.
In Conclusion
The update was still pretty darn simple. All in all I’m glad we waited until after the conference but I think if we had to do it before, we totally could have. THANK YOU again to all the module maintainers and community members who have worked so hard this year to get us to this point. It’s plain to see how many modules are now “stable” in D9 (vs. where we were even a few months ago).
An overview of all the things I’ve been trying / testing to get ready for PHP 8.1.