• Jacob Rockowitz
  • Blog
  • Projects
  • Work
  • Other
  • Contact
  • Contact Icons
  • Resume

Vibing Drupal: Using AI to switch between multiple versions of Drupal core

· Drupal,AI,Agent Skills

With Drupal 12 on the horizon and Drupal 10 reaching end of life in December, I'm facing two challenges. First, I need to upgrade my current site from Drupal 10 to Drupal 11. Second, I need to update my contributed modules to support Drupal 12, while still supporting Drupal 10. Frankly, I am more anxious about upgrading to Drupal 11 and supporting Drupal 12 than about integrating AI into my workflow.

Upgrading to Drupal 11

Upgrading to Drupal 11 has gotten easier over the years thanks to tools such as Drupal Rector, the Drupal Lenient Composer Plugin, the Upgrade Status module, and the Project Update Bot. Still, if you rely on contrib and custom modules, you'll have a lot to tweak and test.

I've done a "big-bang" upgrade via a dedicated branch, using the Lenient plugin and the Project Update Bot's patches for contrib modules, and fixing deprecations in custom code with Drupal Rector. There were always a few rough edges. Ideally, I'd like to gradually test my upgrade to Drupal 11 while continuing to support Drupal 10 in the same codebase using the DeprecationHelper.

As a maintainer of a contributed module, I face a slightly different challenge: supporting Drupal 12, 11, and 10.

Supporting Drupal 10, 11, and 12

As a maintainer of multiple contributed modules, I need to test them across previous, current, and next Drupal versions. I typically use dedicated DDEV instances for each Drupal version. I've started using Git worktrees to maintain a single Drupal playground with branches for each Drupal version. Still, maintaining a composer.json file that targets different Drupal versions across branches is challenging because it leads to endless merge conflicts.

To support multiple Drupal versions and make my composer.json easier to manage and understand, I've been using the Composer Merge Plugin.

Composer Merge Plugin

When you manage multiple Git repositories, external libraries, Drupal Recipes, and patches into one composer.json file, it becomes unwieldy. Over the years, I've split these aspects into separate composer files and merge them with the Composer Merge Plugin. The benefit is that it's easier to understand what each Composer package does, how it works, when it runs, and why. I’ve discussed this approach in more depth in a previous post, “Drupal (AI) Playground: Adding more structures to my playground.”

Below is a recap of how I organize my Composer merge files.

  • composer.json - Main dependencies, settings, and file imports
  • composer.libraries.json - Frontend libraries
  • composer.recipes.json - Drupal recipes and their dependencies
  • composer.sandbox.json - Development repositories and packages I maintain
  • composer.patches.json - Drupal core and contrib patches
  • composer.deprecated.json - Deprecated packages that need to be removed

What you see above uses layers to separate different concerns. The biggest concern I've struggled with is switching between and supporting multiple Drupal versions.

What if the previous, current, and next Drupal versions' concern became another layer in your composer.json?

Drupal versions as a layer

Here’s exactly what I mean when I describe Drupal versions as layers.

  • composer.json
  • composer.libraries.json
  • composer.recipes.json
  • composer.sandbox.json
  • composer.drupal_10.json
  • composer.drupal_11.json
  • composer.drupal_11.lenient.json
  • composer.drupal_11.patches.json
  • composer.drupal_12.json
  • composer.drupal_12.lenient.json
  • composer.drupal_12.patches.json

Since we shouldn't load multiple Drupal versions at once, here is my composer.json merge-plugin include configuration. Note that prefixing an include entry with an underscore points it at a file that doesn’t exist, so the Composer Merge Plugin silently skips it.

"merge-plugin": {
    "include": [
        "composer.json",
        "composer.libraries.json",
        "composer.recipes.json",
        "composer.sandbox.json",
        "_composer.drupal_10.json",
        "composer.drupal_11.json",
        "composer.drupal_11.lenient.json",
        "composer.drupal_11.patches.json",
        "_composer.drupal_12.json",
        "_composer.drupal_12.lenient.json",
        "_composer.drupal_12.patches.json"
    ],
    "merge-extra": true,
    "merge-extra-deep": true,
    "merge-dev": true,
    "replace": true
}

I hope you can see how this pattern works with Drupal 11 being the currently installed version. You can also check out my Drupal playground to see it in action. Although this approach is more organized, it introduces additional complexity. This is where AI serves as the final layer.

AI as a tool and layer

AI is a tool, or layer, for building and maintaining other tools.

I worked with AI to create a /drupal-core-switcher skill that documents Composer merge patterns and helps guide agents in supporting new Drupal versions. Along with the agent skill, a DDEV command named 'drupal-core-switcher' switches the Composer merge files to the target Drupal version, updates dependencies, relocks and applies patches, confirms the expected Drupal version was installed, and optionally runs database updates.

Now, I can run ddev drupal-core-switcher 10 to switch to Drupal 10. I also have the agent skill available; if I encounter Composer errors, I can prompt the agent to "Run ddev drupal-core-switcher 10 and fix the errors." When Drupal 13 arrives, I'll use this agent skill to configure and test support for it.

How can you use the drupal-core-switcher skill and command?

My short answer is to steal it, or, more politely, copy it using your agent.

I don't feel most agent skills, including this one, are one-size-fits-all because agents, their models, and humans are moving so fast. Your needs and your agent will be different from mine. For example, you probably don't need to support sandbox modules in your Drupal project, and depending on whether you have custom modules, you may also want to use the DDEV Module Developer add-on.

It is probably better to ask your agent to…

Help me copy the `/drupal-core-switcher` skill and the DDEV `drupal-core-switcher` command from https://github.com/jrockowitz/drupal_playground so I can improve and apply this approach to my Drupal application. What should we do next?

AI anxiety to AI-possible

I truly believe I could only come up with this solution because AI makes fixing, resolving, and patching Composer dependencies so much easier, allowing me to focus on the bigger challenge of supporting multiple Drupal versions. For the past year, I've experimented and toiled to integrate AI into my workflow, anxious about it. Now I'm starting to see what's AI-possible. I'm using AI to ease my anxiety around upgrading Drupal.

Where are you in your AI journey, moving from AI anxieties to AI possibilities

Is this approach and solution helpful for your next Drupal core upgrade?

If you are procrastinating on upgrading to Drupal 11, would you use AI to help you do it?

Subscribe
Previous
Vibing Drupal: Tale 3 - Using AI to contribute code by...
 Return to site
Profile picture
Cancel
Cookie Use
We use cookies to improve browsing experience, security, and data collection. By accepting, you agree to the use of cookies for advertising and analytics. You can change your cookie settings at any time. Learn More
Accept all
Settings
Decline All
Cookie Settings
These cookies enable core functionality such as security, network management, and accessibility. These cookies can’t be switched off.
These cookies help us better understand how visitors interact with our website and help us discover errors.
These cookies allow the website to remember choices you've made to provide enhanced functionality and personalization.
Save