Skip to content

feat: add config drift checks to Drupal site workflow - #160

Draft
turegjorup wants to merge 6 commits into
developfrom
feature/drupal-config-checks
Draft

turegjorup wants to merge 6 commits into
developfrom
feature/drupal-config-checks

Conversation

@turegjorup

@turegjorup turegjorup commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Adds config drift checks to the Drupal site workflow (github/workflows/drupal/site.yaml), so a site can no longer ship config that is stale, unexported or invalid without a red check.

Changes

  • install-site:
    • Check that config is up to date: drush config:export after installing from config must leave config/ unchanged, new files included. Several projects already carry this check in their own pr.yml.
    • Check that config matches its schema: drush config:inspect --only-error --detail. It runs only when drupal/config_inspector is a dev requirement and otherwise logs a notice and skips, so syncing the template does not break sites that have not added it yet.
  • update-site: run drush updatedb on its own before drush deploy, then fail if the active config differs from config/sync in anything the pull request does not change itself. That means config changed by an update hook but never exported. drush deploy hides this today, because its config import overwrites the hook's changes straight after updb.
  • Document the checks in the template header, and regenerate docs/github-actions-templates.md.

Related, outside this template: by default composer-patches prints "Could not apply patch! Skipping" and carries on. doner-din-stemme has shipped a half-applied core patch that way since its Drupal 11.4 upgrade. Projects that use patches should set "composer-exit-on-patch-failure": true under extra in composer.json, so a patch that doesn't apply fails CI, local installs and release builds alike.

Why

os2loop shipped an openid_connect.client.generic whose prompt setting no longer matched the module's schema (8698). Project-level "config up to date" checks cannot see that: exporting a site installed from stale config reproduces the same stale file. The update-hook check and the schema check cover that gap.

The project checks that do exist were red for weeks on os2loop and doner-din-stemme and merged anyway, because they are not required checks. Once this is in, the new job steps should be marked as required in each site's branch rules.

Being piloted in itk-dev/doner-din-stemme#72 (same file plus drupal/config_inspector).

Checks that installed config exports unchanged, that update hooks leave no unexported config, and (when drupal/config_inspector is installed) that config matches its schema.
@turegjorup turegjorup self-assigned this Oct 28, 2026
Comment on lines +187 to +209
- name: Run database updates
run: |
docker compose exec phpfpm vendor/bin/drush updatedb --yes

- name: Check that config changed by updates is exported
run: |
# After running updates, but before importing config, the active
# config may only differ from the config in code where this pull
# request changes the config. Any other difference comes from an
# update hook changing config that has not been exported.
# Collection prefixes (e.g. "language.da:") and directories are
# stripped so names from both sides compare.
git diff --name-only origin/${{ github.base_ref }} -- config/ \
| sed -E 's#^.*/##; s#\.yml$##' | sort -u > changed-by-pr.txt
docker compose exec -T phpfpm vendor/bin/drush config:status --format=json \
| jq -r 'if type == "object" then keys[] else empty end' \
| sed -E 's#^.*:##' | sort -u > changed-in-db.txt
comm -23 changed-in-db.txt changed-by-pr.txt > not-exported.txt
if [ -s not-exported.txt ]; then
echo "::error::Active config differs from config/sync (not changed by this pull request), e.g. config changed by update hooks that has not been exported:"
cat not-exported.txt
exit 1
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems overly complicated.

Assuming that the "Check that config is up to date" step works and does what it claims to do correctly, we can just run that same task after the "Update site" step (drush deploy runs drush updatedb and everything else needed to update a site). Maybe a YAML anchor can help us reuse the task definition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants