Skip to content

1.42.0 - Halo

Latest

Choose a tag to compare

@github-actions github-actions released this 22 Oct 02:00
· 1 commit to main since this release
807fc1e
vortex-1420-halo

1.42.0 - Halo

This release moves the container images to Lagoon 26.10.0, whose PHP 8.4.27 fixes the 2 critical vulnerabilities in CERT-EU advisory 2026-018, and adds a static maintenance page that keeps requests away from PHP while the next fix like that rolls out. It also moves Behat to version 4 with drevops/behat-steps 4.x, extends the security audit to npm with results in GitHub code scanning, and adds a CI gate for builds that leave a dirty working tree. Stage environments now reroute email, the php container turns off session upload progress, Renovate waits 14 days before proposing updates in its auto-merged groups, and custom themes can opt into a Storybook component library. It ships with drevops/vortex-tooling 1.5.0.


πŸ” Highlights

  • PHP 8.4.27 in the Lagoon 26.10.0 images
    The uselagoon/* images move from 26.9.0 to 26.10.0. Their PHP 8.4.27 fixes CVE-2026-109618 and CVE-2026-109619, the 2 critical vulnerabilities in CERT-EU advisory 2026-018 that let an attacker run code on the server without logging in. Deploying the update to every environment closes both.

  • A maintenance page you switch on per environment
    Set VORTEX_NGINX_MAINTENANCE_MODE=1 on an environment and redeploy it: the nginx container answers every request with HTTP status 503 and the static page in .docker/config/nginx/maintenance.html, and no request reaches PHP. The next time a PHP fix like the one above has to roll out, it keeps PHP out of reach until the fix is on every environment. The page is a plain HTML file in the project, so it can carry the site's own branding.

  • Behat 4 and drevops/behat-steps 4.x
    The Behat stack moves to Behat 4.0 and drevops/behat-steps 4.x, which absorbs the Drupal Extension: FeatureContext extends a single DrupalContext that carries every step, scenarios no longer need the @api tag, and the configuration moves from behat.yml to behat.php. Existing suites need migrating - see Breaking changes.

  • Security audit covers npm and reports to code scanning
    The Security audit workflow now audits the root and theme npm lock files on both CI providers, with a package-audit.jsonc allowlist whose entries expire, so an assessed advisory can be skipped without switching the check off. On GitHub Actions, composer audit, npm audit and Gitleaks findings land in the repository's code scanning tab. Gitleaks, which had been scanning an empty directory on both providers, now scans the repository.

  • CI fails when the build leaves a dirty working tree
    The build job on both providers ends with a check that fails when the build modified a tracked file or left an untracked one, and lists each path. A step that silently rewrites exported configuration, compiled assets or scaffolded files gets caught in the pull request instead of by the next developer who builds.

  • Stage environments stop emailing real users
    Mail is now rerouted in every environment except local, ci and prod, so stage, which usually runs a copy of production content, reroutes like dev. reroute_email installs from the development modules script, so it stays installed when a project replaces the demo provisioning script.

  • Session upload progress is off in the php container
    The php container sets session.upload_progress.enabled = Off. PHP's upload progress tracking writes request data into session storage before Drupal starts, and Drupal never reads it, so turning it off removes attack surface from multipart requests without affecting uploads. New custom.ini files in .docker/config/cli/ and .docker/config/php/ hold project PHP settings for each container.

  • Safer Renovate auto-merge
    Every Renovate group carries its own automerge flag, and new installs pick the auto-merged groups in the installer (all by default). Those groups wait until a release is 14 days old before opening a PR, so a compromised release that gets pulled within days never reaches the project. Drupal core is exempt, so its security releases still arrive on the next daily run.

  • Opt-in Storybook component library
    Projects with a custom theme can opt into Storybook: stories are written in Twig next to each component, Drupal renders them through drupal/storybook, ahoy storybook runs a live development server, and provisioning publishes a static library at /storybook in local, ci and dev.


πŸ’₯ Breaking changes

These changes need attention when you update to 1.42.0.

  • drevops/vortex-tooling 1.5.0 is required. The template now requires ~1.5.0, and the build job, the GitHub Actions security audit and the Storybook commands call scripts that only exist in 1.5.0 (vortex-check-worktree-changes, vortex-convert-audit-sarif and vortex-storybook). After updating, run ahoy composer update drevops/vortex-tooling and commit composer.lock.

  • Behat 4 and drevops/behat-steps 4.x. Migrate the Behat suite:

    1. Remove drupal/drupal-extension, drupal/drupal-driver (if listed) and drevops/behat-format-progress-fail from composer.json - drevops/behat-steps 4.x conflicts with the first two. Require lullabot/mink-selenium2-driver, which @javascript scenarios need and which no longer arrives through the Drupal Extension.
    2. Port behat.yml customizations to behat.php and delete behat.yml. Behat 4 reads only behat.php, so an edited behat.yml that the update keeps is ignored without an error.
    3. Make FeatureContext extend DrevOps\BehatSteps\DrupalContext and remove the use lines for library traits. Custom contexts built on Drupal Extension classes need porting.
    4. Convert docblock annotations on custom steps and hooks (@Given, @When, @Then, @BeforeScenario, @AfterScenario, @Transform) to PHP attributes such as #[Given('...')]. Behat 4 no longer reads annotations.
    5. In feature files, remove the @api and @drush tags and rename steps using the drevops/behat-steps MIGRATION.md.
    6. Every scenario now runs the watchdog error check, which needs the dblog module. A site without it enables dblog or sets 'watchdog' => ['enabled' => FALSE] under steps in the BehatStepsExtension configuration.
    7. Update any log parsing that matched the --- FAIL --- banner, which now reads --- FAILED ---.
  • ESLint 10 and eslint-plugin-import-x. The root and theme lint toolchain moves from ESLint 9 to ESLint 10, because npm marks eslint@9.39.5, the version the lock files held, as no longer supported. eslint-plugin-import doesn't support ESLint 10, so the import rules now come from its eslint-plugin-import-x fork:

    1. In any eslint.config.mjs your project has customized, import the plugin with import { importX } from 'eslint-plugin-import-x'; and use importX.flatConfigs.recommended.
    2. Rename every import/* rule your project configures to import-x/*, for example import/no-mutable-exports to import-x/no-mutable-exports.
    3. Make sure any ESLint plugins or configs your project adds support ESLint 10.
    4. If you've changed either package.json, run npm install in the root and the theme to update the lock files; otherwise ahoy fei installs from the shipped ones.
  • Front-end lint majors and Node 22.13. The root and theme toolchains move to Stylelint 17 (stylelint-config-standard 40 and stylelint-order 8, plus stylelint-config-standard-scss 17 and stylelint-scss 7 in the theme), eslint-plugin-yml 3, eslint-plugin-no-jquery 6 and globals 17:

    1. In any eslint.config.mjs your project has customized, register eslint-plugin-no-jquery directly ('no-jquery': noJQuery) instead of through fixupPluginRules(), which version 6 breaks with Cannot read properties of undefined (reading 'bind'). @eslint/compat is no longer listed in either package.json, so keep it in yours only if your config still wraps another plugin with it.
    2. Run npm on the host with Node 22.13.0 or later, which the root package.json now requires for Stylelint 17 and eslint-plugin-yml 3. The CLI container ships Node 24.
    3. Make sure any Stylelint plugins or configs your project adds support Stylelint 17.
  • Boolean settings flags switch on only with 1. DRUPAL_CLAMAV_ENABLED, DRUPAL_REDIS_ENABLED, DRUPAL_REROUTE_EMAIL_DISABLED, DRUPAL_SHIELD_DISABLED, DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE and DRUPAL_TMP_PATH_IS_SHARED now read as on only with the exact value 1. Change any true, yes or other non-empty value to 1 in .env, CI variables and hosting environment variables. Otherwise Redis or ClamAV stop being configured, Shield or email rerouting come back on, and Acquia falls back to /tmp instead of the shared temporary path.

  • Stage environments reroute email. Acquia stage and test, and Lagoon main, master, release/* and hotfix/* environments that aren't the production branch, now reroute outgoing mail to DRUPAL_REROUTE_EMAIL_ADDRESS unless the recipient matches DRUPAL_REROUTE_EMAIL_ALLOWED. Set DRUPAL_REROUTE_EMAIL_DISABLED=1 on a stage environment that must deliver real mail. reroute_email is now excluded from configuration export, so the next ahoy drush cex drops it from core.extension.yml and config/default; commit that change.

  • New CI gates can fail builds that passed before. The dirty working tree check fails a build that leaves files behind: add the paths to VORTEX_CHECK_WORKTREE_CHANGES_IGNORE, or set VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE=1 to report without failing. The npm audit fails on high and critical advisories: allowlist assessed ones in package-audit.jsonc, or set VORTEX_CI_NPM_AUDIT_IGNORE_FAILURE=1. Gitleaks and DCLint now really check the repository on both providers: allowlist Gitleaks false positives in .gitleaks.toml and fix the Compose findings DCLint reports, or set VORTEX_CI_GITLEAKS_IGNORE_FAILURE=1 or VORTEX_CI_DCLINT_IGNORE_FAILURE=1.

  • .vortex-manifest.json is removed. The installer now works out the previous install state at run time and deletes the .vortex-manifest.json that 1.41.x wrote. Commit the deletion with the update.


What's new since 1.41.1

πŸŒ€ Template

  • ✨ New

    • [#2989] Added an opt-in Storybook component library for the custom theme. @AlexSkrypnyk (#3158)
      What it does: Adds a Storybook component library for the custom theme: stories are written as *.stories.twig next to each component and rendered by Drupal through the drupal/storybook module. ahoy storybook runs a development server that regenerates stories as they change, ahoy storybook-build rebuilds the static library served at /storybook, and ahoy storybook-stories only generates stories, all through the new vortex-storybook tooling script.
      How to use it: Off by default. Answer yes to Storybook component library? during installation (asked only for a custom theme). Provisioning then builds the library in local, ci and dev; set DRUPAL_STORYBOOK_SKIP=1 (default 0) to skip it. An existing project opts in with ahoy update-vortex --interactive, then refreshes composer.lock and the theme package-lock.json and runs ahoy build.

    • [#3136] Added a CI gate that fails when the build leaves a dirty working tree. @AlexSkrypnyk (#3149)
      What it does: Ends the build job on both CI providers with the new vortex-check-worktree-changes tooling script, which fails when the build modified a tracked file or left an untracked one, and lists each path. It runs after the test steps, so a dirty tree never hides their results.
      How to use it: On by default. Add paths the build generates to VORTEX_CHECK_WORKTREE_CHANGES_IGNORE (comma-separated Git pathspecs; a custom value replaces the default docker-compose.yml,*/docker-compose.yml,db_cache_*,codecov,codecov.SHA256SUM,codecov.SHA256SUM.sig), or set VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE=1 (default 0) to report without failing.

    • [#3139] Added an npm dependency audit to the security audit job. @AlexSkrypnyk (#3151)
      What it does: Audits the root and custom theme package-lock.json files in the Security audit workflow on both CI providers, failing on high and critical advisories - the level the new root and theme .npmrc files set with audit-level=high. On CircleCI, every audit step now runs even when an earlier one fails.
      How to use it: Applies automatically. Allowlist an assessed advisory in package-audit.jsonc (#3175), or set VORTEX_CI_NPM_AUDIT_IGNORE_FAILURE=1 (default 0) to report advisories without failing.

    • Added an 'audit-ci' advisory bypass mechanism for npm audit and updated 'drevops/phpcs-standard' to 1.1.0. @AlexSkrypnyk (#3175)
      What it does: Runs both npm audits through audit-ci 7.1.0, which skips advisories listed in an optional package-audit.jsonc allowlist whose entries carry notes and an expiry date. The shipped root and theme allowlists cover the unpatched braces advisory GHSA-vfj7-8cjw-p6xm until 2026-12-31, a new Renovate CI tools group keeps the npx pin current, and drevops/phpcs-standard moves to ^1.1.0.
      How to use it: Add an assessed advisory with notes and an expiry to the root or theme package-audit.jsonc; the entry stops applying once the expiry passes. drevops/phpcs-standard 1.1.0 can flag a parameter that a subclass renamed from its parent - renaming it to match clears the error.

    • [#3144] Uploaded security audit findings to GitHub code scanning as SARIF. @AlexSkrypnyk (#3155)
      What it does: The GitHub Actions Security audit workflow converts composer audit and npm audit results to SARIF with the new vortex-convert-audit-sarif tooling script and uploads them, with Gitleaks' own SARIF report, to GitHub code scanning; every report is also attached to the run as the security-findings artifact. It also fixes the Gitleaks step, which scanned an empty directory because its bind mount resolved against the runner host instead of the job container.
      How to use it: Applies automatically to GitHub Actions projects: findings appear under Security > Code scanning, and the audit steps alone still decide the result. Private repositories need a code scanning entitlement for the upload. Because Gitleaks now scans the real workspace, allowlist false positives in .gitleaks.toml, or set VORTEX_CI_GITLEAKS_IGNORE_FAILURE=1 (default 0).

    • [#3135] Added an opt-in check that fails provisioning when post-provision operations change configuration. @AlexSkrypnyk (#3150)
      What it does: Adds a last step to vortex-provision that runs drush config:status --state=Different and fails with the list of changed items when active configuration differs from the exported configuration after imports, deployment hooks, sanitization and custom scripts/provision-*.sh scripts have run.
      How to use it: Set VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION=1 (default 0). It complements VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_UPDATE, which covers database updates only.

    • [#3182] Added the nightly database-in-image refresh to the GitHub Actions 'database' job. @AlexSkrypnyk (#3188)
      What it does: Brings the CircleCI nightly database-in-image refresh to GitHub Actions: the scheduled database run imports the fetched dump into a clean drevops/mariadb-drupal-data base image and pushes the result with vortex-push-db-image. The job also caches the image archive instead of the dump for database-in-image projects, as the CircleCI job now does.
      How to use it: Applies automatically to projects that set VORTEX_DB_IMAGE, so the VORTEX_CONTAINER_REGISTRY_USER and VORTEX_CONTAINER_REGISTRY_PASS secrets need push access. Projects without VORTEX_DB_IMAGE keep caching the dump and push nothing.

    • [#3191] Added per-group Renovate auto-merge flags and an installer prompt to choose the auto-merged groups. @AlexSkrypnyk (#3192)
      What it does: Adds an explicit automerge flag to each of the 6 Renovate update groups in renovate.json, so a group whose flag is true merges its PRs as soon as they meet the base branch's protection rules.
      How to use it: New installs auto-merge the groups selected in the installer (all by default). An update keeps the project's current flags; set a group's automerge to true or false in renovate.json to change it. Auto-merge needs "Allow auto-merge" in the repository settings and at least 1 required status check that reports on deps/* branches.

    • [#3193] Added a 14-day minimum release age to the auto-merged Renovate groups except Drupal core. @AlexSkrypnyk (#3194)
      What it does: Sets minimumReleaseAge to 14 days on the PHP, JavaScript, container image, CI tools and GitHub Actions groups, so Renovate doesn't open a PR until a release is 14 days old; Drupal core keeps no delay. It also fixes a rule that silently disabled updates for the root package.json, so root npm dependencies now get updates in the weekly JavaScript group.
      How to use it: Applies automatically. Edit a group's minimumReleaseAge in renovate.json to change the delay, or request a pending update early from the Dependency Dashboard. A CircleCI project that pins its own renovate/renovate image older than 41.150.0 must raise it, because older images reject the new configuration.

    • [#3196] Added a weekly Renovate group that keeps the CircleCI self-hosted Renovate image up to date. @AlexSkrypnyk (#3197)
      What it does: Adds a custom regex manager and a group so Renovate updates the renovate/renovate image pinned in .circleci/update-dependencies.yml, which nothing tracked before. The version is looked up as the renovate npm package, which records the release dates the 14-day minimum release age needs.
      How to use it: Applies automatically to projects that run Renovate from CircleCI. Updates arrive weekly, and the group's automerge flag follows the CI tools choice in the installer.

    • Added custom PHP ini support to the 'cli' and 'php' containers and disabled session upload progress. @AlexSkrypnyk (#3222, #3223)
      What it does: The cli and php images copy .docker/config/cli/custom.ini and .docker/config/php/custom.ini into PHP's conf.d directory, where they load after Lagoon's 00-lagoon-php.ini and override its defaults. The php file sets session.upload_progress.enabled = Off, because the tracking writes upload request data into session storage before Drupal starts and Drupal never reads it.
      How to use it: Applies automatically wherever the Vortex images run: locally, in CI and on Lagoon. On Acquia, the platform's own PHP settings apply. Put project PHP ini directives in the matching custom.ini and rebuild with ahoy up --build; in the cli container, drush/php-ini/drush.ini still loads last.

    • Added a static nginx maintenance page switched on by 'VORTEX_NGINX_MAINTENANCE_MODE'. @AlexSkrypnyk (#3225)
      What it does: The nginx image ships .docker/config/nginx/maintenance.conf and maintenance.html. With VORTEX_NGINX_MAINTENANCE_MODE=1, nginx answers every request, POST included, with HTTP status 503 and the static page, so nothing reaches PHP.
      How to use it: Off by default (VORTEX_NGINX_MAINTENANCE_MODE is empty). On Lagoon, set the variable to 1 on 1 environment and redeploy it, since nginx reads the value when its container starts. Locally, run VORTEX_NGINX_MAINTENANCE_MODE=1 ahoy up nginx. Edit .docker/config/nginx/maintenance.html to change the page.

  • πŸ›  Changed

    • Updated all packages to their latest versions and all container images to their latest tags. @AlexSkrypnyk (#3227)
      What it does: Moves the 6 .docker/*.dockerfile bases, and uselagoon/mysql-8.4 and uselagoon/valkey-8 in docker-compose.yml, from Lagoon 26.9.0 to 26.10.0, whose PHP 8.4.27 fixes CVE-2026-109618 and CVE-2026-109619 (CERT-EU advisory 2026-018). selenium/standalone-chromium moves from 152.0 to 155.0, the CircleCI renovate/renovate image to 44.176.2, and Drupal core to ~11.4.11, with config.platform.php and the phpstan.neon phpVersion following PHP 8.4.27. The root and theme front-end toolchains take their latest majors: Stylelint 17, eslint-plugin-yml 3, eslint-plugin-no-jquery 6, globals 17 and, in the theme, postcss-cli 12. Both eslint.config.mjs files register eslint-plugin-no-jquery directly, since version 6 breaks inside fixupPluginRules(), so @eslint/compat leaves both manifests.
      How to use it: Applies on update; deploy it to every environment to bring the patched PHP. Run npm on the host with Node 22.13.0 or later. See Breaking changes for customized eslint.config.mjs files.

    • Switched Behat to 'drevops/behat-steps' 4.x, moved its configuration to 'behat.php' and dropped 'drupal/drupal-extension'. @AlexSkrypnyk (#3159)
      What it does: Replaces behat.yml with behat.php and the Drupal Extension with drevops/behat-steps 4.x, whose BehatStepsExtension picks a backend (drupal, drush or blackbox) for each step instead of relying on the @api tag. FeatureContext now extends DrevOps\BehatSteps\DrupalContext, which carries every library step, and the shipped features use the 4.x step wording.
      How to use it: See Breaking changes for the migration steps.

    • Updated 'behat/behat' to 4.0 with the 'friends-of-behat/mink-extension' 3.0 alpha and 'drevops/behat-screenshot' 3.0. @AlexSkrypnyk (#3202)
      What it does: Moves the template to Behat 4.0 and drevops/behat-screenshot 3.0, and requires friends-of-behat/mink-extension directly at ^3.0@alpha, because Behat 4 needs its 3.x line and that line only has an alpha release so far.
      How to use it: Keep all Behat configuration in behat.php and convert docblock step and hook annotations to PHP attributes. Code that extends the drevops/behat-screenshot extension or context should check its 3.0 renames. See Breaking changes.

    • Replaced 'drevops/behat-format-progress-fail' with the Behat core 'inline_failures' option and updated 'behat/behat' to '^3.34.0'. @AlexSkrypnyk (#3181)
      What it does: Drops drevops/behat-format-progress-fail, whose latest release conflicts with behat/behat 3.33 and newer, and turns on the core progress formatter's inline_failures option, so failed, pending and undefined steps print as they happen.
      How to use it: Remove drevops/behat-format-progress-fail from composer.json if your project lists it, and update log parsing that matched --- FAIL ---, which now reads --- FAILED ---.

    • [#3218] Updated 'eslint' and '@eslint/js' to 10. @AlexSkrypnyk (#3219)
      What it does: Moves the root and theme lint toolchain to ESLint 10, since npm marks eslint@9.39.5 as no longer supported and printed a deprecation warning on every npm ci, including the theme build in the CLI image. eslint-plugin-import doesn't support ESLint 10, so both eslint.config.mjs files switch to its eslint-plugin-import-x fork: they load importX.flatConfigs.recommended, and the mutable exports rule is now import-x/no-mutable-exports.
      How to use it: Applies on update. Rename any import/* rule your project configures to import-x/*; see Breaking changes.

    • [#3220] Installed PCOV with PIE instead of PECL in the CLI image. @AlexSkrypnyk (#3221)
      What it does: The CLI image installs the PCOV coverage extension with pie install --no-build-tools-check pecl/pcov instead of pecl install pcov. PIE resolves pecl/pcov through Packagist and downloads it from the extension's GitHub repository, so image builds no longer fail when pecl.php.net is down.
      How to use it: Applies automatically on the next image build.

    • [#3098] Enabled email rerouting in every cloud environment and moved 'reroute_email' to the development modules script. @AlexSkrypnyk (#3099, #3104)
      What it does: Reroutes outgoing mail in every environment except local, ci and prod, so stage now reroutes like dev: each message goes to DRUPAL_REROUTE_EMAIL_ADDRESS unless its recipient matches DRUPAL_REROUTE_EMAIL_ALLOWED. The module installs from scripts/provision-10-enable-dev-modules.sh instead of the demo modules script, and it's excluded from configuration export.
      How to use it: Applies automatically. To deliver real mail from a stage environment, set DRUPAL_REROUTE_EMAIL_DISABLED=1 in its hosting variables. See Breaking changes.

    • [#3112] Settled one environment variable guard form across the Drupal settings includes. @AlexSkrypnyk (#3122)
      What it does: Reads every boolean flag in the settings includes with getenv('X') === '1', and reads each value variable once and checks it with !empty(). The old !empty() check accepted any non-empty string, so DRUPAL_SHIELD_DISABLED=false disabled Shield.
      How to use it: Set the boolean flags to exactly 1 wherever they're set; any other value now reads as off. See Breaking changes.

    • Adopted the documented Fast 404 settings and covered them with tests. @AlexSkrypnyk (#3102, #3217)
      What it does: Aligns settings.fast_404.php with the settings the module documents: URL whitelisting is on, install.php and update.php leave the whitelist, and path and redirect checking are explicitly off, because the path check queries the database before Drupal connects to it. Requests for missing image style derivatives pass through to Drupal, which generates each one on its first request, and only for a URL with a valid itok token.
      How to use it: Applies automatically wherever drupal/fast_404 is installed. Keep fast404_allow_anon_imagecache at TRUE: with FALSE, the module also blocks derivative generation for logged-in users, because it looks for SESS in cookie values instead of cookie names.

    • Grouped root 'docker-compose.yml' container image updates with the other container images. @AlexSkrypnyk (#3164)
      What it does: Adds docker-compose.yml to the files the container images Renovate group matches, so bumps for uselagoon/mysql-8.4, uselagoon/valkey-8, selenium/standalone-chromium and drevops/docker-wait-for-dependencies join the grouped daily PR instead of opening 1 PR per image.
      How to use it: Applies automatically. uselagoon/mysql-8.4, pinned in both docker-compose.yml and .docker/database.dockerfile, now updates in a single PR.

    • Removed AI writing patterns from the docs and enforced a 76-character Markdown line limit. @AlexSkrypnyk (#3198)
      What it does: Wraps the Markdown files shipped into projects (AGENTS.md, README.md, the docs/ pages, scripts/README.md and the theme README.md) at 76 characters and rewrites parts of their prose, such as the local setup steps in README.md.
      How to use it: Applies on update. Most of the diff is line wrapping; re-apply any project edits the update replaced, which are listed in .logs/vortex-update.md.

    • Moved maintenance skills to '.vortex/skills' and registered them as the 'vortex' Claude Code plugin. @AlexSkrypnyk (#3204)
      What it does: Moves the Vortex maintenance skills from .claude/skills/ into .vortex/skills/ and registers .vortex/ as a local Claude Code plugin marketplace, so the skills load as /vortex:<skill>.
      How to use it: Maintainer-facing; consumer projects receive the same .claude/settings.json as before.

    • Converged installer, test-harness and tooling conventions on their dominant forms. @AlexSkrypnyk (#3116)
      What it does: Settles naming, type hints, BATS assertion helpers and the source comment register on one form each across the installer, the .vortex/tests harness and the tooling scripts.
      How to use it: Internal consistency work; no consumer action needed.

    • [#3110] Reconciled comments and docblocks with the code they describe. @AlexSkrypnyk (#3123)
      What it does: Corrects docblocks that described behavior the code doesn't have, points BATS file headers and script usage comments at the real script names, and pairs orphaned coverage markers.
      How to use it: Internal; no consumer action needed.

  • 🐞 Fixed

    • [#3169] Made 'nginx' start after 'php' and corrected the SSH agent recovery advice in 'vortex-doctor'. @AlexSkrypnyk (#3170)
      What it does: Adds php to nginx.depends_on in docker-compose.yml. Both used to start in parallel, and when php hadn't joined the network yet, nginx exited with host not found in upstream "php" and stayed down.
      How to use it: Applies automatically on the next ahoy up. Lagoon ignores depends_on, so deployments are unaffected.

    • [#3177] Fixed the nightly database job to import the fetched dump into a clean 'VORTEX_DB_IMAGE_BASE' image. @AlexSkrypnyk (#3180)
      What it does: Fixes the CircleCI database-nightly job for database-in-image projects, which rebuilt the database from the previous VORTEX_DB_IMAGE instead of importing the fetched dump, or failed when that image didn't exist yet. The Export DB step now tags VORTEX_DB_IMAGE_BASE as VORTEX_DB_IMAGE before starting the stack, so the pushed image holds the fresh data on a clean base.
      How to use it: Applies automatically to projects that set VORTEX_DB_IMAGE and fetch from a source other than container_registry.

    • [#3100] Corrected the contrib path guard in 'settings.fast404.php' and covered it with unit and functional tests. @AlexSkrypnyk (#3101)
      What it does: Ships drupal/fast_404 (^3.7) and fixes the guard in the settings override, renamed to settings.fast_404.php. The old guard checked a path Composer never creates, so fast404_preboot() never ran and every missing static file went through a full Drupal bootstrap.
      How to use it: On by default in new installs. The module is never enabled in Drupal, because the handler runs from settings.php. An existing project adopts it with ahoy composer require drupal/fast_404 before ahoy update-vortex, or by selecting Fast 404 with ahoy update-vortex --interactive.

    • [#3111] Aborted Acquia hook wrappers on unset and empty required values. @AlexSkrypnyk (#3120)
      What it does: Runs the Acquia hook wrappers in hooks/library/ under set -eu and stops each with an error when a required value is unset or empty, so a blank VORTEX_ACQUIA_KEY or VORTEX_ACQUIA_SECRET no longer lets a task run without credentials. provision.sh now honors the documented VORTEX_PROVISION_ACQUIA_SKIP, and notify-deployment.sh gains VORTEX_NOTIFY_ACQUIA_SKIP.
      How to use it: Applies automatically on Acquia. Set VORTEX_NOTIFY_ACQUIA_SKIP=1 to skip deployment notifications, and remove VORTEX_PROVISION_ACQUIA_SKIP=1 from any environment that should provision, since that variable used to have no effect.

    • [#3210] Fixed DCLint and Gitleaks scanning an empty directory in CI. @AlexSkrypnyk (#3215)
      What it does: The DCLint and Gitleaks steps mounted the checkout with docker run -v "${PWD}", a path the Docker engine couldn't see: CircleCI's remote engine has no access to the checkout, and on GitHub Actions the path belongs to the job container. Both scanned an empty directory and passed. CircleCI now copies the files into the container with docker create and docker cp, GitHub Actions mounts them with --volumes-from, and database2's container-only port gets a dclint disable-line comment for the duplicate-port rule.
      How to use it: Applies automatically. Both linters now check the real files, so a build can start failing on committed secrets or Compose lint findings: allowlist Gitleaks false positives in .gitleaks.toml, fix the Compose findings, or set VORTEX_CI_GITLEAKS_IGNORE_FAILURE=1 or VORTEX_CI_DCLINT_IGNORE_FAILURE=1 (default 0).

    • [#3184] Fixed the DIDI-II database job to use the 'container_registry' fetch source. @AlexSkrypnyk (#3185)
      What it does: Sets VORTEX_FETCH_DB_SOURCE to container_registry in the generated DIDI-II CircleCI test job, which never exercised vortex-fetch-db-container-registry before.
      How to use it: Maintainer-facing.

    • Added a 'filter-by-range' input to release-drafter to skip CalVer and Drupal-era tags. @AlexSkrypnyk (#3097)
      What it does: Restricts release-drafter to tags in the >=1.0.0 <7.0.0 range, so the CalVer and Drupal-era tags no longer outrank the current release when it resolves the previous one.
      How to use it: Maintainer-facing; consumer projects' draft-release-notes.yml is unchanged.

    • Fixed allowlisted npm advisories failing the 'npm audit' code scanning check and renamed 'audit-ci.jsonc' to 'package-audit.jsonc'. @AlexSkrypnyk (#3226)
      What it does: An advisory the npm allowlist accepts no longer raises a code scanning alert that fails the npm audit check on GitHub Actions: vortex-convert-audit-sarif leaves it out of the SARIF report, the way audit-ci leaves it out of the audit. The allowlist file is now package-audit.jsonc in the root and the theme.
      How to use it: Applies automatically with drevops/vortex-tooling 1.5.1 (see Tooling). The audit-ci.jsonc name never shipped in a release, so existing projects have nothing to rename.

  • ⬆️ Updated


🧰 Tooling

1.42.0 requires drevops/vortex-tooling ~1.5.0 (release notes). Besides the scripts behind the template features above (vortex-check-worktree-changes, vortex-convert-audit-sarif, vortex-storybook and the provisioning configuration check), 1.5.0 includes these changes.

  • πŸ›  Changed

    • Updated 'git-artifact' to '1.8.0' and passed the source directory with its '--source' option. @AlexSkrypnyk (#3172)
      What it does: vortex-deploy-artifact downloads the git-artifact 1.8.0 release, checks it against its SHA256 checksum, and passes the source directory as --source, since 1.8.0 keeps --src only as a deprecated alias that prints a notice on every run. The deployed artifact content is unchanged.
      How to use it: Applies automatically; VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_VERSION now defaults to 1.8.0. A project that overrides it must use 1.8.0 or later with the matching VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_SHA256, because older releases reject --source.

    • Updated 'git-artifact' to 1.9.0. @AlexSkrypnyk (#3224)
      What it does: VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_VERSION defaults to 1.9.0, and VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_SHA256 to that release's checksum.
      How to use it: Ships in drevops/vortex-tooling 1.5.1, which ~1.5.0 picks up with ahoy composer update drevops/vortex-tooling. A project that pins its own version keeps it.

    • [#3177] Fixed the nightly database job to import the fetched dump into a clean 'VORTEX_DB_IMAGE_BASE' image. @AlexSkrypnyk (#3180)
      What it does: vortex-fetch-db-container-registry pulls the image named in VORTEX_FETCH_DB_CONTAINER_REGISTRY_IMAGE_BASE and tags it as the database container image, instead of swapping the image name inside its own process where the build never saw it. The variable no longer falls back to VORTEX_DB_IMAGE_BASE.
      How to use it: Set VORTEX_FETCH_DB_CONTAINER_REGISTRY_IMAGE_BASE (default empty) only for a run that must start from an empty database. A project that set it in .env as a fallback must remove it, because it now replaces the database image on every container_registry fetch.

    • [#3113] Reconciled the drifted duplicate helpers across the shipped tooling scripts. @AlexSkrypnyk (#3124)
      What it does: vortex-task-copy-db-acquia, vortex-task-copy-files-acquia and vortex-task-purge-cache-acquia now report a rejected credential, a missing application or a missing environment by name, quoting the Acquia API response, and a credential rejected while polling task status no longer exits without a message. The duplicated JSON, drush, SHA-256 and AWS signing helpers now share one form in every script.
      How to use it: Applies automatically. Set VORTEX_DEBUG=1 to also print the API responses and extracted IDs as the scripts run.

    • [#3108] Closed every 'task' output helper with a matching 'pass' or 'fail'. @AlexSkrypnyk (#3121)
      What it does: Closes every announced task in 9 shipped scripts with exactly one pass or fail on every path. A failed Lagoon deployment now names the request that failed instead of printing Lagoon deployment completed with errors., and vortex-fetch-db-acquia no longer times out when a fresh backup completes on the last allowed poll.
      How to use it: Applies automatically. Update any log parsing that matched Lagoon deployment completed with errors..

  • 🐞 Fixed

    • [#3208] Made 'vortex-fetch-db' fail on an unknown 'VORTEX_FETCH_DB_SOURCE' instead of reporting success. @AlexSkrypnyk (#3212)
      What it does: vortex-fetch-db resolves the fetch script first and fails with the list of supported values when VORTEX_FETCH_DB_SOURCE (or an indexed variant such as VORTEX_FETCH_DB2_SOURCE) holds anything else. It used to run no fetch script and still report a finished fetch. The new none value skips fetching on purpose.
      How to use it: Applies automatically; a mistyped source now fails the fetch step with Unsupported database source. Set VORTEX_FETCH_DB_SOURCE=none where a project deliberately fetches no database.

    • Fixed allowlisted npm advisories failing the 'npm audit' code scanning check and renamed 'audit-ci.jsonc' to 'package-audit.jsonc'. @AlexSkrypnyk (#3226)
      What it does: vortex-convert-audit-sarif reads the audit-ci allowlist and leaves the advisory IDs and package names it accepts out of the npm SARIF report. It applies entries the way audit-ci does: the first entry for an ID wins, active must be set, and an expiry must lie in the future. Path entries are skipped, because a finding covers the whole package.
      How to use it: Ships in drevops/vortex-tooling 1.5.1. The allowlist defaults to package-audit.jsonc next to the lock file; set VORTEX_CONVERT_AUDIT_SARIF_ALLOWLIST_FILE to read another file.

    • [#3105] Matched the prod domain placeholder case in the Acquia purge-cache task. @AlexSkrypnyk (#3118)
      What it does: vortex-task-purge-cache-acquia now strips the uppercase $TARGET_ENV_REMAP. and $TARGET_ENV. placeholders that hooks/library/domains.txt ships, so on prod an entry such as $TARGET_ENV_REMAP.example.com purges example.com instead of a missing prod.example.com.
      How to use it: Applies automatically to Acquia cache purges on prod.

    • [#3169] Made 'nginx' start after 'php' and corrected the SSH agent recovery advice in 'vortex-doctor'. @AlexSkrypnyk (#3170)
      What it does: vortex-doctor now recommends ahoy up --no-deps --force-recreate cli when the SSH key is missing inside the CLI container. The previous advice left the running container attached to the old Pygmy SSH agent.
      How to use it: Applies automatically to ahoy doctor output.

    • [#3106] Added the missing marker space in negative BATS step assertions. @AlexSkrypnyk (#3119)
      What it does: Fixes negative step assertions in the BATS tests that stripped the first character of the message instead of the marker, which left 3 assertions unable to catch a regression.
      How to use it: Maintainer-facing.


πŸŽ› Installer

  • ✨ New

    • [#3191] Added per-group Renovate auto-merge flags and an installer prompt to choose the auto-merged groups. @AlexSkrypnyk (#3192)
      What it does: Adds an "Auto-merge dependency updates" multiselect after the dependency updates provider question. It lists the 6 Renovate groups, all selected by default, writes each group's automerge flag, and is asked only for the Renovate GitHub app and self-hosted providers.
      How to use it: Choose the groups during installation. On update, groups whose flag is already true are preselected, so existing choices carry over.

    • [#2989] Added an opt-in Storybook component library for the custom theme. @AlexSkrypnyk (#3158)
      What it does: Adds a Storybook component library? prompt to the Drupal section, shown only for a custom theme and defaulting to no. Declining removes the Storybook packages, scripts, settings, nginx configuration and ahoy commands, and prunes the theme package-lock.json to match.
      How to use it: Answer the prompt during installation, or run ahoy update-vortex --interactive to add Storybook to an existing project.

    • [#3100] Corrected the contrib path guard in 'settings.fast404.php' and covered it with unit and functional tests. @AlexSkrypnyk (#3101)
      What it does: Adds Fast 404 to the Modules multiselect, selected by default. Deselecting it removes drupal/fast_404, settings.fast_404.php and the matching settings test assertions.
      How to use it: Choose it during installation. On update, it stays selected only when the project's composer.json already requires drupal/fast_404.

  • πŸ›  Changed

    • [#3094] Derived the previous install state at run time instead of storing '.vortex-manifest.json' in the project. @AlexSkrypnyk (#3096)
      What it does: Downloads the version named by the README Vortex badge and renders it with the answers discovered from the project, so the checksums that decide which unmodified template-owned files an update removes are built in a temporary directory instead of read from a committed .vortex-manifest.json. Every project edit an update overwrites is appended to .logs/vortex-update.md, with diffs to re-apply.
      How to use it: Applies automatically on update. The installer deletes the existing .vortex-manifest.json; commit that deletion with the update.

    • [#3115] Settled the installer's file checks, badge detection, width measurement and test scaffolding. @AlexSkrypnyk (#3126)
      What it does: Routes every installer filesystem call through the File utility and fixes the defects found on the way: an unreadable --config or --prompts path reports a read error, the caret lands in the right column after colored or multibyte text, and a failed archive extraction no longer leaves the download behind. Project and version detection now read the README Vortex badge with the same pattern.
      How to use it: Applies automatically. Keep the README Vortex badge in its shipped form, which is the only form the installer recognizes as a Vortex project.

    • [#3114] Derived the handler processing order and prompt count in 'PromptManager'. @AlexSkrypnyk (#3125)
      What it does: Each prompt handler declares its own place in the processing order, and the progress total shown with each prompt is counted from the prompt list instead of a hard-coded number that sat below the real count.
      How to use it: Internal; the counter next to each prompt now shows the real total.

    • Switched Behat to 'drevops/behat-steps' 4.x, moved its configuration to 'behat.php' and dropped 'drupal/drupal-extension'. @AlexSkrypnyk (#3159, #3202, #3181)
      What it does: Teaches the Tools handler to ship and strip behat.php, to detect Behat from behat.php or a legacy behat.yml, and to remove lullabot/mink-selenium2-driver and friends-of-behat/mink-extension with the other Behat packages when Behat is deselected. The Webroot handler now reaches drupal_root and the Drush root in behat.php, so a custom web root such as Acquia's docroot applies there too.
      How to use it: Reflected automatically in installed and updated projects.

    • [#3139] Added an npm dependency audit to the security audit job. @AlexSkrypnyk (#3151, #3175)
      What it does: Removes the root .npmrc, package-audit.jsonc and the root npm audit step when ESLint, Stylelint and Jest are all deselected. The theme audit step stays as long as the project has a custom theme.
      How to use it: Reflected automatically in installed projects.

    • [#3218] Updated 'eslint' and '@eslint/js' to 10. @AlexSkrypnyk (#3219)
      What it does: The Tools handler removes eslint-plugin-import-x instead of eslint-plugin-import from the root and theme package.json files when ESLint is deselected.
      How to use it: Reflected automatically in installed projects.

    • Updated all packages to their latest versions and all container images to their latest tags. @AlexSkrypnyk (#3227)
      What it does: The Tools handler no longer lists @eslint/compat among the packages it removes when ESLint is deselected, since neither package.json ships it.
      How to use it: Reflected automatically in installed projects.

    • [#3098] Enabled email rerouting in every cloud environment and moved 'reroute_email' to the development modules script. @AlexSkrypnyk (#3099)
      What it does: Treats Reroute email as a development module: deselecting it removes its block from scripts/provision-10-enable-dev-modules.sh, which is removed only when every development module is deselected.
      How to use it: Reflected automatically in installed projects.

    • Moved maintenance skills to '.vortex/skills' and registered them as the 'vortex' Claude Code plugin. @AlexSkrypnyk (#3204)
      What it does: Strips the vortex marketplace and plugin entries from .claude/settings.json during installation, since consumer projects don't receive .vortex/.
      How to use it: Internal; no consumer action needed.

  • 🐞 Fixed

    • [#3127] Restored the process environment after every installer test. @AlexSkrypnyk (#3129)
      What it does: Snapshots and restores getenv(), $_ENV and $_SERVER around each installer test, so values loaded from an installed project's .env no longer leak into later tests.
      How to use it: Test-infrastructure fix; no consumer action needed.

πŸ“– Documentation

  • πŸ›  Changed

    • Refreshed the docs features page against the current template and linked every product it names. @AlexSkrypnyk (#3229)
      What it does: Rewrites the Features page to match what the template ships, among them MySQL 8.4, Valkey 8 and Selenium Chromium where it listed MariaDB, Redis and Chrome, the 4 CI jobs plus the security audit workflow, all 10 code quality tools and the contributed modules grouped by purpose. Every tool, service, hosting platform, module and DrevOps package it names links to its homepage or repository, each tab ends with a link to its docs section, and the planned items match the roadmap.
      How to use it: No action needed; see https://www.vortextemplate.com/docs/features.

    • Rewrote the docs in the documentation voice and corrected the claims that had drifted from the template. @AlexSkrypnyk (#3205)
      What it does: Rewrites 81 documentation pages in a consistent technical-writing voice and corrects statements that no longer matched the template, among them the minimum-stability example, the tools ahoy lint covers, a broken trigger-branch link and the description of how .env and .env.local reach the containers.
      How to use it: No action needed; browse https://www.vortextemplate.com/docs.

    • [#3209] Documented how '.env' reaches PHP-FPM through the Lagoon entrypoint and when a change to it applies. @AlexSkrypnyk (#3214)
      What it does: Explains that PHP-FPM loads variables Drupal reads directly, such as DRUPAL_CLAMAV_ENABLED, from .env when its container starts and never from .env.local, and shows how to pass a machine-only value through docker-compose.override.yml.
      How to use it: Run ahoy restart to apply a change to such a variable in .env; ahoy up recreates a container only when its configuration changes.

    • Added Vale prose linting with a 'Vortex' house style to the documentation and fixed all reported alerts. @AlexSkrypnyk (#3156)
      What it does: Lints every documentation page with Vale against the Google and write-good packages plus a Vortex house style, and edits 71 pages to pass it.
      How to use it: Maintainer-facing. Run yarn lint-prose in .vortex/docs; error-level rules fail CI.

    • Removed AI writing patterns from the docs and enforced a 76-character Markdown line limit. @AlexSkrypnyk (#3198, #3203)
      What it does: Rewrites the documentation and the repository README.md in plain sentences, corrects 3 wrong claims about the security audit, and wraps every Markdown file at 76 characters.
      How to use it: Maintainer-facing. markdownlint MD013 now fails ahoy lint-docs and ahoy lint-markdown on over-long lines.

    • [#3107] Replaced the drifted script snippet in '.vortex/CLAUDE.md' with a pointer to 'script-boilerplate.sh'. @AlexSkrypnyk (#3117)
      What it does: Points contributors to script-boilerplate.sh as the single source for script structure and the 5 output helpers, replacing an inline snippet that no longer matched the shipped scripts.
      How to use it: Maintainer-facing.

    • Refreshed '.vortex/' dev dependencies for October 2026. @AlexSkrypnyk (#3206, #3199)
      What it does: Refreshes the lock files for the docs, installer and tests subsystems.
      How to use it: Maintainer-facing.

    • Updated all packages to their latest versions and all container images to their latest tags. @AlexSkrypnyk (#3227)
      What it does: Moves the docs site tooling to Jest 30, Testing Library 16, cspell 9 and markdownlint-cli2 0.24, with markdownlint's new MD060 table rule disabled, and the installer to Guzzle 8.
      How to use it: Maintainer-facing.


πŸ“‹ Release checklist

  • Updated all dependencies outside of the schedule - done by hand in #3227 instead of a manual Renovate run: every Composer and npm package and every container image is on its latest release, majors included where they install and pass lint and tests. Held back: phpunit/phpunit 13 (Drupal 11.4's test base classes target PHPUnit 11), softcreatr/jsonpath 1.x and 2.x (they need PHP 8.5), and in .vortex/docs React 19, cspell 10, Babel 8 and ESLint 10.
  • Updated container images and checked @see links - uselagoon/* all at 26.10.0 since #3227, the latest Lagoon release (php-cli-drupal, php-fpm, nginx-drupal, solr-9-drupal, commons, mysql-8.4, valkey-8); drevops/docker-wait-for-dependencies:26.10.0 and drevops/mariadb-drupal-data:26.10.0 (latest, and the 4 VORTEX_DB_IMAGE_BASE pins agree); clamav/clamav-debian:1.5.4 (latest). Solr luceneMatchVersion stays 9.12.3: uselagoon/solr-9-drupal:26.10.0 builds on Solr 9.11.0 instead of 9.10.1, and Solr 9.11.0 still pins Lucene 9.12.3. All 14 @see links return 200.
  • Updated selenium/standalone-chromium from 152.0 to 155.0 in #3227.
  • CI tool images verified and consistent across both providers - hadolint/hadolint:v2.15.1 (also pinned in .vortex/tests/lint.dockerfiles.sh), zavoloklom/dclint:3.1.0, ghcr.io/gitleaks/gitleaks:v8.30.1, rhysd/actionlint:1.7.12, all latest, and renovate/renovate:44.176.2 in .circleci/update-dependencies.yml (#3227). No untagged references.
  • Updated PHP version in composer.json for config.platform - 8.4.23 β†’ 8.4.27 (8.4.25 in #3213, 8.4.27 in #3227), matching uselagoon/php-8.4-cli-drupal:26.10.0.
  • Updated PHP version in phpcs.xml for testVersion - 8.4, matches.
  • Updated PHP version in phpstan.neon for phpVersion - 80423 β†’ 80427 (80425 in #3213, 80427 in #3227), matching the container's PHP_VERSION_ID.
  • Tagged drevops/vortex-tooling before the Vortex tag - 1.5.0 published on 2026-10-20 from drevops/vortex@b3af19a76, which held every tooling change at the time (the template calls 3 scripts that 1.4.0 lacks), and available on Packagist. The pin is ~1.5.0 in the root composer.json require, and 1.5.0 in the root path-repo versions override, scripts/vortex-tooling.sh (VORTEX_DEV bootstrap) and .vortex/tests/phpunit/Traits/SutTrait.php, with the tooling README.md and docs updated to match.
  • Tagged drevops/vortex-tooling 1.5.1 before the Vortex tag - published on 2026-10-21 with the 2 tooling changes that landed after 1.5.0: #3224 (vortex-deploy-artifact, git-artifact 1.9.0) and #3226 (vortex-convert-audit-sarif skips allowlisted npm advisories). ~1.5.0 picks it up with no template change. The 1.5.0 and 1.5.1 GitHub release bodies are still empty.
  • Updated minor version of all packages in composer.json (composer update -W) - bumped drupal/drupal_helpers ^2.2.0, drupal/generated_content ^2.2.0 and drupal/testmode ^2.8.0 (bump-after-update). drevops/behat-steps stays ^4.0@rc (4.0.0-rc2, published 2026-10-20, is the latest; prefer-stable picks up 4.0.0 once released), and friends-of-behat/mink-extension stays ^3.0@alpha (v3.0.0-ALPHA.1 is the only 3.x tag upstream). No security advisories. #3227 then took Drupal core ~11.4.11 and drupal/shield ^1.10.
  • Updated theme dependencies - refreshed the root and theme package-lock.json files with npm update on top of the ESLint 10 locks from #3219. The full re-resolution moves postcss-selector-parser to 7.1.7, which clears GHSA-rj75-hqrm-r3gf, and drops eslint-import-resolver-node, an optional peer of eslint-plugin-import-x that the locks carried over, along with the polyfill packages it pulled in through resolve@2.0.0-next.7. import-x loads it only for legacy resolver options, which neither eslint.config.mjs sets, and ahoy lint passes without it. The only high-severity advisory in either tree is braces GHSA-vfj7-8cjw-p6xm, which has no patched release and is allowlisted in both package-audit.jsonc files: audit-ci@7.1.0 --high passes for both, and the allowlist expiry moved from 2026-10-31 to 2026-12-31 so the audit doesn't fail days after release. #3227 then moved both toolchains to their latest majors, and both audit-ci --high gates still pass with only the allowlisted braces advisory.
  • drevops/ci-runner version in CI configs - 26.10.0, confirmed latest.
  • Incremented the CI database cache version - v26.8.1 β†’ v26.10.0 in .circleci/config.yml and .github/workflows/build-test-deploy.yml, with .circleci/vortex-test-common.yml and .github/workflows/vortex-test-didi.yml regenerated. It follows the documented rule that the version matches the uselagoon/* tag, which is 26.10.0 since #3227.
  • Updated documentation (ahoy update-docs) - no changes; it kept the new cache key.
  • Regenerated the installer snapshots (ahoy update-snapshots) - 160 scenarios, Updated: 0, after rebasing onto main at 364bdd11f. Fixtures mask container tags, cache versions and dependency versions. #3227 regenerated them for its package.json and eslint.config.mjs changes, and all 160 scenarios pass.
  • Fast 404 image derivatives - fixed on main in #3217 before the tag: fast404_allow_anon_imagecache is TRUE, so missing image style derivatives reach Drupal and get generated.
  • Re-recorded the demo videos (ahoy update-videos) - all 9 recorded clean against drevops/vortex-tooling 1.5.0 from Packagist. 2 recording fixes went in first: the installer expect script now also matches the N selected β”˜ border of a scrolling multiselect, and type-and-run.php hands the recorded command the terminal itself rather than a pipe, so Docker Compose can open a console for its build progress. #3219 and #3221 landed after the recordings, but no recording shows the PCOV install step or the import plugin, so they stay current.
  • Re-record the build, provision and test videos - #3227 landed after the recordings, and these 3 show its old versions: build pulls the 26.9.0 images, provision reports Drupal core version : 11.4.10 and test reports PHP 8.4.25. The other 6 show no image tag, PHP version or Drupal core version.
  • Tagged the Vortex release - pending, after the tooling tag.
  • Pending deprecations checked - none due. The only 2 @deprecated markers are in .vortex/installer/src/Prompts/Handlers/HostingProjectName.php (lines 86 and 142), open-ended Acquia backward-compatibility shims that name no removal version.
  • Demo database URL - left at the 1.40.0 release asset. It only changes when the demo databases are regenerated.

Full Changelog: 1.41.1...1.42.0

@AlexSkrypnyk, @renovate[bot] and renovate[bot]