Updated Vortex to eaceb9e. - #316
Conversation
Took the Lagoon base image bump to 26.8.0, the hadolint inline ignores that replace the file-global ignore list, and the explicit 'ARG PHP_INI_SCAN_DIR'. Kept npm for the theme build: this project migrated the 'drevops' subtheme to npm and ships 'package-lock.json', so the template's yarn default does not apply.
Bumped the Lagoon commons image to 26.8.0 and ClamAV to 1.5.4, and replaced the file-global hadolint ignore list with per-line ignores that state why each rule is waived. No project divergence in this file.
Raised the InnoDB redo log capacity to 1GB. The image default of 128MB is exhausted during a large dump import faster than the log checkpointer reclaims it, aborting with 'ERROR 1114 ... table is full'. Paired with the config path move in '.docker/database.dockerfile'.
Bumped the MySQL image to 26.8.0 and moved the server config from '/etc/my.cnf.d/' to '/etc/mysql/conf.d/', which is the directory the entrypoint rewrites before starting the server. Without the move the redo log setting added to 'my.cnf' would be ignored.
Bumped the Lagoon nginx-drupal image to 26.8.0 and moved the hadolint waivers inline. No project divergence in this file.
Bumped the Lagoon php-fpm image to 26.8.0 and moved the hadolint waivers inline. No project divergence in this file.
Bumped the Lagoon solr-9-drupal image to 26.8.0 and moved the hadolint waivers inline. The Solr config-set copied into the image is unchanged. No project divergence in this file.
Vortex inverted the file from an allowlist to a denylist, so the build context is now everything except the named paths. Added this theme's build outputs to the exclusion list: the template excludes 'web/themes/**/build', but the 'drevops' subtheme emits 'dist', 'storybook-static' and 'components_combined', which would otherwise be copied into the image and then overwritten by the in-image build.
Added a JavaScript 'max_line_length' of 160 so editors agree with the Prettier 'printWidth' raised in '.prettierrc.json'. No project divergence in this file.
Raised 'printWidth' from 80 to 160 and pinned JSDoc comments to 80 via 'jsdocPrintWidth', so code stays on one line while doc comments keep the narrow wrap. No project divergence in this file.
Raised the Drush 'memory_limit' from 512M to 1G. This project runs config sync and database imports through Drush in CI and on deploy, which are the operations the limit is sized for. No project divergence in this file.
Added the missing final newline. No project divergence in this file.
Added the missing final newline to all five files. Grouped into one commit because the change is byte-identical across them and carries no per-file decision. No project divergence in these files.
Took the only upstream change, the analysed PHP version moving from 8.4.21 to 8.4.23. Restored the project's own settings that the re-render dropped: the '.artifacts/phpstan' tmpDir, the 'scripts/composer/ScriptHandler.php' exclusion, and the ignore for the AI module's ProviderProxy '__call()' forwarding.
Replaced the hardcoded 'Drupal9SetList'/'Drupal10SetList' with the composer-based set provider, which binds the Drupal deprecation sets to the installed core version so the set tracks core upgrades without editing this file. Also took the two new foreach-rename skips and the scoping of 'RemoveUnusedPublicMethodParameterRector' to 'src/Hook/*', which matches the hook classes in do_base, do_feed and do_content_api. The set-provider API requires 'palantirnet/drupal-rector' ^1.x, so this file depends on the constraint bump made in the composer reconciliation.
Took the 'ENVIRONMENT_TYPE' pass-through, which lets the auto-detected environment type be overridden, and the hyphenated fallback for the image name. Restored the project's 'DRUPAL_AI_PROVIDER_GEMINI_API_KEY' pass-through that the re-render dropped. The database, valkey and chromium image bumps in this update were already at or ahead of the template here, so they are unchanged.
Took the two upstream changes: an explicit 'shell: bash' on the pre-deployment backup and database fetch tasks, which otherwise run under sh and mis-parse the bracket tests, and the task name spelling. Kept the project's own configuration that the re-render reset: the production and develop 'routes' blocks naming the real domains, and the absence of 'monitoring_urls' and the top-level 'routes: insecure: Redirect'. The upstream patch does not touch either of those, so re-adding them would have been the re-render undoing a project decision rather than an update.
Extended the container-image group to '.github/workflows/**' and added a regex manager that reads image tags out of 'docker run' invocations. This update pins 'hadolint/hadolint:v2.15.1' and 'gitleaks:v8.30.1' inside workflow steps, and without these managers those tags would never be updated. The '.circleci' patterns are inert here and kept for template parity. The project's 'Australia/Melbourne' timezone is unchanged.
…aceb9e. Adopted the template's version of this script, which adds an early bail-out in production, moves from the deprecated 'pm:enable' to 'pm:install', tolerates modules missing from '--no-dev' builds, and corrects the 'Drupal\Core\Site\Settings' namespace casing. Re-added the Testmode module, which the template's version does not install. Behat scenarios tagged '@Testmode' restrict lists to test content and the module is excluded from exported configuration, so provisioning is the only place it gets installed.
Took the standard message helpers and the 'composer_run' wrapper, which suppresses Composer's progress output during this bootstrap and replays it on stderr only when a command fails, so the ahoy entrypoint stays quiet without losing diagnostics. This project's local fix that removes an existing tooling directory before the move has since landed upstream, so the file now matches the template with no divergence.
Resets the search tracker and reindexes on local, ci, dev and stage, skipping production. This project runs Solr through 'search_api_solr' but had no indexing step in provisioning, so search content was only indexed by cron or by hand after a database restore. Set 'DRUPAL_SEARCH_INDEX_SKIP=1' to turn it off for an environment.
Moved the default version bump from the removed top-level 'version-resolver' key to a 'version-resolver' category entry, which is where release-drafter now reads it. Left as it was, the default minor increment would be ignored and drafted releases would resolve their version incorrectly.
Bumped the pinned 'toshimaru/auto-author-assign' SHA to v3.1.0.
…eb9e. Read the Lagoon webhook endpoint from 'vars' rather than 'env'. The step declared no 'env' block of its own, so the old reference resolved to an empty string and the override silently fell back to the hardcoded default.
…ceb9e. Granted the job 'issues: write', which Renovate needs to maintain its Dependency Dashboard issue, and bumped the pinned checkout, setup-node and renovate action SHAs. This repository already has 'renovate.json' and a 'RENOVATE_TOKEN', so the workflow is live rather than dormant.
…ceb9e. Bumped the pinned checkout and release-drafter action SHAs. The release-drafter bump is what reads the 'version-resolver' category introduced in '.github/release-drafter.yml'.
Took the reworked trigger gate: 'VR_DIFFY_AUTO_BRANCHES' becomes 'VR_DIFFY_PR_SKIP_BRANCHES', a new 'VR_DIFFY_BRANCHES' opts whole branches in outside the PR flow, and the branch matching moves into shared helpers. Neither variable is set on this repository, so the gate keeps its current behaviour of running on the 'VR' label with 'deps/*' bypassing it. This project's own additions to the file - the run-summary step, the summary job output and the 'pages_changed' jq fix - have since landed upstream, so the file now matches the template with no divergence.
Receives the Composer audit and Gitleaks steps that this update removes from 'build-test-deploy.yml', so a failing security check is distinguishable from a failing linter and can be re-run on its own. Declining it would have dropped both scans entirely. Needs no new tokens or services - it runs in the same ci-runner image and reads the existing 'VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE' and 'VORTEX_CI_GITLEAKS_IGNORE_FAILURE' variables. The audit now runs with '--locked', so it resolves against 'composer.lock' rather than the installed tree.
…b9e. Moved the Composer audit and Gitleaks steps out to the new 'audit.yml' workflow, bumped the ci-runner image to 26.8.0, pinned 'hadolint/hadolint' to v2.15.1 so Renovate can track it, and bumped the checkout action. Added an opt-in 'Free up disk space on the runner' step gated on the 'CI_FREE_DISK_SPACE' variable, pruned dangling images after the stack starts, and removed the database dump from the runner once it is inside the container so the job does not hold two copies. Kept npm for the theme lint step. The root of this repository uses yarn and the 'drevops' subtheme uses npm, so the template's blanket yarn default is correct at the root and wrong for the theme.
Added the 'ENVIRONMENT_' prefix to the environment variable filter for the cli command, so the 'ENVIRONMENT_TYPE' override introduced in 'docker-compose.yml' reaches the container instead of being dropped at the boundary.
| * | ||
| * This file was generated by drupal-composer/drupal-scaffold. | ||
| * https://github.com/drupal-composer/drupal-scaffold | ||
| * This file was generated by drupal-scaffold. |
There was a problem hiding this comment.
Docblock only: the scaffold attribution is shortened and a @see pointing at core/modules/statistics/statistics.php is dropped, that module having been removed from Drupal core. No code change.
| use Drupal\Tests\media\Traits\MediaTypeCreationTrait; | ||
| use PHPUnit\Framework\Attributes\CoversClass; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
Adds #[RunTestsInSeparateProcesses], required by PhpUnitAddRunTestsInSeparateProcessesAttributeRector, which reached this project through the rector set-provider migration in rector.php. The lint gate fails without it.
Rector emits the attribute fully qualified; it is written here in the imported form to match every other attribute in the file.
Cost checked rather than assumed: timed on one class, 64.7s with the attribute against 73.2s without, and the full kernel suite passes at 107 tests and 1526 assertions. Process isolation is not making this suite slower.
| use PHPUnit\Framework\Attributes\CoversClass; | ||
| use PHPUnit\Framework\Attributes\DataProvider; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
#[RunTestsInSeparateProcesses] added for the same rector rule as the other kernel and functional tests in this PR. Import form rather than rector's fully-qualified output, to match the file's other attributes.
| // Allow to stop any mail send out through settings. Note if email | ||
| // functionality needs to be tested, this code should be removed and | ||
| // replaced with a dev mail system. | ||
| // The 'suspend_mail_send' setting stops all outgoing mail. Remove this and |
There was a problem hiding this comment.
Comment rewrite on the mail-suspension hook - the only upstream change to this file.
do_base_xmlsitemap_link_alter() is preserved. The re-render deleted it outright. It suppresses the sitemap entry for the node behind the front page, which otherwise appears twice - once as the front page and once under its internal path - with both entries serving identical content to search engines. Its absence would not have failed any gate; xmlsitemap.feature asserts the front page entry but not the absence of the duplicate.
| if (!form) { | ||
| return; | ||
| } | ||
| once('recaptcha-v3-guard', '.recaptcha-v3-token', context).forEach(function processToken(tokenInput) { |
There was a problem hiding this comment.
Formatting only. The once() callback no longer wraps now that Prettier's printWidth is 160 rather than 80, per the .prettierrc.json change in this PR. Produced by ahoy lint-fix, not hand-edited; no behaviour change.
| namespace Drupal\Tests\do_base\Functional; | ||
|
|
||
| use PHPUnit\Framework\Attributes\Group; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
Template scaffold example test. Upstream renamed the test methods to match the operation they name, collapsed the per-suite functional:subtraction group prefix to a plain subtraction, and added #[RunTestsInSeparateProcesses].
Safe here because nothing in this project selects tests by those group names - checked against phpunit.xml, .ahoy.yml and the CI workflow.
| use Drupal\node\NodeInterface; | ||
| use Drupal\preview_link\Entity\PreviewLinkInterface; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
#[RunTestsInSeparateProcesses] added for the rector rule introduced by the set-provider migration. Project test rather than scaffold - preview links are a real feature here (docs/preview-links.md) - but the change is the attribute only; no assertion or behaviour is touched.
| use Drupal\node\NodeInterface; | ||
| use PHPUnit\Framework\Attributes\DataProvider; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
#[RunTestsInSeparateProcesses] added for the same rector rule. Attribute only; the social-card assertions are unchanged.
| namespace Drupal\Tests\do_base\FunctionalJavascript; | ||
|
|
||
| use PHPUnit\Framework\Attributes\Group; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
Template scaffold example test: #[RunTestsInSeparateProcesses] added, and two comments dropped that restated the lines below them. No assertion changes.
|
|
||
| use PHPUnit\Framework\Attributes\DataProvider; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
Template scaffold example test: method and data-provider renames to match the operation each names, the kernel:subtraction group prefix collapsed to subtraction, #[RunTestsInSeparateProcesses] added, and the placeholder comments reworded. Nothing selects tests by those group names in this project.
| use Drupal\image\Entity\ImageStyle; | ||
| use PHPUnit\Framework\Attributes\DataProvider; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
#[RunTestsInSeparateProcesses] added for the rector rule. Attribute only; the image-dimensions assertions are unchanged.
| use Drupal\node\NodeInterface; | ||
| use PHPUnit\Framework\Attributes\DataProvider; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
#[RunTestsInSeparateProcesses] added for the rector rule. Attribute only; the metatag assertions are unchanged.
| use Drupal\node\NodeInterface; | ||
| use PHPUnit\Framework\Attributes\DataProvider; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
#[RunTestsInSeparateProcesses] added for the rector rule. Attribute only.
Worth noting for this file specifically: it covers the CSP page-attachments path, where the assertions depend on a fabricated route and a booted session. Process isolation gives each test method a clean container, which suits that setup rather than working against it - the suite passes unchanged.
| * | ||
| * @param string $suffix | ||
| * Optional suffix to append to the filename. Defaults to a timestamp. | ||
| * |
There was a problem hiding this comment.
Docblock only: drops a bare @see to a core issue that explained nothing on its own. The reasoning it stood for now lives in tests/phpunit/bootstrap.php, where the directory is actually created. No code change.
| * Trait MockTrait. | ||
| * | ||
| * This trait provides a method to prepare class mock. | ||
| * Provides a method to prepare class mocks. |
There was a problem hiding this comment.
Comments only: a docblock reworded and one inline comment dropped that restated its own line. No code change.
|
|
||
| $method = $class->getMethod($name); | ||
|
|
||
| // If the method is static, we won't pass an object instance to invokeArgs() |
There was a problem hiding this comment.
Two comments removed that restated the lines below them - the whole upstream change to this file.
This project's fix to getProtectedValue() is preserved, and that is the point of interest. The template still passes the ReflectionClass to ReflectionProperty::getValue() where the object instance is required, so the method raises a TypeError for any non-static property; it also drops the parameter type hints. The re-render proposed reverting this repo's corrected version back to the broken one.
Raised upstream so the template picks up the fix rather than this staying a permanent local divergence: drevops/vortex#3019
| } | ||
|
|
||
| // Replace below with a call to your class method. | ||
| // Replace the line below with a call to the method under test. |
There was a problem hiding this comment.
Template scaffold example test: method and data-provider renames, the unit:subtraction group prefix collapsed to subtraction, and the placeholder comments reworded. No RunTestsInSeparateProcesses here - the rector rule targets kernel and functional tests, not unit tests.
| use Drupal\do_content_api\Hook\ModerationPolicyHook; | ||
| use PHPUnit\Framework\Attributes\CoversClass; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
#[RunTestsInSeparateProcesses] added for the rector rule. Attribute only; the moderation-policy assertions are unchanged.
This is the class used to measure the cost of the isolation change - 64.7s with the attribute against 73.2s without, over the same 8 tests - which is what established that the rule is not slowing the suite down.
|
|
||
| if (!$entity->isNew()) { | ||
| $original = $entity->original ?? NULL; | ||
| $original = $entity->getOriginal() ?? NULL; |
There was a problem hiding this comment.
The only production code change in this PR outside settings files.
Two reads of $entity->original become $entity->getOriginal(). The property is deprecated in favour of the accessor, which returns ?static and is present in the installed core 11.4.5, so the two are equivalent here.
Flagged by rector's ReplaceEntityOriginalPropertyRector, which reached this project through the set-provider migration in rector.php: the deprecation sets are now bound to the installed core version rather than the hardcoded Drupal 9 and 10 lists, so rules newer than those lists now apply. This is the concrete payoff of that change rather than a coincidence.
| use PHPUnit\Framework\Attributes\CoversClass; | ||
| use PHPUnit\Framework\Attributes\DataProvider; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
#[RunTestsInSeparateProcesses] added for the rector rule. Attribute only; the form assertions are unchanged.
| use PHPUnit\Framework\Attributes\CoversClass; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
| use Drupal\do_feed\Hook\EntityDeleteHook; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
#[RunTestsInSeparateProcesses] added for the rector rule. Attribute only.
| use PHPUnit\Framework\Attributes\CoversClass; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
| use Drupal\do_feed\Hook\EntityPresaveHook; | ||
| use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; |
There was a problem hiding this comment.
#[RunTestsInSeparateProcesses] added for the rector rule. Attribute only - notably the assertions did not need changing despite the hook under test moving from $entity->original to $entity->getOriginal(), since the test drives the hook through entity saves rather than stubbing the property.
| declare(strict_types=1); | ||
|
|
||
| if ($settings['environment'] === ENVIRONMENT_CI) { | ||
| // Disable mail send out. |
There was a problem hiding this comment.
Drops a comment that restated the line below it. No behaviour change - mail is still suspended in CI.
| * Redis module works with Redis services. | ||
| * We use `DRUPAL_REDIS_` environment variables as the Drupal | ||
| * module name is `redis`. | ||
| * The `DRUPAL_REDIS_` environment variable prefix follows the Drupal module |
There was a problem hiding this comment.
Mostly a comment rewrite, but two real fixes are in here.
@phpcs:disable becomes phpcs:disable. With the leading @ those annotations were parsed as docblock tags rather than sniff directives, so the three suppressions at the top of this file were never actually applied - the sniffs were live the whole time.
The container class string loses its leading backslash: '\Drupal\redis\Cache\PhpRedis' becomes 'Drupal\redis\Cache\PhpRedis'. It is a plain string consumed by the container builder, not a resolved class name, and the leading separator is not part of the class name.
Redis is live here - DRUPAL_REDIS_ENABLED gates it and the service is in the compose stack - so this file is executed rather than dormant.
|
|
||
| if ($settings['environment'] === ENVIRONMENT_CI || $settings['environment'] === ENVIRONMENT_LOCAL) { | ||
| // Disable CSP locally and in CI as we do not serve the site over HTTPS. | ||
| if ($settings['environment'] === ENVIRONMENT_LOCAL || $settings['environment'] === ENVIRONMENT_CI) { |
There was a problem hiding this comment.
Comment rewrite and a reordering of the environment check to read local-then-CI, matching the other settings includes. Behaviour is identical: CSP stays disabled locally and in CI, where the site is not served over HTTPS.
|
|
||
| declare(strict_types=1); | ||
|
|
||
| // Default Shield credentials. |
There was a problem hiding this comment.
Comment rewrite and the same local-then-CI reordering as the other settings includes. No behaviour change: Shield stays enforced on every non-production environment and bypassed locally and in CI.
The retained comment is the load-bearing part - unlike the other settings files, enablement here deliberately does not follow the presence of environment variables, because Shield must stay on even when the credential variables are missing. Inverting that would silently unprotect an environment.
|
|
||
| declare(strict_types=1); | ||
|
|
||
| // Add custom domains to trusted host patterns if specified. |
There was a problem hiding this comment.
Drops a comment that restated the line below it. No behaviour change.
| '\.', '', '', '|', | ||
| ], $localdev_url); | ||
| $settings['trusted_host_patterns'][] = '^' . $container_patterns . '$'; | ||
| $container_localdev_url = getenv('LOCALDEV_URL'); |
There was a problem hiding this comment.
A real fix rather than a tidy-up. The trusted host pattern was built by a hand-rolled str_replace that escaped only dots and folded a comma-separated list into a single anchored alternation. Any other regex metacharacter in LOCALDEV_URL reached the pattern unescaped, and the alternation inside one ^...$ did not mean what it looked like.
Now each URL is split out, lowercased and escaped with preg_quote, producing one anchored pattern per host. The local variables are also prefixed so they cannot collide with the including scope - this file is included into settings.php, so a bare $patterns was shared state.
Covered by a new test in EnvironmentSettingsTest added in this PR, which passes two URLs with surrounding whitespace and a trailing empty entry and asserts both generated patterns.
| declare(strict_types=1); | ||
|
|
||
| if (!empty(getenv('LAGOON_KUBERNETES'))) { | ||
| // Environment is marked as 'production' in Lagoon. |
There was a problem hiding this comment.
The same trusted-host fix as the container settings, applied to LAGOON_ROUTES: each route is split out and escaped with preg_quote rather than folded into one alternation that escaped only dots.
This is the one that was actually in use. This project serves several routes per environment - drevops.com and www.drevops.com on production, dev.drevops.com on develop - so the old single-alternation pattern was the code path running on every Lagoon environment, not a theoretical case.
The rest is comment removal where the comment restated its line.
| $app_root ??= DRUPAL_ROOT; | ||
| $site_path ??= 'sites/default'; | ||
| // @phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable | ||
| // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable |
There was a problem hiding this comment.
@phpcs:ignore corrected to phpcs:ignore. As with the Redis settings, the leading @ made PHPCS read it as a docblock tag rather than a sniff directive, so the unused-variable suppression on the $contrib_path assignment was never applied - the sniff was live and simply had nothing to report yet.
The other change is a comment rewording on the environment-type override. This project's own settings additions in this file are unchanged.
Checklist before requesting a review
[#123] Verb in past tense.- no ticket; this is a template update#123added to description - no ticket; this is a template updateChangedsectionChanged
Covers all upstream work between the
1.40.2release and commiteaceb9ed110b5dceaa2752acf4faf7fb4606f8f3- roughly five weeks, and the content of the unreleased1.41.0. There is no tag for this point, so the commit SHA is recorded in the README badge.Key highlights: Security scanning moves out of the main build into its own
Security auditworkflow, so a failing audit is distinguishable from a failing linter and can be re-run alone. All Lagoon container images move to26.8.0, and the database container gains a 1GB InnoDB redo log so large production dumps stop aborting mid-import..dockerignoreand.gitignoreboth flip from allowlists to deny lists. The refactoring toolchain switches to a provider that binds its rule sets to the installed Drupal version rather than a hardcoded list, which immediately surfaced a deprecated entity API call in this codebase.Overall impact: No runtime code paths change and Drupal core is untouched, so the site behaves identically. The visible day-to-day differences are in CI - a new required check appears on pull requests, and the build job reclaims runner disk space when opted in. There are no breaking changes for developers, but two things need a conscious decision later:
stage_file_proxywas deliberately held at 3.x rather than following the template to 4.x, and the template now hard-gates homepage accessibility while this project still audits everything in advisory mode.Vortex Update
CI
Split Gitleaks and
composer auditinto a standaloneSecurity auditworkflow, so a failing security scan no longer looks like a failing linter and can be re-run on its own. This adds one new check to every pull request.composer auditnow runs with--locked, resolving advisories againstcomposer.lockrather than the installed tree, so the result no longer depends on whether dev dependencies are present.Added an opt-in "Free up disk space" step to the build and database jobs, gated on a
CI_FREE_DISK_SPACErepository variable. It removes preinstalled runner toolchains this project never uses. It is off unless the variable is set.The database dump is now deleted from the runner once it has been copied into the container, so the job stops holding two copies of a 31MB file for its remaining lifetime.
Pinned
hadolinttov2.15.1instead of trackinglatest, and taught Renovate to read image tags out ofdocker runlines in workflows so those pins actually get updated.Bumped the CI database cache key to
v26.8.0, which discards the existing cache once - the first build on this branch refetches the database rather than restoring it.Release drafter's default version bump moved to a
version-resolvercategory. Left on the old top-level key it would have been ignored, and drafted releases would have resolved the wrong version.The Lagoon webhook endpoint is now read from
varsrather thanenv. The step declared noenvblock, so the override silently resolved to an empty string and always fell back to the hardcoded default.Docker and local environment
All Lagoon images move to
26.8.0across the CLI, PHP, Nginx, Solr, ClamAV and database containers, with ClamAV itself on1.5.4.Raised the InnoDB redo log capacity to 1GB. The image default of 128MB is exhausted during a large dump import faster than the checkpointer reclaims it, aborting with
ERROR 1114 ... table is full.Moved the database config to
/etc/mysql/conf.d/, which is the directory the entrypoint actually rewrites - without the move the redo log setting above would have been ignored..dockerignoreis now a deny list, so everything not named is included rather than the reverse. This project's theme build outputs (dist,storybook-static,components_combined) were added to the exclusions, since the template only knows aboutbuild.Replaced file-global hadolint ignores with per-line ones that state why each rule is waived, so a new violation is no longer hidden by a blanket suppression at the top of the file.
The theme still builds with npm here. The template switched to yarn; this project ships
package-lock.jsonfor thedrevopssubtheme, so npm was kept in both the Docker build and the CI lint step.Provisioning
Provisioning is now split into numbered scripts - demo modules, development modules, search indexing and an example - replacing the single example script.
Added search indexing to provisioning, resetting the tracker and reindexing on local, CI, dev and stage. This project runs Solr but had no indexing step, so search content was only indexed by cron or by hand after a database restore. Set
DRUPAL_SEARCH_INDEX_SKIP=1to disable it per environment.Development modules now bail out early in production and install with
pm:installrather than the deprecatedpm:enable, tolerating modules absent from--no-devbuilds.Testmode is still installed during provisioning. The template's version of the development modules script does not install it, which would have broken every
@testmodeBehat scenario; it was added back and raised upstream.Raised the Drush
memory_limitto 1G, sized for the config sync and database imports this project runs on every deploy.Testing
Wired six more behat-steps traits into
FeatureContext- Cache, Iframe, Json, Redirect, Rest and Xml - making their steps available immediately, since all of them already existed in the installed library.Removed two step definitions the library now provides. behat-steps 3.13.0 absorbed
should be pinned to the top of the viewportandshould stack above the element, and a duplicate step definition aborts the whole suite before any scenario runs. The library implementations are stronger: the stacking assertion walks the stacking-context chain rather than comparing raw z-index values that are only meaningful within one context, and the pinned assertion allows two pixels of rounding and rejects a zero-height element that would otherwise report as pinned at the origin.Added scenarios covering REST, XML and JSON assertions, viewport resizing and redirects, along with two response fixtures and a new
redirect.feature.Kernel and functional tests now run in separate processes. Measured on one class this costs no time - 64.7s with isolation against 73.2s without.
The project's own test coverage was preserved throughout. The re-render would have replaced the sitemap, search, accessibility, ClamAV and Behat feature files with template versions, dropping the blog and project sitemap scenarios, the CivicTheme media bundles and the 24-region region map.
Code quality tooling
Rector now resolves its Drupal rule sets from the installed core version rather than hardcoded Drupal 9 and 10 lists, so the checks track core upgrades without editing configuration. This required a major bump of the rules provider.
That change immediately found a deprecated API call - two reads of
$entity->originalin the feed presave hook now useEntityInterface::getOriginal().Raised Prettier's
printWidthfrom 80 to 160 while pinning doc comments to 80, so code stays on one line and comments keep the narrow wrap. One JavaScript file was reformatted as a result.RemoveUnusedPublicMethodParameterRectoris now scoped tosrc/Hook/*rather than skipped everywhere, which matches the hook classes indo_base,do_feedanddo_content_api.Settings and configuration
Trusted host patterns are now built with
preg_quoteover each route individually, instead of a hand-rolled replacement that escaped only dots and folded every route into one alternation. Any other regex metacharacter inLAGOON_ROUTESorLOCALDEV_URLpreviously reached the pattern unescaped.Corrected
@phpcs:ignoretophpcs:ignoreinsettings.phpand the Redis settings. With the leading@the suppressions were read as docblock tags and never applied.Added an
ENVIRONMENT_TYPEpass-through through Docker Compose, the ahoy container filter and the settings test harness, so the auto-detected environment type can be overridden..gitignoreis now a deny list. Verified against this project: no file becomes newly visible, and the files directory, simpletest and local settings overrides all remain ignored.Added
.vortex-manifest.json, a checksum for every template-owned path. A later update reads it to tell whether a file has been modified since it was installed, which is what lets the installer prune paths the template no longer ships without destroying local changes.Excluded stray dumps and key material from the build context. The deny list covered
db_cache_*and nothing else carrying data. The dump patterns are anchored to the project root so they cannot matchscripts/sanitize.sql, which the sanitisation step reads at runtime, andauth.jsonstays included because the CLI image copies it for Composer authentication.Dependency Updates
Drupal core is unchanged at
11.4.5. Every changed package is a development dependency, none of which ship to production.Composer
Updated
drevops/behat-steps3.12.0 → 3.13.0drevops/vortex-tooling1.3.0 → 1.4.0mglaman/phpstan-drupal2.1.1 → 2.1.2palantirnet/drupal-rector0.21.2 → 1.1.2 (major)rector/rector2.6.1 → 2.6.2Added
softcreatr/jsonpath0.10.0Removed
Node
No changes to
package.jsonin either the repository root or the theme.Not included
Three things were deliberately left out of this update:
drupal/stage_file_proxystays on 3.x. The template moved to^4.0.0, but that is a contrib major with exported configuration and belongs in a dependency update rather than a template update.drupal/reroute_emailwas declined. It surfaced only because the installer was answered with every module option so that declined packages become visible; the settings file generated for it was removed.The accessibility gate was not tightened. The template now asserts the homepage passes accessibility checks as a hard gate and audits secondary pages in advisory mode; this project continues to audit everything in advisory mode.
Separately,
composer auditreportsSA-CONTRIB-2026-096againstdrupal/diff. That advisory pre-dates this branch and is unrelated to the update.Screenshots
N/A - this change touches CI configuration, Docker files, settings includes and tests. Nothing user-facing is rendered differently.
Before / After
Security scanning and the build shared one workflow, so an audit failure and a lint failure were indistinguishable and could not be re-run apart:
They now run in their own workflow, and provisioning is split into ordered, individually replaceable scripts: