What keeps a module working through Drupal and PHP updates

A contributed module is an add-on that anyone can download from Drupal.org(Opens in a new tab/window) and install on their own website. Each one has to keep working while Drupal ships 2 minor releases a year and PHP a new version every year.

Any of those releases can break a module that worked fine last month. When nothing tests the module against the new versions, the first sign is often a bug report from a site that has just updated. Drupal 12 is next: it's in beta, and every module that will support it needs testing against it.

Keeping a module reliable takes work around its code:

  • a Drupal site to develop and test against
  • automated tests across the Drupal and PHP versions its users run
  • coding standards checks
  • a pipeline that runs all of it on every change
  • a way to publish each release to Drupal.org

Building that by hand for each module is a project in itself, and keeping it current is a job for years.

Set up from the first commit: a local site, CI and publishing to Drupal.org

Eddy(Opens in a new tab/window) is our template for contributed Drupal modules and themes, developed in public on GitHub(Opens in a new tab/window). An installer asks a short list of questions, then shapes the template into your module or theme and removes everything you didn't pick.

The local development site runs on the PHP already on your machine, built by the same commands CI runs, so a failing CI job reproduces locally on the same Drupal and PHP versions.

Maintainers develop on GitHub. When the tests pass on a deploy branch, CI mirrors the tested commit to Drupal.org, and release tags follow the same path. Each deployment checks the branch right before it pushes, so an older commit can't replace a newer one.

Tested on the versions sites run: Drupal 10, 11 and 12 on PHP 8.3 to 8.5

CI on GitHub Actions(Opens in a new tab/window) tests the edges of a module's support range: the lowest and highest supported PHP on each Drupal major. Drupal 11 and 12 add 2 more tiers. Legacy builds an older minor that some sites stay on, and canary builds the next minor's beta or release candidate.

For a website, that means a Drupal change can show up in the CI of the modules it depends on before it shows up on the site.

Drupal 12 is opt-in. Select it, and CI builds the newest Drupal 12 pre-release, then moves to 12.0.0 on its own once it ships. The documentation lists the Drupal 12 changes a module is most likely to hit, each with a fix that works on Drupal 10, 11 and 12.

Every module starts with working examples of each PHPUnit(Opens in a new tab/window) suite, including tests that drive a real browser, plus Jest(Opens in a new tab/window) tests for its JavaScript. Checks for PHP, Twig, JavaScript, CSS and spelling run with 1 command.

Kept current: a tooling package, Renovate and AI-assisted template updates

Renovate(Opens in a new tab/window) opens grouped pull requests that keep a module's dependencies current. The commands that build, run and deploy it come from a Composer package, drevops/eddy-tooling(Opens in a new tab/window), so their fixes reach every project as patch releases.

When Eddy itself changes, its update skill for Claude Code renders the template twice from the project's original installer answers, once at the project's release and once at the latest. It merges the difference, builds, lints and tests the result, and opens a pull request, so the maintainer decides only on lines both sides changed.

Maintained since 2015: more than 60 releases, and the modules we maintain

Eddy has followed Drupal from version 7 to the Drupal 12 pre-releases, and it tests itself the way it tests a module created from it.

Maintained since 2015, with more than 60 releases, and testing modules on Drupal 10, 11 and 12 today.

The contributed modules we maintain use it, including Testmode(Opens in a new tab/window) and Generated Content(Opens in a new tab/window). It's free and open source under GPL-2.0, and our launch post walks through every part in more depth.

For websites that depend on contributed and custom modules

Eddy is 3 of our services applied to our own modules: automated testing, CI/CD pipelines and readiness for the next Drupal upgrade. Vortex(Opens in a new tab/window), its sibling template for whole Drupal websites, brings the same discipline to the sites that install them.

If you run a Drupal website, its modules largely decide how smoothly each upgrade goes. This is the shape the engagement takes: we review the modules your site depends on, check how each one is tested and maintained, and plan the path through the next major version. The upgrade itself can run hand-crafted or with AI-assisted delivery, at the same tested standard.

If you'd like to know what Drupal 12 will mean for the modules your website runs, send us the list and we'll take a look.