From 66c18793ec63610e38d8ed0bba4cdcdec712c818 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 31 Aug 2026 12:36:13 +1000 Subject: [PATCH 01/71] Update GitHub Actions - All - Major, minor and patch (#3069) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> (cherry picked from commit c56c751867c719bdc9fea1453c917f5ce86dd69e) --- .github/workflows/update-dependencies.yml | 2 +- .github/workflows/vortex-test-common.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index d7eac08903..dbd9ed9f47 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -67,7 +67,7 @@ jobs: - name: Run Renovate if: steps.check-requirements.outputs.should_run == 'true' - uses: renovatebot/github-action@e09d604f8f803bb527bd8321ed5be06c460b8682 # v46.2.2 + uses: renovatebot/github-action@5402b206248e5a8c8427a15102702eb9c1793efc # v46.2.4 with: configurationFile: renovate.json token: ${{ secrets.RENOVATE_TOKEN }} diff --git a/.github/workflows/vortex-test-common.yml b/.github/workflows/vortex-test-common.yml index 982706b9e1..74ece7efc2 100644 --- a/.github/workflows/vortex-test-common.yml +++ b/.github/workflows/vortex-test-common.yml @@ -259,7 +259,7 @@ jobs: continue-on-error: ${{ vars.VORTEX_CI_ACTIONLINT_IGNORE_FAILURE == '1' }} - name: Check GitHub Actions security with Zizmor - uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2 + uses: zizmorcore/zizmor-action@70fb788f84895a7701f5643d103d587e460b5c99 # v0.6.3 with: # Audit only the template's own workflows. The CLI test fixtures # carry generated workflow snapshots whose action SHAs are normalized From d28298fbc60cd38175647e744a76c7e06a64f44e Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 31 Aug 2026 19:24:02 +1000 Subject: [PATCH 02/71] [#3070] Restored Drupal Rector sets and added a guard against them silently unloading. (#3071) (cherry picked from commit 121eaafb72049d251660959af081b1fa41861b76) --- .../phpunit/Functional/AhoyWorkflowTest.php | 2 + .../Traits/Subtests/SubtestAhoyTrait.php | 42 +++++++++++++++++++ composer.json | 2 +- rector.php | 38 ++++------------- 4 files changed, 52 insertions(+), 32 deletions(-) diff --git a/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php b/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php index 212ae8eeb9..de1a2a0cb4 100644 --- a/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php +++ b/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php @@ -62,6 +62,8 @@ public function testAhoyWorkflowStateless(): void { $this->subtestAhoyLintBe(); + $this->subtestAhoyLintBeRector(); + $this->subtestAhoyLintFe(); $this->subtestAhoyLintSdc(); diff --git a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php index 4f5b8eaa6b..afca3c7e58 100644 --- a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php +++ b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php @@ -458,6 +458,48 @@ protected function subtestAhoyLintBe(string $webroot = 'web'): void { $this->logStepFinish(); } + protected function subtestAhoyLintBeRector(string $webroot = 'web'): void { + $this->logStepStart(); + + // Rector reports success when its rule sets load nothing, so a passing + // `ahoy lint-be` is not evidence that the Drupal rules ran. Seed a + // deprecation that only those rules rewrite: the run has to fail, and the + // failure has to name the rule that caught it, because an unrelated rule + // firing on this file would otherwise mask a set that stopped loading. + $this->logSubstep('Assert that the Drupal Rector rule sets are loaded'); + $test_file = $webroot . '/modules/custom/sw_base/src/RectorCanary.php'; + $canary = <<<'PHP' + syncToContainer($test_file); + + $this->cmdFail('ahoy cli vendor/bin/rector --dry-run --clear-cache', ['* FunctionToStaticRector'], tio: 300, ito: 180, txt: '`rector` fails and names the rule that rewrote a deprecated Drupal call'); + + $this->removePathHostAndContainer($test_file); + + $this->logStepFinish(); + } + protected function subtestAhoyLintFe(string $webroot = 'web'): void { $this->logStepStart(); diff --git a/composer.json b/composer.json index 0b33586f37..ffee38e9b8 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,7 @@ "phpstan/phpstan": "^2.2.10", "phpunit/phpunit": "^11.5.56", "pyrech/composer-changelogs": "^2.2", - "rector/rector": "^2.6.4", + "rector/rector": ">=2.6.4 <2.6.5", "softcreatr/jsonpath": "^0.10 || ^1.0", "vincentlanglet/twig-cs-fixer": "^4.1.0" }, diff --git a/rector.php b/rector.php index 5dfa25297c..6947e3ab86 100644 --- a/rector.php +++ b/rector.php @@ -16,7 +16,6 @@ declare(strict_types=1); -use DrupalFinder\DrupalFinderComposerRuntime; use DrupalRector\Set\DrupalSetProvider; use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector; use Rector\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector; @@ -84,9 +83,9 @@ '*/vendor/*', '*/node_modules/*', ]) - // PHP version upgrade sets - modernizes syntax to PHP 8.4. - // Includes all rules from PHP 5.3 through 8.4. - ->withPhpSets(php84: TRUE) + // PHP version upgrade sets. Called without an argument, the target version + // comes from `composer.json`, so the sets follow the project's PHP version. + ->withPhpSets() #;< TOOL_BEHAT // Behat attribute sets - converts annotations to PHP 8 attributes. ->withAttributesSets(behat: TRUE) @@ -100,11 +99,10 @@ privatization: TRUE, typeDeclarations: TRUE, ) - // Drupal-specific deprecation fixes. The provider binds each set to a - // `drupal/core` version and only the sets the installed core satisfies are - // loaded, so the set tracks core upgrades without changing this - // configuration. Both calls are required: the provider supplies the sets, - // `withComposerBased()` enables the group. + // Drupal deprecation fixes for the installed `drupal/core` version. Both + // calls are required: the provider supplies the sets, `withComposerBased()` + // enables the group. The sets carry the autoload paths and the file + // extensions Drupal executes PHP from, so this file declares neither. ->withSetProviders(DrupalSetProvider::class) ->withComposerBased(drupal: TRUE) // Additional rules. @@ -112,27 +110,5 @@ DeclareStrictTypesRector::class, YieldDataProviderRector::class, ]) - // Configure Drupal autoloading. - ->withAutoloadPaths((function (): array { - $drupalFinder = new DrupalFinderComposerRuntime(); - $drupalRoot = $drupalFinder->getDrupalRoot(); - - return [ - $drupalRoot . '/core', - $drupalRoot . '/modules', - $drupalRoot . '/themes', - $drupalRoot . '/profiles', - ]; - })()) - // Drupal file extensions. - ->withFileExtensions([ - 'php', - 'module', - 'install', - 'profile', - 'theme', - 'inc', - 'engine', - ]) // Import configuration. ->withImportNames(importNames: FALSE, importDocBlockNames: FALSE); From 17cd72715ba2316829e3b7493214410f86bdb43f Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:39:02 +1100 Subject: [PATCH 03/71] Bumped 'drevops/behat-steps' to '^3.14.2'. Forward-ported from main 367929b0454f5f0d36cbb312b90219c04e6c5687. Only the constraint carries over: the cache key bump belongs to main's 'VORTEX_DB_IMAGE_BASE' change and the lock files are refreshed separately on 2.x. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ffee38e9b8..524c2f036c 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,7 @@ "dealerdirect/phpcodesniffer-composer-installer": "^1.2.1", "drevops/behat-format-progress-fail": "^1.5.1", "drevops/behat-screenshot": "^2.6.0", - "drevops/behat-steps": "^3.14.1", + "drevops/behat-steps": "^3.14.2", "drevops/phpcs-standard": "^1.0.0", "drupal/coder": "^9.0.1", "drupal/drupal-extension": "^6.1", From c7c713637ef8b01379ae6e44e25d02fd25a7d09f Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:39:22 +1100 Subject: [PATCH 04/71] Suppressed the 'git init' branch advice leaking into the CLI output. Forward-ported from main 2bf1dadb1ebcfde5c6ca0e2b6d8a209cec5ca9e0, applied to '.vortex/cli/src/Utils/FileManager.php'. --- .vortex/cli/src/Utils/FileManager.php | 4 +++- .vortex/docs/.utils/update-videos.php | 11 ++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.vortex/cli/src/Utils/FileManager.php b/.vortex/cli/src/Utils/FileManager.php index 3238007d1b..a7919d1150 100644 --- a/.vortex/cli/src/Utils/FileManager.php +++ b/.vortex/cli/src/Utils/FileManager.php @@ -34,7 +34,9 @@ public function prepareDestination(): array { if (!is_readable($dst . '/.git')) { $messages[] = sprintf('Initialising a new Git repository in directory "%s".', $dst); - passthru(sprintf('git --work-tree="%s" --git-dir="%s/.git" init > /dev/null', $dst, $dst)); + // 'git init' writes the initial branch advice to stderr when + // 'init.defaultBranch' is unset, and passthru() draws it inside the TUI. + passthru(sprintf('git -c advice.defaultBranchName=false --work-tree="%s" --git-dir="%s/.git" init > /dev/null', $dst, $dst)); if (!File::exists($dst . '/.git')) { throw new \RuntimeException(sprintf('Unable to initialise Git repository in directory "%s".', $dst)); diff --git a/.vortex/docs/.utils/update-videos.php b/.vortex/docs/.utils/update-videos.php index f26768ac7e..58b38dc738 100755 --- a/.vortex/docs/.utils/update-videos.php +++ b/.vortex/docs/.utils/update-videos.php @@ -492,4 +492,13 @@ function main(array $argv): int { return 0; } -exit(main($argv)); +// A failure inside main() reports itself before it is thrown, so the message +// alone is the whole error. +try { + exit(main($argv)); +} +catch (Throwable $exception) { + fwrite(STDERR, $exception->getMessage() . "\n"); + + exit(1); +} From b757cba29c7427d2b2f9db04266f08afb4f2eef2 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Tue, 1 Sep 2026 10:37:53 +1000 Subject: [PATCH 05/71] Updated release notes template. (cherry picked from commit 73e0a8eaaab287532fa4216b130e265b3a72c719) --- .../skills/prepare-vortex-release/SKILL.md | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/.claude/skills/prepare-vortex-release/SKILL.md b/.claude/skills/prepare-vortex-release/SKILL.md index ca9e4e3006..82ea7431bf 100644 --- a/.claude/skills/prepare-vortex-release/SKILL.md +++ b/.claude/skills/prepare-vortex-release/SKILL.md @@ -193,18 +193,28 @@ Summary paragraph (1-3 sentences). ### 🌀 Template - ✨ **New** - - [#ISSUE] Title from commit/PR. @author (#PR_NUMBER) - Description paragraph explaining what changed and why it matters to users. + + - **[#ISSUE] Title from commit/PR. @author (#PR_NUMBER)** + **What it does:** ... + **How to use it:** ... + + - **[#ISSUE] Next entry. @author (#PR_NUMBER)** + **What it does:** ... + **How to use it:** ... - 🛠 **Changed** - - ... + + - ... - 🐞 **Fixed** - - ... + + - ... - ⬆️ **Updated** - - Title. @author (#PR_NUMBER) - - Title. @[renovate[bot]](https://github.com/apps/renovate) (#PR_NUMBER) + + - **Title. @author (#PR_NUMBER)** + + - **Title. @[renovate[bot]](https://github.com/apps/renovate) (#PR_NUMBER)** --- @@ -254,6 +264,7 @@ Concrete examples: (Renovate Updated-section entries: bold the title only - they have no `What it does` / `How to use it` body.) Key rules: +- **Blank lines are mandatory, not cosmetic.** Put a blank line after every group header (`- ✨ **New**`, `- 🛠 **Changed**`, `- 🐞 **Fixed**`, `- ⬆️ **Updated**`) and between every pair of entries within a group, including single-line entries in the Updated section. Without them the notes render as an unbroken wall of text that nobody reads. The `What it does:` and `How to use it:` lines of a single entry stay tight against their title line with no blank line between them - the separation is between entries, not inside one. - The first line is the PR title with issue reference, author attribution, and PR number, wrapped in `**...**`. - The body must contain **two pieces of information** for any non-trivial entry: 1. **What the change does** (the behaviour, the new feature, the bug that was fixed). From 4b509639616ff2f076f24cb1e2569583f8aaae9e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2026 16:58:54 +1000 Subject: [PATCH 06/71] Update renovatebot/github-action action to v46.2.5 (#3075) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> (cherry picked from commit 07d8658d01c1245458c04b29938cd11394641d63) --- .github/workflows/update-dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index dbd9ed9f47..63b826fe85 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -67,7 +67,7 @@ jobs: - name: Run Renovate if: steps.check-requirements.outputs.should_run == 'true' - uses: renovatebot/github-action@5402b206248e5a8c8427a15102702eb9c1793efc # v46.2.4 + uses: renovatebot/github-action@39b914146caeff8cd512e61c8992f1d5913af85c # v46.2.5 with: configurationFile: renovate.json token: ${{ secrets.RENOVATE_TOKEN }} From de33dcc286af3a57a992e349a25f5a638b2a9698 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Sep 2026 15:42:47 +1000 Subject: [PATCH 07/71] Update actions/deploy-pages digest to 368f825 (#3076) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> (cherry picked from commit 3e6111182c467b08a3cac9f433fd931ddca78af3) --- .github/workflows/vortex-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/vortex-release.yml b/.github/workflows/vortex-release.yml index ec07ea0f05..0e49dd6fc5 100644 --- a/.github/workflows/vortex-release.yml +++ b/.github/workflows/vortex-release.yml @@ -242,4 +242,4 @@ jobs: path: .vortex/docs_combined/build - name: Deploy to GitHub Pages - uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5 + uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5 From 14184a5b4bfc2e186c561e123b5452c036c359cd Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Thu, 3 Sep 2026 15:43:07 +1000 Subject: [PATCH 08/71] [#3077] Covered '.mjs' and '.cjs' by the '.editorconfig' line-length rule and removed the redundant 'eslint.config.mjs' section. (#3083) (cherry picked from commit 7be04c0aaf2bf6450ca55b6856887c88d073032d) --- .editorconfig | 5 +---- .../tests/Fixtures/handler_process/_baseline/.editorconfig | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.editorconfig b/.editorconfig index b448d1278e..9ceb90cf15 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,7 +14,7 @@ trim_trailing_whitespace = true insert_final_newline = true # Matches the Prettier 'printWidth' in .prettierrc.json. -[*.js] +[*.{js,mjs,cjs}] max_line_length = 160 [*.{json,lock}] @@ -23,9 +23,6 @@ indent_size = 4 [*.xml] indent_size = 4 -[eslint.config.mjs] -indent_size = 2 - [.prettierrc.json] indent_size = 2 diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.editorconfig b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.editorconfig index b448d1278e..9ceb90cf15 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.editorconfig +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.editorconfig @@ -14,7 +14,7 @@ trim_trailing_whitespace = true insert_final_newline = true # Matches the Prettier 'printWidth' in .prettierrc.json. -[*.js] +[*.{js,mjs,cjs}] max_line_length = 160 [*.{json,lock}] @@ -23,9 +23,6 @@ indent_size = 4 [*.xml] indent_size = 4 -[eslint.config.mjs] -indent_size = 2 - [.prettierrc.json] indent_size = 2 From 24e055d9fa569e3a0bd0e308bedf5093dc9c1953 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:39:48 +1100 Subject: [PATCH 09/71] [#3079] Corrected the 'appying' spelling in the '.env' provision description. Forward-ported from main 6edbf26d152391256421c6c08f51a1c11e942ad4. --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index 4ffa8e6158..3bb086a835 100644 --- a/.env +++ b/.env @@ -111,7 +111,7 @@ DRUPAL_CLAMAV_MODE=daemon ################################################################################ # By "provision", we mean the process of initialising the database (from dump -# or fresh install from profile), running updates, appying configuration +# or fresh install from profile), running updates, applying configuration # changes, clearing caches and performing other tasks that prepare the site for # use. # @see https://www.vortextemplate.com/docs/development/provision From 71629dc0ff03e02864dfe325cfc91db86e072f3d Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Thu, 3 Sep 2026 17:55:01 +1000 Subject: [PATCH 10/71] [#3082] Excluded 'sdc_devel' from exported configuration like the other development modules. (#3088) (cherry picked from commit 9f7de2a5e1a0e8f9da80dfb5dd18bba4b8a2405b) --- .../modules/contributed-modules.mdx | 2 +- .../Traits/Subtests/SubtestAhoyTrait.php | 18 ++++++- .../Drupal/EnvironmentSettingsTest.php | 48 +++++++++++++++++++ .../includes/modules/settings.sdc_devel.php | 10 ++++ 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 web/sites/default/includes/modules/settings.sdc_devel.php diff --git a/.vortex/docs/content/development/modules/contributed-modules.mdx b/.vortex/docs/content/development/modules/contributed-modules.mdx index b6d3f07f50..446b36bf3e 100644 --- a/.vortex/docs/content/development/modules/contributed-modules.mdx +++ b/.vortex/docs/content/development/modules/contributed-modules.mdx @@ -224,7 +224,7 @@ email rerouting in an environment where it would otherwise be enabled. ### Configuration -No settings override. +[`settings.sdc_devel.php`](https://github.com/drevops/vortex/blob/main/web/sites/default/includes/modules/settings.sdc_devel.php) excludes it from the exported configuration. ## Search API diff --git a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php index afca3c7e58..b9ed77dbb9 100644 --- a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php +++ b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php @@ -271,11 +271,25 @@ protected function subtestAhoyProvision(): void { $this->syncToHost('config'); $this->assertFilesWildcardExists('config/default/*.yml'); - $this->logSubstep('Assert demo-only modules are excluded from the exported configuration'); - $this->cmd('ahoy drush pm:list --status=enabled --type=module --format=list', ['* generated_content', '* testmode'], 'Demo-only modules should be enabled after provisioning with demo content'); + $this->logSubstep('Assert development modules are excluded from the exported configuration'); + $this->cmd('ahoy drush pm:list --status=enabled --type=module --format=json', ['* "devel":', '* "generated_content":', '* "sdc_devel":', '* "testmode":'], 'Development modules should be enabled after provisioning'); + $this->assertFileNotContainsString('config/default/core.extension.yml', 'devel', 'Excluded module "devel" should not appear in the exported extension list'); $this->assertFileNotContainsString('config/default/core.extension.yml', 'generated_content', 'Excluded module "generated_content" should not appear in the exported extension list'); + $this->assertFileNotContainsString('config/default/core.extension.yml', 'sdc_devel', 'Excluded module "sdc_devel" should not appear in the exported extension list'); $this->assertFileNotContainsString('config/default/core.extension.yml', 'testmode', 'Excluded module "testmode" should not appear in the exported extension list'); + $this->logSubstep('Assert provisioned modules are captured in the exported configuration'); + $this->assertFileContainsString('config/default/core.extension.yml', 'config_split', 'Module "config_split" should appear in the exported extension list'); + $this->assertFileContainsString('config/default/core.extension.yml', 'environment_indicator', 'Module "environment_indicator" should appear in the exported extension list'); + $this->assertFileContainsString('config/default/core.extension.yml', 'pathauto', 'Module "pathauto" should appear in the exported extension list'); + $this->assertFileContainsString('config/default/core.extension.yml', 'redirect', 'Module "redirect" should appear in the exported extension list'); + $this->assertFileContainsString('config/default/core.extension.yml', 'search_api', 'Module "search_api" should appear in the exported extension list'); + $this->assertFileContainsString('config/default/core.extension.yml', 'shield', 'Module "shield" should appear in the exported extension list'); + $this->assertFileContainsString('config/default/core.extension.yml', 'stage_file_proxy', 'Module "stage_file_proxy" should appear in the exported extension list'); + $this->assertFileContainsString('config/default/core.extension.yml', 'sw_base', 'Module "sw_base" should appear in the exported extension list'); + $this->assertFileContainsString('config/default/core.extension.yml', 'sw_demo', 'Module "sw_demo" should appear in the exported extension list'); + $this->assertFileContainsString('config/default/core.extension.yml', 'sw_search', 'Module "sw_search" should appear in the exported extension list'); + $this->seedCacheTableRow(); $this->cmd('ahoy export-db db.sql', '* Exported database dump saved', 'Export database should complete successfully'); diff --git a/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 40ce6a863c..1b7ac2f55c 100644 --- a/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -342,6 +342,9 @@ public function testEnvironmentNoOverrides(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -445,6 +448,9 @@ public function testEnvironmentOverrides(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -513,6 +519,9 @@ public function testEnvironmentLocal(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -582,6 +591,9 @@ public function testEnvironmentLocalContainer(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -654,6 +666,9 @@ public function testEnvironmentCircleCi(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -725,6 +740,9 @@ public function testEnvironmentGha(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -792,6 +810,9 @@ public function testEnvironmentAcquiaDynamic(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -856,6 +877,9 @@ public function testEnvironmentAcquiaDev(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -920,6 +944,9 @@ public function testEnvironmentAcquiaStage(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -981,6 +1008,9 @@ public function testEnvironmentAcquiaProd(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -1046,6 +1076,9 @@ public function testEnvironmentAcquiaConfigPathOverride(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -1118,6 +1151,9 @@ public function testEnvironmentAcquiaConfigVcsDirectoryFallback(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -1190,6 +1226,9 @@ public function testEnvironmentLagoonPreview(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -1264,6 +1303,9 @@ public function testEnvironmentLagoonDev(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -1338,6 +1380,9 @@ public function testEnvironmentLagoonTest(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -1410,6 +1455,9 @@ public function testEnvironmentLagoonProd(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_SDC_DEVEL + 'sdc_devel', + // phpcs:ignore #;> MODULE_SDC_DEVEL // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE diff --git a/web/sites/default/includes/modules/settings.sdc_devel.php b/web/sites/default/includes/modules/settings.sdc_devel.php new file mode 100644 index 0000000000..f0759b3ae7 --- /dev/null +++ b/web/sites/default/includes/modules/settings.sdc_devel.php @@ -0,0 +1,10 @@ + Date: Fri, 4 Sep 2026 06:30:29 +1000 Subject: [PATCH 11/71] [#3078] Kept 'auth.json' out of the container build context and image. (#3084) (cherry picked from commit b5c93d4b8b663ecbeeec92297e1c31acecf04b77) --- .docker/cli.dockerfile | 2 +- .dockerignore | 3 +++ .../phpunit/Functional/DockerComposeWorkflowTest.php | 9 +++++++++ .vortex/tests/phpunit/Traits/SutTrait.php | 2 +- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.docker/cli.dockerfile b/.docker/cli.dockerfile index 59087b65dc..eb732790a4 100644 --- a/.docker/cli.dockerfile +++ b/.docker/cli.dockerfile @@ -78,7 +78,7 @@ COPY scripts /app/scripts # to the repository. # The .env file (and other environment files) is copied into the image, as it # may be needed by Composer scripts to access additional variables. -COPY composer.json composer.* patches.lock.* .env* auth* /app/ +COPY composer.json composer.* patches.lock.* .env* /app/ #;< VORTEX_DEV # Copy the in-tree drevops/vortex-tooling package so the path repository diff --git a/.dockerignore b/.dockerignore index 22544fa0ee..b690ae92ae 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,6 +11,9 @@ .vscode **/.DS_Store +# Credentials. The package token reaches the build through a build secret. +auth* + # Drupal directories generated by Composer during the image build. web/core web/libraries diff --git a/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php b/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php index 1e3788724f..eab49ab286 100644 --- a/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php +++ b/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php @@ -128,11 +128,20 @@ public function testDockerComposePackageToken(): void { $this->assertFileContainsString('composer.json', 'drevops/test-private-package', 'composer.json should contain private package'); File::remove('composer.lock'); + $this->logSubstep('Adding a decoy auth.json to the build context'); + // The bogus token leaves both build outcomes unchanged, so the assertion + // below tests only whether the file reaches the image. + File::dump('auth.json', json_encode(['github-oauth' => ['github.com' => 'decoy-token']], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"); + $this->logSubstep('Building without PACKAGE_TOKEN - should fail'); $this->cmdFail('docker compose build cli --no-cache', out: '* did not complete successfully', txt: 'Build stack images without token should fail', env: ['PACKAGE_TOKEN' => FALSE], tio: 15 * 60); $this->logSubstep('Building with PACKAGE_TOKEN - should succeed'); $this->cmd('docker compose build cli --no-cache', txt: 'Build stack images with token should succeed', env: ['PACKAGE_TOKEN' => $package_token], tio: 15 * 60); + + $this->logSubstep('Asserting that auth.json is absent from the built image'); + $this->assertFileExists('auth.json', 'auth.json should still exist in the build context'); + $this->cmd('docker compose run --rm --no-deps -T --entrypoint bash cli -c "test ! -f /app/auth.json"', txt: 'Built image should not contain auth.json'); } } diff --git a/.vortex/tests/phpunit/Traits/SutTrait.php b/.vortex/tests/phpunit/Traits/SutTrait.php index 3db75180c7..51497ad972 100644 --- a/.vortex/tests/phpunit/Traits/SutTrait.php +++ b/.vortex/tests/phpunit/Traits/SutTrait.php @@ -138,7 +138,7 @@ protected function injectTestingTooling(): void { $dockerfile_path = $sut_root . DIRECTORY_SEPARATOR . '.docker' . DIRECTORY_SEPARATOR . 'cli.dockerfile'; if (file_exists($dockerfile_path)) { $content = (string) file_get_contents($dockerfile_path); - $needle = 'COPY composer.json composer.* patches.lock.* .env* auth* /app/'; + $needle = 'COPY composer.json composer.* patches.lock.* .env* /app/'; $replacement = $needle . "\n\n# Test-only: enables path-repo resolution.\nCOPY .tooling-source /app/.tooling-source"; file_put_contents($dockerfile_path, str_replace($needle, $replacement, $content)); } From 394a21ff32290bcc63a5d3a708024e3599565cb7 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:41:05 +1100 Subject: [PATCH 12/71] Update selenium/standalone-chromium Docker tag to v152. Forward-ported from main 1c1981b4592055302170bf5c0892ca6991f59c52, applied to the 'browser' service. --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 4af6c63025..90fba02580 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -264,7 +264,7 @@ services: # Browser container, used for browser testing. browser: - image: selenium/standalone-chromium:151.0 + image: selenium/standalone-chromium:152.0 environment: <<: *default-environment <<: *default-volumes From 81f70f3fe3188e604cd050146bfc010436a90866 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:41:12 +1100 Subject: [PATCH 13/71] Update PHP - Drupal core - Minor and patch to ~11.4.6. Forward-ported from main 5666568fb2301b8d1d8cbb01c0ec8dacd0e876f9. --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 524c2f036c..02d2c19819 100644 --- a/composer.json +++ b/composer.json @@ -13,8 +13,8 @@ "drupal/coffee": "^2.0.1", "drupal/config_split": "^2.0.2", "drupal/config_update": "^2@alpha", - "drupal/core-composer-scaffold": "~11.4.5", - "drupal/core-recommended": "~11.4.5", + "drupal/core-composer-scaffold": "~11.4.6", + "drupal/core-recommended": "~11.4.6", "drupal/deploy_steps": "^1.0.0-alpha1", "drupal/devel": "^5.5", "drupal/drupal_helpers": "^2.1.0", From 96dddee3b0aac6931acf4f8eb9606626dd2507f6 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:41:57 +1100 Subject: [PATCH 14/71] Removed Composer requirements that top-level packages already provide. Forward-ported from main ccec81401785d933f80582ee0af79d638265c61a. The Rector skips it added are already on 2.x, so only the 'composer.json' and documentation changes carry over. --- .vortex/docs/content/development/composer.mdx | 7 +------ composer.json | 9 ++------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/.vortex/docs/content/development/composer.mdx b/.vortex/docs/content/development/composer.mdx index b0b17b2be5..b26bb52f1c 100644 --- a/.vortex/docs/content/development/composer.mdx +++ b/.vortex/docs/content/development/composer.mdx @@ -572,7 +572,6 @@ where each module is installed. | [`drupal/testmode`](https://www.drupal.org/project/testmode) | Adjusts site behavior during automated tests, for example by filtering out generated content from listings. | [Testmode](modules/testmode.mdx), [Settings](settings.mdx#per-module-overrides) | | [`drupal/xmlsitemap`](https://www.drupal.org/project/xmlsitemap) | Generates a multilingual XML sitemap to help search engines index the site. | [Settings](settings.mdx#per-module-overrides) | | [`drush/drush`](https://github.com/drush-ops/drush) | A command-line shell and scripting interface for Drupal, providing a wide range of utilities to manage and interact with your Drupal sites. | [Drush](environment/drush.mdx) | -| [`webflo/drupal-finder`](https://github.com/webflo/drupal-finder) | Locates Drupal installations in a directory structure. | | #### `require-dev` @@ -586,7 +585,6 @@ environment keeps its full tooling. |---------|-------------|---------------| | [`behat/behat`](https://github.com/Behat/Behat) | A PHP framework for Behavior-Driven Development (BDD), running human-readable stories that describe the behavior of your application. It facilitates communication between developers, stakeholders and clients. | [Behat](testing/behat.mdx) | | [`dantleech/gherkin-lint`](https://github.com/dantleech/gherkin-lint) | Lints the Gherkin feature files used in Behat tests, checking syntax and formatting for consistency. | [Gherkin Lint](code-quality/gherkin-lint.mdx) | -| [`dealerdirect/phpcodesniffer-composer-installer`](https://github.com/Dealerdirect/phpcodesniffer-composer-installer) | Registers the coding standards installed through Composer with PHP_CodeSniffer, so they can be referenced by name. | [PHPCS](code-quality/phpcs.mdx) | | [`drevops/behat-format-progress-fail`](https://github.com/drevops/behat-format-progress-fail) | A Behat output formatter that prints compact progress and expands the detail only for failing scenarios. | [Behat](testing/behat.mdx) | | [`drevops/behat-screenshot`](https://github.com/drevops/behat-screenshot) | Automatically captures a screenshot when a Behat scenario fails, which helps to understand why a test failed. | [Behat](testing/behat.mdx) | | [`drevops/behat-steps`](https://github.com/drevops/behat-steps) | A collection of pre-defined Behat step definitions for Drupal, speeding up the process of writing new tests. | [Behat](testing/behat.mdx) | @@ -594,18 +592,15 @@ environment keeps its full tooling. | [`drupal/coder`](https://www.drupal.org/project/coder) | Provides the PHP_CodeSniffer rules for the Drupal coding standards. The 9.x line targets PHP_CodeSniffer 4.x. | [PHPCS](code-quality/phpcs.mdx) | | [`drupal/drupal-extension`](https://github.com/jhedstrom/drupalextension) | A Behat extension that integrates with Drupal, offering Drupal-specific step definitions and bootstrapping the site for testing. | [Behat](testing/behat.mdx) | | [`ergebnis/composer-normalize`](https://github.com/ergebnis/composer-normalize) | A Composer plugin that normalizes the formatting and key order of `composer.json`. | | -| [`lullabot/mink-selenium2-driver`](https://github.com/lullabot/mink-selenium2-driver) | A maintained fork of the Mink Selenium2 driver that lets Behat control real browsers through Selenium WebDriver. | [Behat](testing/behat.mdx) | -| [`lullabot/php-webdriver`](https://github.com/lullabot/php-webdriver) | A maintained fork of the PHP WebDriver client used by the Mink Selenium2 driver to communicate with browsers. | [Behat](testing/behat.mdx) | | [`mglaman/phpstan-drupal`](https://github.com/mglaman/phpstan-drupal) | Teaches PHPStan about Drupal APIs, so static analysis understands hooks, services and entities in modules and themes. | [PHPStan](code-quality/phpstan.mdx) | | [`mikey179/vfsstream`](https://github.com/bovigo/vfsStream) | A virtual file system for PHPUnit tests, allowing file operations to be exercised without touching the real file system. | [PHPUnit](testing/phpunit.mdx) | -| [`palantirnet/drupal-rector`](https://github.com/palantirnet/drupal-rector) | Rector rules that rewrite deprecated Drupal code, making core upgrades more efficient. | [Rector](code-quality/rector.mdx) | +| [`palantirnet/drupal-rector`](https://github.com/palantirnet/drupal-rector) | Rector rules that rewrite deprecated Drupal code, making core upgrades more efficient. It installs [`rector/rector`](https://github.com/rectorphp/rector) and constrains it to the versions its rule sets support. | [Rector](code-quality/rector.mdx) | | [`phpcompatibility/php-compatibility`](https://github.com/PHPCompatibility/PHPCompatibility) | PHP_CodeSniffer sniffs that check code for compatibility with specific PHP versions. The 10.x line targets PHP_CodeSniffer 4.x. | [PHPCS](code-quality/phpcs.mdx) | | [`phpspec/prophecy-phpunit`](https://github.com/phpspec/prophecy-phpunit) | Integrates the Prophecy mocking library with PHPUnit to provide advanced mocking capabilities in tests. | [PHPUnit](testing/phpunit.mdx) | | [`phpstan/extension-installer`](https://github.com/phpstan/extension-installer) | Automatically registers the installed PHPStan extensions, removing the need to wire them up by hand. | [PHPStan](code-quality/phpstan.mdx) | | [`phpstan/phpstan`](https://github.com/phpstan/phpstan) | A static analysis tool that finds type errors, incorrect method calls and other bugs without running the code. | [PHPStan](code-quality/phpstan.mdx) | | [`phpunit/phpunit`](https://github.com/sebastianbergmann/phpunit) | The PHP testing framework, used here for unit, kernel and functional tests. | [PHPUnit](testing/phpunit.mdx) | | [`pyrech/composer-changelogs`](https://github.com/pyrech/composer-changelogs) | Prints a summary of package additions, updates and removals after running `composer update`. | | -| [`rector/rector`](https://github.com/rectorphp/rector) | An automated refactoring tool that upgrades and modernizes PHP code. | [Rector](code-quality/rector.mdx) | | [`softcreatr/jsonpath`](https://github.com/SoftCreatR/JSONPath) | A JSONPath implementation required by the `drevops/behat-steps` JSON assertion steps. | [Behat](testing/behat.mdx) | | [`vincentlanglet/twig-cs-fixer`](https://github.com/VincentLanglet/Twig-CS-Fixer) | Checks and fixes Twig templates against a coding standard, keeping template files consistent and readable. | [Twig CS Fixer](code-quality/twig-cs-fixer.mdx) | diff --git a/composer.json b/composer.json index 02d2c19819..e35f353685 100644 --- a/composer.json +++ b/composer.json @@ -36,13 +36,11 @@ "drupal/stage_file_proxy": "^4.0.0", "drupal/testmode": "^2.7.1", "drupal/xmlsitemap": "^2.0", - "drush/drush": "^13.7.6", - "webflo/drupal-finder": "^1.3.1" + "drush/drush": "^13.7.6" }, "require-dev": { "behat/behat": "^3.32.0", "dantleech/gherkin-lint": "^0.2.4", - "dealerdirect/phpcodesniffer-composer-installer": "^1.2.1", "drevops/behat-format-progress-fail": "^1.5.1", "drevops/behat-screenshot": "^2.6.0", "drevops/behat-steps": "^3.14.2", @@ -50,18 +48,15 @@ "drupal/coder": "^9.0.1", "drupal/drupal-extension": "^6.1", "ergebnis/composer-normalize": "^2.52.0", - "lullabot/mink-selenium2-driver": "^1.7.4", - "lullabot/php-webdriver": "^2.0.7", "mglaman/phpstan-drupal": "^2.1.1", "mikey179/vfsstream": "^1.6.12", - "palantirnet/drupal-rector": "^1.1.2", + "palantirnet/drupal-rector": "^1.1.3", "phpcompatibility/php-compatibility": "^10.0@alpha", "phpspec/prophecy-phpunit": "^2.5", "phpstan/extension-installer": "^1.4.3", "phpstan/phpstan": "^2.2.10", "phpunit/phpunit": "^11.5.56", "pyrech/composer-changelogs": "^2.2", - "rector/rector": ">=2.6.4 <2.6.5", "softcreatr/jsonpath": "^0.10 || ^1.0", "vincentlanglet/twig-cs-fixer": "^4.1.0" }, From f38ab81804cddccbada8e8b310ff953f233a0f9d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Sep 2026 14:36:38 +1000 Subject: [PATCH 15/71] Update renovatebot/github-action action to v46.2.6 (#3095) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> (cherry picked from commit bdf1646371624c299a6b20b6f9027b005021dd75) --- .github/workflows/update-dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index 63b826fe85..7ac812feba 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -67,7 +67,7 @@ jobs: - name: Run Renovate if: steps.check-requirements.outputs.should_run == 'true' - uses: renovatebot/github-action@39b914146caeff8cd512e61c8992f1d5913af85c # v46.2.5 + uses: renovatebot/github-action@37beffda261423addd537c33f2d126df7f6ffbab # v46.2.6 with: configurationFile: renovate.json token: ${{ secrets.RENOVATE_TOKEN }} From 7e8100c801612ec9e254394c3885863aa414fe04 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Tue, 8 Sep 2026 09:28:12 +1000 Subject: [PATCH 16/71] Added a 'filter-by-range' input to release-drafter to skip CalVer and Drupal-era tags. (#3097) (cherry picked from commit 9052460a647de2345120bce2c88b38e9b2aaf692) --- .github/workflows/draft-release-notes.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/draft-release-notes.yml b/.github/workflows/draft-release-notes.yml index f0f2958371..b4e3e190d5 100644 --- a/.github/workflows/draft-release-notes.yml +++ b/.github/workflows/draft-release-notes.yml @@ -46,3 +46,8 @@ jobs: tag: ${{ steps.calver.outputs.version }} name: ${{ steps.calver.outputs.version }} version: ${{ steps.calver.outputs.version }} + #;< VORTEX_DEV + # The previous release is the numerically highest one, so the range + # excludes the releases left behind by the switch from CalVer. + filter-by-range: '>=1.0.0 <7.0.0' + #;> VORTEX_DEV From f8e58ccf7769f6140d814c5cee7c5bbd4c574931 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:42:23 +1100 Subject: [PATCH 17/71] Replaced 'name:' with 'usage:' and normalised the working directory flags in the maintenance '.ahoy.yml'. Forward-ported the '.vortex/.ahoy.yml' part of main efa94ff2fe5431f63cef683a271be71aac511833. The installer, Bash tooling and BATS parts of that commit target subsystems that 2.x replaced. --- .vortex/.ahoy.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.vortex/.ahoy.yml b/.vortex/.ahoy.yml index cc5241a96b..5885be6136 100644 --- a/.vortex/.ahoy.yml +++ b/.vortex/.ahoy.yml @@ -4,7 +4,7 @@ ahoyapi: v2 commands: install: - name: Install test dependencies. + usage: Install test dependencies. cmd: | [ -d ./tests/vendor ] && rm -rf ./tests/vendor composer --working-dir tests install @@ -18,19 +18,19 @@ commands: yarn --cwd=docs install --frozen-lockfile docs: - name: Start documentation server. + usage: Start documentation server. cmd: | [ ! -d ./docs/node_modules ] && yarn --cwd=docs install --frozen-lockfile yarn --cwd=docs run start docs-serve: - name: Serve built documentation. + usage: Serve built documentation. cmd: | [ ! -d ./docs/node_modules ] && yarn --cwd=docs install --frozen-lockfile yarn --cwd=docs run start build-docs: - name: Build documentation. + usage: Build documentation. cmd: | [ ! -d ./docs/node_modules ] && yarn --cwd=docs install --frozen-lockfile yarn --cwd=docs run build @@ -48,13 +48,13 @@ commands: php -S "localhost:${port}" -t ./docs_combined/build ./docs/.utils/serve-router.php build-cli: - name: Build the Vortex CLI PHAR. + usage: Build the Vortex CLI PHAR. cmd: | [ ! -d ./cli/vendor ] && composer --working-dir cli install composer --working-dir cli build lint: - name: Lint Vortex project. + usage: Lint Vortex project. cmd: | ahoy lint-cli ahoy lint-tests @@ -66,7 +66,7 @@ commands: ahoy lint-ci lint-fix: - name: Fix linting issues in Vortex project. + usage: Fix linting issues in Vortex project. cmd: | ahoy lint-cli-fix ahoy lint-tests-fix @@ -114,13 +114,13 @@ commands: lint-docs: cmd: | yarn --cwd=docs run lint - yarn --cwd=./docs run spellcheck + yarn --cwd=docs run spellcheck lint-docs-fix: cmd: yarn --cwd=docs run lint-fix test: - name: Test Vortex project. + usage: Test Vortex project. cmd: | ahoy test-tooling ahoy test-docs @@ -132,17 +132,17 @@ commands: test-docs: cmd: | - [ ! -d ./docs/node_modules ] && yarn --cwd=./docs install --frozen-lockfile - yarn --cwd=./docs run test - yarn --cwd=./docs run spellcheck + [ ! -d ./docs/node_modules ] && yarn --cwd=docs install --frozen-lockfile + yarn --cwd=docs run test + yarn --cwd=docs run spellcheck # If there are changes to the snapshots - this command will re-run twice reporting error the first time. update-snapshots: aliases: [us] cmd: | export XDEBUG_MODE=off - composer --working-dir=tests update-snapshots - composer --working-dir=cli update-snapshots -- --jobs=8 + composer --working-dir tests update-snapshots + composer --working-dir cli update-snapshots -- --jobs=8 update-snapshots-install: aliases: [usi] From 0f7ebb07ff7411b23e43ba667783554c160243ed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Sep 2026 14:04:05 +1000 Subject: [PATCH 18/71] Update zizmorcore/zizmor-action action to v0.6.4 (#3128) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> (cherry picked from commit 9aaee685429051def57a598e407eb12a8a8f92d0) --- .github/workflows/vortex-test-common.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/vortex-test-common.yml b/.github/workflows/vortex-test-common.yml index 74ece7efc2..c3efdcfbd8 100644 --- a/.github/workflows/vortex-test-common.yml +++ b/.github/workflows/vortex-test-common.yml @@ -259,7 +259,7 @@ jobs: continue-on-error: ${{ vars.VORTEX_CI_ACTIONLINT_IGNORE_FAILURE == '1' }} - name: Check GitHub Actions security with Zizmor - uses: zizmorcore/zizmor-action@70fb788f84895a7701f5643d103d587e460b5c99 # v0.6.3 + uses: zizmorcore/zizmor-action@cc914d7f3750a2d13d75c7f184a1060aa0e9d482 # v0.6.4 with: # Audit only the template's own workflows. The CLI test fixtures # carry generated workflow snapshots whose action SHAs are normalized From aaf1c5a87fc960826ae6a000a22f38275872a80f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 07:28:33 +1000 Subject: [PATCH 19/71] Update PHP - All packages except core - Minor and patch (#3131) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> (cherry picked from commit c872225299a519d218513fd00679b911bac1ac49) --- composer.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index e35f353685..c6f31b0f21 100644 --- a/composer.json +++ b/composer.json @@ -36,10 +36,10 @@ "drupal/stage_file_proxy": "^4.0.0", "drupal/testmode": "^2.7.1", "drupal/xmlsitemap": "^2.0", - "drush/drush": "^13.7.6" + "drush/drush": "^13.8.0" }, "require-dev": { - "behat/behat": "^3.32.0", + "behat/behat": "^3.33.0", "dantleech/gherkin-lint": "^0.2.4", "drevops/behat-format-progress-fail": "^1.5.1", "drevops/behat-screenshot": "^2.6.0", @@ -47,18 +47,18 @@ "drevops/phpcs-standard": "^1.0.0", "drupal/coder": "^9.0.1", "drupal/drupal-extension": "^6.1", - "ergebnis/composer-normalize": "^2.52.0", - "mglaman/phpstan-drupal": "^2.1.1", + "ergebnis/composer-normalize": "^2.53.0", + "mglaman/phpstan-drupal": "^2.2.0", "mikey179/vfsstream": "^1.6.12", "palantirnet/drupal-rector": "^1.1.3", "phpcompatibility/php-compatibility": "^10.0@alpha", "phpspec/prophecy-phpunit": "^2.5", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.2.10", + "phpstan/phpstan": "^2.2.14", "phpunit/phpunit": "^11.5.56", "pyrech/composer-changelogs": "^2.2", "softcreatr/jsonpath": "^0.10 || ^1.0", - "vincentlanglet/twig-cs-fixer": "^4.1.0" + "vincentlanglet/twig-cs-fixer": "^4.1.1" }, "conflict": { "drupal/drupal": "*" From 27f854b6f6ee78cbaac1d3b20e0273497a76cf01 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 07:29:02 +1000 Subject: [PATCH 20/71] Update renovatebot/github-action action to v46.3.0 (#3130) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> (cherry picked from commit 583421380b28b03b77f9ae6e251be34dc5e1624f) --- .github/workflows/update-dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index 7ac812feba..c32a118c2d 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -67,7 +67,7 @@ jobs: - name: Run Renovate if: steps.check-requirements.outputs.should_run == 'true' - uses: renovatebot/github-action@37beffda261423addd537c33f2d126df7f6ffbab # v46.2.6 + uses: renovatebot/github-action@c314dda4a9a93b08239ec978f2043b9a433b9ac4 # v46.3.0 with: configurationFile: renovate.json token: ${{ secrets.RENOVATE_TOKEN }} From 3fc78b78f972dcf064819b5923b5607b5c52529a Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:43:25 +1100 Subject: [PATCH 21/71] Update GitHub Actions - All - Major, minor and patch. Forward-ported from main d84d08bedaccee7204d17004080c6cae27728100, applied to every 2.x workflow that pins these actions. --- .github/workflows/build-test-deploy.yml | 2 +- .github/workflows/update-dependencies.yml | 2 +- .github/workflows/vortex-test-cli.yml | 2 +- .github/workflows/vortex-test-common.yml | 2 +- .github/workflows/vortex-test-docs.yml | 2 +- .github/workflows/vortex-test-tooling.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-test-deploy.yml b/.github/workflows/build-test-deploy.yml index 45ce63d12a..10245e54d5 100644 --- a/.github/workflows/build-test-deploy.yml +++ b/.github/workflows/build-test-deploy.yml @@ -490,7 +490,7 @@ jobs: #;< CODE_COVERAGE_PROVIDER_CODECOV - name: Upload coverage report to Codecov - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 + uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7 if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' && env.CODECOV_TOKEN != '' }} continue-on-error: true with: diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index c32a118c2d..b2d6c4394b 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -67,7 +67,7 @@ jobs: - name: Run Renovate if: steps.check-requirements.outputs.should_run == 'true' - uses: renovatebot/github-action@c314dda4a9a93b08239ec978f2043b9a433b9ac4 # v46.3.0 + uses: renovatebot/github-action@dcfba84a42d1b5d5e49bf131b1bf53511851a123 # v46.3.1 with: configurationFile: renovate.json token: ${{ secrets.RENOVATE_TOKEN }} diff --git a/.github/workflows/vortex-test-cli.yml b/.github/workflows/vortex-test-cli.yml index 22de486753..bdf954a540 100644 --- a/.github/workflows/vortex-test-cli.yml +++ b/.github/workflows/vortex-test-cli.yml @@ -99,7 +99,7 @@ jobs: if-no-files-found: error - name: Upload coverage report to Codecov - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 + uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7 continue-on-error: true with: files: .vortex/cli/.logs/cobertura.xml diff --git a/.github/workflows/vortex-test-common.yml b/.github/workflows/vortex-test-common.yml index c3efdcfbd8..7e06c78a16 100644 --- a/.github/workflows/vortex-test-common.yml +++ b/.github/workflows/vortex-test-common.yml @@ -212,7 +212,7 @@ jobs: if-no-files-found: error - name: Upload coverage report to Codecov - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 + uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7 continue-on-error: true with: directory: /tmp/.vortex-coverage-html diff --git a/.github/workflows/vortex-test-docs.yml b/.github/workflows/vortex-test-docs.yml index 07bd6fec64..3b3227a057 100644 --- a/.github/workflows/vortex-test-docs.yml +++ b/.github/workflows/vortex-test-docs.yml @@ -191,7 +191,7 @@ jobs: if-no-files-found: error - name: Upload coverage report to Codecov - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 + uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7 continue-on-error: true with: files: .vortex/docs/.logs/cobertura.xml diff --git a/.github/workflows/vortex-test-tooling.yml b/.github/workflows/vortex-test-tooling.yml index b5f8848479..d5c317c47e 100644 --- a/.github/workflows/vortex-test-tooling.yml +++ b/.github/workflows/vortex-test-tooling.yml @@ -95,7 +95,7 @@ jobs: if-no-files-found: error - name: Upload coverage report to Codecov - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 + uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7 continue-on-error: true with: files: .vortex/tooling/.logs/cobertura.xml From b709c87a7a8df8531ddd090df33b208c2c61776c Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:43:35 +1100 Subject: [PATCH 22/71] Update codecov/codecov-action digest to 303a32d. Forward-ported from main 33ff9e5f3ab910fdca13bd2deb73870a2f648f67, applied to every 2.x workflow that pins the action. --- .github/workflows/build-test-deploy.yml | 2 +- .github/workflows/vortex-test-cli.yml | 2 +- .github/workflows/vortex-test-common.yml | 2 +- .github/workflows/vortex-test-docs.yml | 2 +- .github/workflows/vortex-test-tooling.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-test-deploy.yml b/.github/workflows/build-test-deploy.yml index 10245e54d5..8077763063 100644 --- a/.github/workflows/build-test-deploy.yml +++ b/.github/workflows/build-test-deploy.yml @@ -490,7 +490,7 @@ jobs: #;< CODE_COVERAGE_PROVIDER_CODECOV - name: Upload coverage report to Codecov - uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7 + uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7 if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' && env.CODECOV_TOKEN != '' }} continue-on-error: true with: diff --git a/.github/workflows/vortex-test-cli.yml b/.github/workflows/vortex-test-cli.yml index bdf954a540..a27414e99d 100644 --- a/.github/workflows/vortex-test-cli.yml +++ b/.github/workflows/vortex-test-cli.yml @@ -99,7 +99,7 @@ jobs: if-no-files-found: error - name: Upload coverage report to Codecov - uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7 + uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7 continue-on-error: true with: files: .vortex/cli/.logs/cobertura.xml diff --git a/.github/workflows/vortex-test-common.yml b/.github/workflows/vortex-test-common.yml index 7e06c78a16..0e4140637f 100644 --- a/.github/workflows/vortex-test-common.yml +++ b/.github/workflows/vortex-test-common.yml @@ -212,7 +212,7 @@ jobs: if-no-files-found: error - name: Upload coverage report to Codecov - uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7 + uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7 continue-on-error: true with: directory: /tmp/.vortex-coverage-html diff --git a/.github/workflows/vortex-test-docs.yml b/.github/workflows/vortex-test-docs.yml index 3b3227a057..842126a8cf 100644 --- a/.github/workflows/vortex-test-docs.yml +++ b/.github/workflows/vortex-test-docs.yml @@ -191,7 +191,7 @@ jobs: if-no-files-found: error - name: Upload coverage report to Codecov - uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7 + uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7 continue-on-error: true with: files: .vortex/docs/.logs/cobertura.xml diff --git a/.github/workflows/vortex-test-tooling.yml b/.github/workflows/vortex-test-tooling.yml index d5c317c47e..2ea68154a3 100644 --- a/.github/workflows/vortex-test-tooling.yml +++ b/.github/workflows/vortex-test-tooling.yml @@ -95,7 +95,7 @@ jobs: if-no-files-found: error - name: Upload coverage report to Codecov - uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7 + uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7 continue-on-error: true with: files: .vortex/tooling/.logs/cobertura.xml From e17fea24e4267e03c5458ca32d9165e6c5b21443 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:43:37 +1100 Subject: [PATCH 23/71] Update PHP - Drupal core - Minor and patch to ~11.4.7. Forward-ported from main 0c55c07ab670d0fc6efebca62979b6509f649622. --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index c6f31b0f21..131bec4bfa 100644 --- a/composer.json +++ b/composer.json @@ -13,8 +13,8 @@ "drupal/coffee": "^2.0.1", "drupal/config_split": "^2.0.2", "drupal/config_update": "^2@alpha", - "drupal/core-composer-scaffold": "~11.4.6", - "drupal/core-recommended": "~11.4.6", + "drupal/core-composer-scaffold": "~11.4.7", + "drupal/core-recommended": "~11.4.7", "drupal/deploy_steps": "^1.0.0-alpha1", "drupal/devel": "^5.5", "drupal/drupal_helpers": "^2.1.0", From 8c1e891de9c42271bd593435c5c7b4441de394a4 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:43:41 +1100 Subject: [PATCH 24/71] Update dawidd6/action-download-artifact action to v25. Forward-ported from main 29967b239bb75247f766902ed7e4825880fe2c4d, including its Drupal core '~11.4.8' bump. --- .github/workflows/vortex-test-docs.yml | 2 +- composer.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/vortex-test-docs.yml b/.github/workflows/vortex-test-docs.yml index 842126a8cf..482cfee999 100644 --- a/.github/workflows/vortex-test-docs.yml +++ b/.github/workflows/vortex-test-docs.yml @@ -68,7 +68,7 @@ jobs: # searching by name returns the most recent successful run across all # branches, which would pull a binary built from a different commit. - name: Download the binary artifact - uses: dawidd6/action-download-artifact@d63b86af1b34672e53c440b1b83979861906bad7 # v24 + uses: dawidd6/action-download-artifact@634d83b91986fcec9be314054943fa5c976aeb0e # v25 with: run_id: ${{ github.event.workflow_run.id }} name: ${{ env.BINARY_ARTIFACT }} diff --git a/composer.json b/composer.json index 131bec4bfa..02b5ddec2c 100644 --- a/composer.json +++ b/composer.json @@ -13,8 +13,8 @@ "drupal/coffee": "^2.0.1", "drupal/config_split": "^2.0.2", "drupal/config_update": "^2@alpha", - "drupal/core-composer-scaffold": "~11.4.7", - "drupal/core-recommended": "~11.4.7", + "drupal/core-composer-scaffold": "~11.4.8", + "drupal/core-recommended": "~11.4.8", "drupal/deploy_steps": "^1.0.0-alpha1", "drupal/devel": "^5.5", "drupal/drupal_helpers": "^2.1.0", From 31417cd6656071fbf2162d5c82af0c67b9f39ed8 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 28 Sep 2026 08:18:16 +1000 Subject: [PATCH 25/71] Grouped root 'docker-compose.yml' container image updates with the other container images. (#3164) (cherry picked from commit 9bea17d7abee9800abb9402a09bc4cb472b110f6) --- .../cli/tests/Fixtures/handler_process/_baseline/renovate.json | 1 + renovate.json | 1 + 2 files changed, 2 insertions(+) diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/renovate.json b/.vortex/cli/tests/Fixtures/handler_process/_baseline/renovate.json index 865b120b97..b5f2b5e4b0 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/renovate.json +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/renovate.json @@ -171,6 +171,7 @@ "groupSlug": "container-images-all-major-minor-patch", "matchFileNames": [ ".docker/**", + "docker-compose.yml", ".circleci/**", ".github/workflows/**" ], diff --git a/renovate.json b/renovate.json index 050099d7ac..15d28764fd 100644 --- a/renovate.json +++ b/renovate.json @@ -174,6 +174,7 @@ "groupSlug": "container-images-all-major-minor-patch", "matchFileNames": [ ".docker/**", + "docker-compose.yml", ".circleci/**", ".github/workflows/**" ], From c6c8b01ca714348480c945def4cd6fe06c608c14 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:43:52 +1100 Subject: [PATCH 26/71] Update GitHub Actions - All - Major, minor and patch. Forward-ported from main 10e4aefcf7251689608d614b67e2540f4dc4fbdc. The 'upload-sarif' pins are not carried over because 2.x has no SARIF upload steps. --- .github/workflows/update-dependencies.yml | 4 ++-- .github/workflows/vortex-test-common.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index b2d6c4394b..4343e26b87 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -63,11 +63,11 @@ jobs: node-version: 22.17.1 - name: Validate Renovate configuration - uses: suzuki-shunsuke/github-action-renovate-config-validator@ee9f69e1f683ed0d08225086482b34fc9abe9300 # v2.1.0 + uses: suzuki-shunsuke/github-action-renovate-config-validator@b850926b611b1f3d3fe3729776339c217834bf2c # v2.2.0 - name: Run Renovate if: steps.check-requirements.outputs.should_run == 'true' - uses: renovatebot/github-action@dcfba84a42d1b5d5e49bf131b1bf53511851a123 # v46.3.1 + uses: renovatebot/github-action@f3a31a786096ba6b40d0f0ffe11a494ef73bfa7c # v46.3.4 with: configurationFile: renovate.json token: ${{ secrets.RENOVATE_TOKEN }} diff --git a/.github/workflows/vortex-test-common.yml b/.github/workflows/vortex-test-common.yml index 0e4140637f..9c0ab63054 100644 --- a/.github/workflows/vortex-test-common.yml +++ b/.github/workflows/vortex-test-common.yml @@ -105,7 +105,7 @@ jobs: # as used in the Renovate workflow to ensure that they both use the same # version. - name: Validate Renovate configuration - uses: suzuki-shunsuke/github-action-renovate-config-validator@ee9f69e1f683ed0d08225086482b34fc9abe9300 # v2.1.0 + uses: suzuki-shunsuke/github-action-renovate-config-validator@b850926b611b1f3d3fe3729776339c217834bf2c # v2.2.0 vortex-test-workflow: runs-on: ubuntu-latest From 90dd4aaeec6caf8b301b43bcda51966f16f2459e Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:44:01 +1100 Subject: [PATCH 27/71] Update Container images - All - Major, minor and patch to v26.9.0. Forward-ported from main 5614bc87c4d8b4cdb473b5143573bb632c05c828, applied to the renamed 2.x Docker Compose services. --- .docker/clamav.dockerfile | 2 +- .docker/cli.dockerfile | 2 +- .docker/database.dockerfile | 2 +- .docker/nginx-drupal.dockerfile | 2 +- .docker/php.dockerfile | 2 +- .docker/solr.dockerfile | 2 +- docker-compose.yml | 6 +++--- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.docker/clamav.dockerfile b/.docker/clamav.dockerfile index d706b5d51a..4601e973e1 100644 --- a/.docker/clamav.dockerfile +++ b/.docker/clamav.dockerfile @@ -8,7 +8,7 @@ # @see https://hub.docker.com/r/uselagoon/commons/tags # @see https://github.com/uselagoon/lagoon-images/tree/main/images/commons -FROM uselagoon/commons:26.8.1 AS commons +FROM uselagoon/commons:26.9.0 AS commons FROM clamav/clamav-debian:1.5.4 diff --git a/.docker/cli.dockerfile b/.docker/cli.dockerfile index eb732790a4..1ba3777dd8 100644 --- a/.docker/cli.dockerfile +++ b/.docker/cli.dockerfile @@ -8,7 +8,7 @@ # @see https://hub.docker.com/r/uselagoon/php-8.4-cli-drupal/tags # @see https://github.com/uselagoon/lagoon-images/tree/main/images/php-cli-drupal -FROM uselagoon/php-8.4-cli-drupal:26.8.1 +FROM uselagoon/php-8.4-cli-drupal:26.9.0 # Add missing variables. # @todo Remove once https://github.com/uselagoon/lagoon/issues/3121 is resolved. diff --git a/.docker/database.dockerfile b/.docker/database.dockerfile index 652ce1bc73..918bb74468 100644 --- a/.docker/database.dockerfile +++ b/.docker/database.dockerfile @@ -8,7 +8,7 @@ # # The ARG value will be updated with a value passed from docker-compose.yml -ARG IMAGE=uselagoon/mysql-8.4:26.8.1 +ARG IMAGE=uselagoon/mysql-8.4:26.9.0 FROM ${IMAGE} # hadolint ignore=DL3066 # named account provided by the base image diff --git a/.docker/nginx-drupal.dockerfile b/.docker/nginx-drupal.dockerfile index 0ed0c8a8e4..99a57768f3 100644 --- a/.docker/nginx-drupal.dockerfile +++ b/.docker/nginx-drupal.dockerfile @@ -8,7 +8,7 @@ ARG CLI_IMAGE FROM ${CLI_IMAGE:-cli} AS cli -FROM uselagoon/nginx-drupal:26.8.1 +FROM uselagoon/nginx-drupal:26.9.0 # Webroot is used for Nginx web root configuration. ARG WEBROOT=web diff --git a/.docker/php.dockerfile b/.docker/php.dockerfile index 3b51c48b36..0c14aa995a 100644 --- a/.docker/php.dockerfile +++ b/.docker/php.dockerfile @@ -9,7 +9,7 @@ ARG CLI_IMAGE FROM ${CLI_IMAGE:-cli} AS cli -FROM uselagoon/php-8.4-fpm:26.8.1 +FROM uselagoon/php-8.4-fpm:26.9.0 # hadolint ignore=DL3018 # the package set tracks the pinned base image RUN apk add --no-cache tzdata diff --git a/.docker/solr.dockerfile b/.docker/solr.dockerfile index a27eae0b6a..ea40711f92 100644 --- a/.docker/solr.dockerfile +++ b/.docker/solr.dockerfile @@ -3,7 +3,7 @@ # @see https://hub.docker.com/r/uselagoon/solr-9-drupal/tags # @see https://github.com/uselagoon/lagoon-images/blob/main/images/solr-drupal/9.Dockerfile -FROM uselagoon/solr-9-drupal:26.8.1 +FROM uselagoon/solr-9-drupal:26.9.0 # Solr jump-start config needs to be manually copied from the search_api_solr # Drupal module to .docker/config/solr/config-set. diff --git a/docker-compose.yml b/docker-compose.yml index 90fba02580..8e060257af 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -191,7 +191,7 @@ services: context: . dockerfile: .docker/database.dockerfile args: - IMAGE: "${VORTEX_DB_IMAGE:-uselagoon/mysql-8.4:26.8.1}" # Use custom database image (if defined) or fallback to standard database image. + IMAGE: "${VORTEX_DB_IMAGE:-uselagoon/mysql-8.4:26.9.0}" # Use custom database image (if defined) or fallback to standard database image. environment: <<: *default-environment <<: *default-user @@ -204,7 +204,7 @@ services: #;< MIGRATION database2: - image: "${VORTEX_DB2_IMAGE:-uselagoon/mysql-8.4:26.8.1}" # Use custom database image (if defined) or fallback to standard database image. + image: "${VORTEX_DB2_IMAGE:-uselagoon/mysql-8.4:26.9.0}" # Use custom database image (if defined) or fallback to standard database image. environment: <<: *default-environment MYSQL_DATABASE: drupal @@ -219,7 +219,7 @@ services: #;< SERVICE_CACHE cache: - image: uselagoon/valkey-8:26.8.1 + image: uselagoon/valkey-8:26.9.0 #;< HOSTING_LAGOON labels: lagoon.type: redis # Change to 'none' if dedicated Redis service is used. See https://docs.lagoon.sh/using-lagoon-advanced/service-types/ From 1ce4ac395e15ff580ae947cca686a954aa205df6 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:44:04 +1100 Subject: [PATCH 28/71] Update renovatebot/github-action action to v46.3.6. Forward-ported from main 7a07413fbaa55fabfb34d22aee3c67766651e479. --- .github/workflows/update-dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index 4343e26b87..5cf4a0d3dd 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -67,7 +67,7 @@ jobs: - name: Run Renovate if: steps.check-requirements.outputs.should_run == 'true' - uses: renovatebot/github-action@f3a31a786096ba6b40d0f0ffe11a494ef73bfa7c # v46.3.4 + uses: renovatebot/github-action@6d26fcf0275dc65624cbc3d51fe78bc773f98321 # v46.3.6 with: configurationFile: renovate.json token: ${{ secrets.RENOVATE_TOKEN }} From 56b4dc28bef2ec3efc187aca9acaf0a9f1aaa9f6 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:44:06 +1100 Subject: [PATCH 29/71] Update dawidd6/action-download-artifact action to v27. Forward-ported from main 837439bafc9039ef773dc7a03b4c84e8b945f316. --- .github/workflows/vortex-test-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/vortex-test-docs.yml b/.github/workflows/vortex-test-docs.yml index 482cfee999..0c8f3ae0ea 100644 --- a/.github/workflows/vortex-test-docs.yml +++ b/.github/workflows/vortex-test-docs.yml @@ -68,7 +68,7 @@ jobs: # searching by name returns the most recent successful run across all # branches, which would pull a binary built from a different commit. - name: Download the binary artifact - uses: dawidd6/action-download-artifact@634d83b91986fcec9be314054943fa5c976aeb0e # v25 + uses: dawidd6/action-download-artifact@eab87c9830c39eff17e5a6eadb20bfb4bc880477 # v27 with: run_id: ${{ github.event.workflow_run.id }} name: ${{ env.BINARY_ARTIFACT }} From c8ae4276177043f732732d18b8d0acff2ee80b87 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:44:22 +1100 Subject: [PATCH 30/71] Updated 'drevops/docker-wait-for-dependencies' to '26.10.0'. Forward-ported from main 7369cb2511fd7718ebba4d666fc1c14df938ea70. --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 8e060257af..77ef5e3697 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -280,7 +280,7 @@ services: # Helper container to wait for services to become available. wait-for-dependencies: - image: drevops/docker-wait-for-dependencies:26.6.1 + image: drevops/docker-wait-for-dependencies:26.10.0 depends_on: #;< SERVICE_ANTIVIRUS - antivirus From 2b4bc6b77b961aefcc4fa7d5ba208bc5b3ebee99 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Oct 2026 16:29:07 +1000 Subject: [PATCH 31/71] Update release-drafter/release-drafter action to v7.9.0 (#3174) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> (cherry picked from commit 43ed9207424f3edffb7864a4624e913a837bf30b) --- .github/workflows/draft-release-notes.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/draft-release-notes.yml b/.github/workflows/draft-release-notes.yml index b4e3e190d5..541dd98931 100644 --- a/.github/workflows/draft-release-notes.yml +++ b/.github/workflows/draft-release-notes.yml @@ -41,7 +41,7 @@ jobs: echo "Version set to ${VERSION}" - name: Draft release notes - uses: release-drafter/release-drafter@34d80673e067bdc0c24568d3af899c216adcfaa9 # v7.7.0 + uses: release-drafter/release-drafter@72967cdc98ddd3160f1fc3dff619de365e137dd0 # v7.9.0 with: tag: ${{ steps.calver.outputs.version }} name: ${{ steps.calver.outputs.version }} From 273ba6caadf454dc6bcbc38109c9d43dd4ddf39c Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:44:32 +1100 Subject: [PATCH 32/71] Updated 'drevops/mariadb-drupal-data' to '26.10.0'. Forward-ported the 'update-test-assets' seed bump from main b2c1f4ccb973fcc819b126718c0be56a1c88be32. The CircleCI hunk targets the nightly database job, which 2.x does not have. --- .vortex/tests/update-test-assets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vortex/tests/update-test-assets b/.vortex/tests/update-test-assets index 4cd1f73d5b..56a4829ef4 100755 --- a/.vortex/tests/update-test-assets +++ b/.vortex/tests/update-test-assets @@ -40,8 +40,8 @@ declare(strict_types=1); */ const SUT_DIR = '/tmp/star-wars'; -const SEED_URL = 'https://github.com/drevops/mariadb-drupal-data/releases/download/26.7.0/seed.sh'; -const SEED_SHA256 = 'd97c184b2b76111b39b3cba96a624c22ed3f3408d781345770ea2b17beaba91e'; +const SEED_URL = 'https://github.com/drevops/mariadb-drupal-data/releases/download/26.10.0/seed.sh'; +const SEED_SHA256 = '1bc8062d54787945b97af61608a13169d87e60d7fbd4e87ec120c3216c8fe7d8'; const IMAGE_DEMO = 'drevops/vortex-dev-mariadb-drupal-data-demo-11.x'; const IMAGE_TEST = 'drevops/vortex-dev-mariadb-drupal-data-test-11.x'; const IMAGE_DEST = 'drevops/vortex-dev-mariadb-drupal-data-demo-destination-11.x'; From 18296e8ed6b1146cbeaa8d810fa0cee51403e22a Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:44:35 +1100 Subject: [PATCH 33/71] Update suzuki-shunsuke/github-action-renovate-config-validator action to v2.3.0. Forward-ported from main fb09240148af36bafe4fe088c8f5545a3fdf1f9a. --- .github/workflows/update-dependencies.yml | 2 +- .github/workflows/vortex-test-common.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index 5cf4a0d3dd..5fa647d500 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -63,7 +63,7 @@ jobs: node-version: 22.17.1 - name: Validate Renovate configuration - uses: suzuki-shunsuke/github-action-renovate-config-validator@b850926b611b1f3d3fe3729776339c217834bf2c # v2.2.0 + uses: suzuki-shunsuke/github-action-renovate-config-validator@394f7a3d2641cad2995938f9dc7e54580c8a7089 # v2.3.0 - name: Run Renovate if: steps.check-requirements.outputs.should_run == 'true' diff --git a/.github/workflows/vortex-test-common.yml b/.github/workflows/vortex-test-common.yml index 9c0ab63054..2d911b2ddf 100644 --- a/.github/workflows/vortex-test-common.yml +++ b/.github/workflows/vortex-test-common.yml @@ -105,7 +105,7 @@ jobs: # as used in the Renovate workflow to ensure that they both use the same # version. - name: Validate Renovate configuration - uses: suzuki-shunsuke/github-action-renovate-config-validator@b850926b611b1f3d3fe3729776339c217834bf2c # v2.2.0 + uses: suzuki-shunsuke/github-action-renovate-config-validator@394f7a3d2641cad2995938f9dc7e54580c8a7089 # v2.3.0 vortex-test-workflow: runs-on: ubuntu-latest From 9d9c5414005eef99cadaa341af77c5f3abc385e3 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 5 Oct 2026 13:43:32 +1100 Subject: [PATCH 34/71] Replaced 'drevops/behat-format-progress-fail' with the Behat core 'inline_failures' option and updated 'behat/behat' to '^3.34.0'. (#3181) (cherry picked from commit 8ffaa357b3bfb4018c8968fbbd13a8106d5c48e8) --- .vortex/cli/src/Prompts/Handlers/Tools.php | 2 -- .vortex/docs/content/development/composer.mdx | 1 - .vortex/docs/content/development/testing/behat.mdx | 5 +---- behat.yml | 8 +++----- composer.json | 3 +-- 5 files changed, 5 insertions(+), 14 deletions(-) diff --git a/.vortex/cli/src/Prompts/Handlers/Tools.php b/.vortex/cli/src/Prompts/Handlers/Tools.php index c6fa7b8335..cb607c165f 100644 --- a/.vortex/cli/src/Prompts/Handlers/Tools.php +++ b/.vortex/cli/src/Prompts/Handlers/Tools.php @@ -505,7 +505,6 @@ public static function getToolDefinitions(string $filter = 'all'): array { 'title' => 'Behat', 'present' => fn(): mixed => File::contains($this->dstDir . '/composer.json', 'behat/behat') || File::contains($this->dstDir . '/composer.json', 'drupal/drupal-extension') || - File::contains($this->dstDir . '/composer.json', 'drevops/behat-format-progress-fail') || File::contains($this->dstDir . '/composer.json', 'drevops/behat-screenshot') || File::contains($this->dstDir . '/composer.json', 'drevops/behat-steps') || File::exists($this->dstDir . '/behat.yml'), @@ -513,7 +512,6 @@ public static function getToolDefinitions(string $filter = 'all'): array { $cj->removeSubNode('require-dev', 'behat/behat'); $cj->removeSubNode('require-dev', 'drupal/drupal-extension'); $cj->removeSubNode('require-dev', 'dantleech/gherkin-lint'); - $cj->removeSubNode('require-dev', 'drevops/behat-format-progress-fail'); $cj->removeSubNode('require-dev', 'drevops/behat-screenshot'); $cj->removeSubNode('require-dev', 'drevops/behat-steps'); }, diff --git a/.vortex/docs/content/development/composer.mdx b/.vortex/docs/content/development/composer.mdx index b26bb52f1c..97d828af08 100644 --- a/.vortex/docs/content/development/composer.mdx +++ b/.vortex/docs/content/development/composer.mdx @@ -585,7 +585,6 @@ environment keeps its full tooling. |---------|-------------|---------------| | [`behat/behat`](https://github.com/Behat/Behat) | A PHP framework for Behavior-Driven Development (BDD), running human-readable stories that describe the behavior of your application. It facilitates communication between developers, stakeholders and clients. | [Behat](testing/behat.mdx) | | [`dantleech/gherkin-lint`](https://github.com/dantleech/gherkin-lint) | Lints the Gherkin feature files used in Behat tests, checking syntax and formatting for consistency. | [Gherkin Lint](code-quality/gherkin-lint.mdx) | -| [`drevops/behat-format-progress-fail`](https://github.com/drevops/behat-format-progress-fail) | A Behat output formatter that prints compact progress and expands the detail only for failing scenarios. | [Behat](testing/behat.mdx) | | [`drevops/behat-screenshot`](https://github.com/drevops/behat-screenshot) | Automatically captures a screenshot when a Behat scenario fails, which helps to understand why a test failed. | [Behat](testing/behat.mdx) | | [`drevops/behat-steps`](https://github.com/drevops/behat-steps) | A collection of pre-defined Behat step definitions for Drupal, speeding up the process of writing new tests. | [Behat](testing/behat.mdx) | | [`drevops/phpcs-standard`](https://github.com/drevops/phpcs-standard) | A PHP_CodeSniffer coding standard that extends the Drupal coding standards with additional rules and best practices. | [PHPCS](code-quality/phpcs.mdx) | diff --git a/.vortex/docs/content/development/testing/behat.mdx b/.vortex/docs/content/development/testing/behat.mdx index 7a9990f30f..0a0702cd41 100644 --- a/.vortex/docs/content/development/testing/behat.mdx +++ b/.vortex/docs/content/development/testing/behat.mdx @@ -177,7 +177,6 @@ The configuration uses the following contexts and extensions: - [Drupal Extension](https://github.com/jhedstrom/drupalextension): an integration layer between Behat, Mink Extension, and Drupal. It provides step definitions for common testing scenarios specific to Drupal sites. - [Behat Steps](https://github.com/drevops/behat-steps): a library of re-usable Behat steps for Drupal. - [Behat Screenshot](https://github.com/drevops/behat-screenshot): extension and step definitions to create HTML and image screenshots on demand or when tests fail. -- [Behat Progress Fail Output Extension](https://github.com/drevops/behat-format-progress-fail): output formatter, see [Output format](#output-format). ### FeatureContext @@ -217,9 +216,7 @@ pipeline handles animation. ### Output format -Out of the box, **Vortex** comes with the [Behat Progress formatter](https://github.com/drevops/behat-format-progress-fail) -output formatter to show progress as TAP and failures inline. This lets a test -run continue after a failure while maintaining a minimal output. +Out of the box, **Vortex** uses Behat's built-in `progress` formatter with the `inline_failures` option turned on in `behat.yml`. It prints a dot for each passed step and the details of each failed, pending, or undefined step as soon as it happens. The test run continues after a failure while the output stays minimal. ## Observing the browser diff --git a/behat.yml b/behat.yml index a1e99c1d52..3126490c61 100644 --- a/behat.yml +++ b/behat.yml @@ -18,8 +18,9 @@ default: - DrevOps\BehatScreenshotExtension\Context\ScreenshotContext formatters: - # Show test progress and explicit fail information whule continuing the test run. - progress_fail: true + # Show test progress and explicit fail information while continuing the test run. + progress: + inline_failures: true # Output test results in JUnit format. junit: @@ -93,9 +94,6 @@ default: - step - datetime - # Show explicit fail information and continue the test run. - DrevOps\BehatFormatProgressFail\FormatExtension: ~ - # Profiles for parallel testing. CI derives the profile number from the index # of the runner it is on minus 'VORTEX_CI_BEHAT_PROFILE_OFFSET', so profiles # stay numbered from 'p0' regardless of which runner Behat starts on. Adding a diff --git a/composer.json b/composer.json index 02b5ddec2c..b69bb6fc53 100644 --- a/composer.json +++ b/composer.json @@ -39,9 +39,8 @@ "drush/drush": "^13.8.0" }, "require-dev": { - "behat/behat": "^3.33.0", + "behat/behat": "^3.34.0", "dantleech/gherkin-lint": "^0.2.4", - "drevops/behat-format-progress-fail": "^1.5.1", "drevops/behat-screenshot": "^2.6.0", "drevops/behat-steps": "^3.14.2", "drevops/phpcs-standard": "^1.0.0", From 9feeb9ede9c5e3aee835fdb40cf074fcd48273e9 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:45:15 +1100 Subject: [PATCH 35/71] Update PHP - All packages except core - Minor and patch. Forward-ported from main 2880cff55731710d99d655cf16da71ea8bb0ce7b. --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index b69bb6fc53..b4105b89b7 100644 --- a/composer.json +++ b/composer.json @@ -42,18 +42,18 @@ "behat/behat": "^3.34.0", "dantleech/gherkin-lint": "^0.2.4", "drevops/behat-screenshot": "^2.6.0", - "drevops/behat-steps": "^3.14.2", + "drevops/behat-steps": "^3.14.4", "drevops/phpcs-standard": "^1.0.0", "drupal/coder": "^9.0.1", "drupal/drupal-extension": "^6.1", - "ergebnis/composer-normalize": "^2.53.0", - "mglaman/phpstan-drupal": "^2.2.0", + "ergebnis/composer-normalize": "^2.54.0", + "mglaman/phpstan-drupal": "^2.2.2", "mikey179/vfsstream": "^1.6.12", "palantirnet/drupal-rector": "^1.1.3", "phpcompatibility/php-compatibility": "^10.0@alpha", "phpspec/prophecy-phpunit": "^2.5", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.2.14", + "phpstan/phpstan": "^2.2.17", "phpunit/phpunit": "^11.5.56", "pyrech/composer-changelogs": "^2.2", "softcreatr/jsonpath": "^0.10 || ^1.0", From 8c26f104b081914444980c64ca27fb6d7b691a5d Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:45:18 +1100 Subject: [PATCH 36/71] Update GitHub Actions - All - Major, minor and patch. Forward-ported from main 747103025da77ac460beaf6d0acc17811699b9a7. --- .github/workflows/update-dependencies.yml | 4 ++-- .github/workflows/vortex-test-common.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index 5fa647d500..a93f6afc3a 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -63,11 +63,11 @@ jobs: node-version: 22.17.1 - name: Validate Renovate configuration - uses: suzuki-shunsuke/github-action-renovate-config-validator@394f7a3d2641cad2995938f9dc7e54580c8a7089 # v2.3.0 + uses: suzuki-shunsuke/github-action-renovate-config-validator@1e1604219a6b38ae9a10aff42a28a3656322c31a # v2.4.1 - name: Run Renovate if: steps.check-requirements.outputs.should_run == 'true' - uses: renovatebot/github-action@6d26fcf0275dc65624cbc3d51fe78bc773f98321 # v46.3.6 + uses: renovatebot/github-action@230ce922b08968d0a4f6f70f295601daff09ef1d # v46.3.7 with: configurationFile: renovate.json token: ${{ secrets.RENOVATE_TOKEN }} diff --git a/.github/workflows/vortex-test-common.yml b/.github/workflows/vortex-test-common.yml index 2d911b2ddf..584f063295 100644 --- a/.github/workflows/vortex-test-common.yml +++ b/.github/workflows/vortex-test-common.yml @@ -105,7 +105,7 @@ jobs: # as used in the Renovate workflow to ensure that they both use the same # version. - name: Validate Renovate configuration - uses: suzuki-shunsuke/github-action-renovate-config-validator@394f7a3d2641cad2995938f9dc7e54580c8a7089 # v2.3.0 + uses: suzuki-shunsuke/github-action-renovate-config-validator@1e1604219a6b38ae9a10aff42a28a3656322c31a # v2.4.1 vortex-test-workflow: runs-on: ubuntu-latest From 8c6273a9bf89750126fc09d7b6f4ee778dffe1df Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:45:45 +1100 Subject: [PATCH 37/71] [#3184] Fixed the DIDI-II database job to use the 'container_registry' fetch source. Forward-ported from main cffa3e4d19e3148be637e5e1e87d937baa6af8d5, applied to the 2.x 'build_database_builder_job()' generator. --- .circleci/vortex-test-common.yml | 3 ++- .vortex/tests/generate-vortex-dev-circleci | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.circleci/vortex-test-common.yml b/.circleci/vortex-test-common.yml index 8bc3c6f2ae..f9fa1cc46b 100644 --- a/.circleci/vortex-test-common.yml +++ b/.circleci/vortex-test-common.yml @@ -481,9 +481,10 @@ jobs: vortex-dev-database-ii: <<: *runner_config environment: - VORTEX_FETCH_DB_SOURCE: VORTEX_CONTAINER_REGISTRY + VORTEX_FETCH_DB_SOURCE: container_registry VORTEX_FETCH_DB_FORCE: 1 VORTEX_DB_IMAGE: drevops/vortex-dev-mariadb-drupal-data-demo-destination-11.x + COMPOSE_PROGRESS: plain VORTEX_PUSH_CONTAINER_REGISTRY_IMAGE_TAG: vortex-dev-database-ii VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED: 1 VORTEX_CI_DB_CACHE_BRANCH: vortex-dev-didi-ii diff --git a/.vortex/tests/generate-vortex-dev-circleci b/.vortex/tests/generate-vortex-dev-circleci index 3265bb5f31..d0152451d0 100755 --- a/.vortex/tests/generate-vortex-dev-circleci +++ b/.vortex/tests/generate-vortex-dev-circleci @@ -69,9 +69,10 @@ $output = implode("\n", [ '', ' # DIDI-II variant jobs', build_database_builder_job('vortex-dev-database-ii', [ - 'VORTEX_FETCH_DB_SOURCE' => 'VORTEX_CONTAINER_REGISTRY', + 'VORTEX_FETCH_DB_SOURCE' => 'container_registry', 'VORTEX_FETCH_DB_FORCE' => 1, 'VORTEX_DB_IMAGE' => 'drevops/vortex-dev-mariadb-drupal-data-demo-destination-11.x', + 'COMPOSE_PROGRESS' => 'plain', 'VORTEX_PUSH_CONTAINER_REGISTRY_IMAGE_TAG' => 'vortex-dev-database-ii', 'VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED' => 1, 'VORTEX_CI_DB_CACHE_BRANCH' => 'vortex-dev-didi-ii', From 258eeb86299c79ec25ff204c7d38f95ccb75c534 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:45:59 +1100 Subject: [PATCH 38/71] Update GitHub Actions - All - Major, minor and patch. Forward-ported from main 3b9ec251064929bd113c480e20ed1199e6bebccb, applied to every 2.x workflow that pins these actions. --- .github/workflows/build-test-deploy.yml | 6 +++--- .github/workflows/draft-release-notes.yml | 2 +- .github/workflows/vortex-release.yml | 8 ++++---- .github/workflows/vortex-test-cli.yml | 4 ++-- .github/workflows/vortex-test-common.yml | 4 ++-- .github/workflows/vortex-test-docs.yml | 2 +- .github/workflows/vortex-test-tooling.yml | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-test-deploy.yml b/.github/workflows/build-test-deploy.yml index 8077763063..306a79cc94 100644 --- a/.github/workflows/build-test-deploy.yml +++ b/.github/workflows/build-test-deploy.yml @@ -552,7 +552,7 @@ jobs: fi - name: Upload test artifacts - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 if: always() with: name: test-artifacts-${{ matrix.instance }} @@ -651,7 +651,7 @@ jobs: du -sh "/tmp/artifacts" - name: Upload exported codebase as an artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 if: ${{ contains(env.VORTEX_DEPLOY_TYPES, 'artifact') }} with: name: code-artifact @@ -720,7 +720,7 @@ jobs: #;< DEPLOY_TYPES_ARTIFACT # Artifact deployments do not work for manual deploys as the build job is skipped. - name: Download exported codebase as an artifact - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8 if: ${{ !inputs.deploy_target && contains(env.VORTEX_DEPLOY_TYPES, 'artifact') }} with: name: code-artifact diff --git a/.github/workflows/draft-release-notes.yml b/.github/workflows/draft-release-notes.yml index 541dd98931..d965d22c2d 100644 --- a/.github/workflows/draft-release-notes.yml +++ b/.github/workflows/draft-release-notes.yml @@ -41,7 +41,7 @@ jobs: echo "Version set to ${VERSION}" - name: Draft release notes - uses: release-drafter/release-drafter@72967cdc98ddd3160f1fc3dff619de365e137dd0 # v7.9.0 + uses: release-drafter/release-drafter@978bb0b30c5ee8cdd332ced253758157150d43f0 # v7.10.0 with: tag: ${{ steps.calver.outputs.version }} name: ${{ steps.calver.outputs.version }} diff --git a/.github/workflows/vortex-release.yml b/.github/workflows/vortex-release.yml index 0e49dd6fc5..20e0536d56 100644 --- a/.github/workflows/vortex-release.yml +++ b/.github/workflows/vortex-release.yml @@ -94,7 +94,7 @@ jobs: working-directory: .vortex/cli - name: Upload v${{ env.CURRENT_MAJOR }} artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: vortex-installer-v${{ env.CURRENT_MAJOR }} path: .vortex/cli/.build/vortex.phar @@ -121,7 +121,7 @@ jobs: working-directory: vortex-v${{ env.OTHER_MAJOR }}/.vortex/installer - name: Upload v${{ env.OTHER_MAJOR }} installer artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: vortex-installer-v${{ env.OTHER_MAJOR }} path: vortex-v${{ env.OTHER_MAJOR }}/.vortex/installer/build/installer.phar @@ -173,13 +173,13 @@ jobs: php-version: 8.3 - name: Download v1 installer - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8 with: name: vortex-installer-v1 path: installer-v1 - name: Download v2 installer - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8 with: name: vortex-installer-v2 path: installer-v2 diff --git a/.github/workflows/vortex-test-cli.yml b/.github/workflows/vortex-test-cli.yml index a27414e99d..8c4bbb4681 100644 --- a/.github/workflows/vortex-test-cli.yml +++ b/.github/workflows/vortex-test-cli.yml @@ -91,7 +91,7 @@ jobs: working-directory: .vortex/docs - name: Upload coverage reports as an artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: ${{github.job}}-code-coverage-report-${{ matrix.php-versions }} path: .vortex/cli/.logs @@ -121,7 +121,7 @@ jobs: - name: Upload CLI artifact if: matrix.php-versions == '8.3' - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: vortex-cli path: .vortex/cli/.build/vortex.phar diff --git a/.github/workflows/vortex-test-common.yml b/.github/workflows/vortex-test-common.yml index 584f063295..480dd5d002 100644 --- a/.github/workflows/vortex-test-common.yml +++ b/.github/workflows/vortex-test-common.yml @@ -195,7 +195,7 @@ jobs: TEST_VORTEX_DEBUG: ${{ vars.TEST_VORTEX_DEBUG }} - name: Upload test artifacts - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 if: always() with: name: ${{github.job}}-${{ matrix.batch }}-test-artifacts @@ -204,7 +204,7 @@ jobs: if-no-files-found: ignore - name: Upload coverage report as an artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: ${{github.job}}-${{ matrix.batch }}-code-coverage-report path: /tmp/.vortex-coverage-html diff --git a/.github/workflows/vortex-test-docs.yml b/.github/workflows/vortex-test-docs.yml index 0c8f3ae0ea..8a5aa6b9ea 100644 --- a/.github/workflows/vortex-test-docs.yml +++ b/.github/workflows/vortex-test-docs.yml @@ -183,7 +183,7 @@ jobs: This preview is rebuilt on every commit and is not the production documentation site. - name: Upload coverage reports as an artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: ${{github.job}}-docs-coverage-report path: .vortex/docs/.logs diff --git a/.github/workflows/vortex-test-tooling.yml b/.github/workflows/vortex-test-tooling.yml index 2ea68154a3..e5cc448a0d 100644 --- a/.github/workflows/vortex-test-tooling.yml +++ b/.github/workflows/vortex-test-tooling.yml @@ -87,7 +87,7 @@ jobs: working-directory: .vortex/tooling - name: Upload coverage reports as an artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: ${{ github.job }}-code-coverage-report-${{ matrix.php-versions }} path: .vortex/tooling/.logs From 33e73bd8828c700e9a7fc54eb4e9814d5944a94b Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:46:08 +1100 Subject: [PATCH 39/71] Update GitHub Actions - All - Major, minor and patch. Forward-ported from main 4479daa36642e27c2545be583ab122db8dda98b0, applied to every 2.x workflow that pins these actions. The 'upload-sarif' pins are not carried over because 2.x has no SARIF upload steps. --- .github/workflows/audit.yml | 2 +- .github/workflows/build-test-deploy.yml | 8 ++++---- .github/workflows/update-dependencies.yml | 2 +- .github/workflows/vortex-release.yml | 6 +++--- .github/workflows/vortex-test-cli.yml | 4 ++-- .github/workflows/vortex-test-common.yml | 10 +++++----- .github/workflows/vortex-test-docs.yml | 4 ++-- .github/workflows/vortex-test-tooling.yml | 2 +- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 4295e88a9d..a37117ebaa 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -70,7 +70,7 @@ jobs: persist-credentials: false - name: Set up PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: '8.4' tools: composer diff --git a/.github/workflows/build-test-deploy.yml b/.github/workflows/build-test-deploy.yml index 306a79cc94..d2621e4ede 100644 --- a/.github/workflows/build-test-deploy.yml +++ b/.github/workflows/build-test-deploy.yml @@ -92,7 +92,7 @@ jobs: persist-credentials: false - name: Set up PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: '8.4' tools: composer @@ -272,7 +272,7 @@ jobs: persist-credentials: false - name: Set up PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: '8.4' tools: composer @@ -617,7 +617,7 @@ jobs: persist-credentials: false - name: Set up PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: '8.4' tools: composer @@ -705,7 +705,7 @@ jobs: ref: ${{ env.DEPLOY_BRANCH || github.head_ref || github.ref_name }} - name: Set up PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: '8.4' tools: composer diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index a93f6afc3a..8db1580b84 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -58,7 +58,7 @@ jobs: with: persist-credentials: false - - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 with: node-version: 22.17.1 diff --git a/.github/workflows/vortex-release.yml b/.github/workflows/vortex-release.yml index 20e0536d56..3f35697117 100644 --- a/.github/workflows/vortex-release.yml +++ b/.github/workflows/vortex-release.yml @@ -51,7 +51,7 @@ jobs: key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }} - name: Setup PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: 8.3 @@ -163,12 +163,12 @@ jobs: NEEDS_VORTEX_RELEASE_CLI_OUTPUTS_RELEASE_VERSION: ${{ needs.vortex-release-cli.outputs.release-version }} - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 + uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7 with: node-version: 22.17.1 - name: Setup PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: 8.3 diff --git a/.github/workflows/vortex-test-cli.yml b/.github/workflows/vortex-test-cli.yml index 8c4bbb4681..6893b9fd12 100644 --- a/.github/workflows/vortex-test-cli.yml +++ b/.github/workflows/vortex-test-cli.yml @@ -43,14 +43,14 @@ jobs: persist-credentials: false - name: Setup PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: ${{ matrix.php-versions }} coverage: pcov ini-values: pcov.directory=. - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 + uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7 with: node-version: 22.17.1 diff --git a/.github/workflows/vortex-test-common.yml b/.github/workflows/vortex-test-common.yml index 480dd5d002..d171f5c337 100644 --- a/.github/workflows/vortex-test-common.yml +++ b/.github/workflows/vortex-test-common.yml @@ -45,7 +45,7 @@ jobs: persist-credentials: false - name: Set up PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: '8.4' tools: composer @@ -76,7 +76,7 @@ jobs: echo "SSH_AUTH_SOCK=${SSH_AUTH_SOCK}" >> "$GITHUB_ENV" - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 + uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7 with: node-version: 22.17.1 @@ -136,7 +136,7 @@ jobs: persist-credentials: false - name: Set up PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: '8.4' tools: composer @@ -155,7 +155,7 @@ jobs: echo "SSH_AUTH_SOCK=${SSH_AUTH_SOCK}" >> "$GITHUB_ENV" - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 + uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7 with: node-version: 22.17.1 @@ -235,7 +235,7 @@ jobs: persist-credentials: false - name: Set up PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: '8.4' tools: composer diff --git a/.github/workflows/vortex-test-docs.yml b/.github/workflows/vortex-test-docs.yml index 8a5aa6b9ea..092667f2eb 100644 --- a/.github/workflows/vortex-test-docs.yml +++ b/.github/workflows/vortex-test-docs.yml @@ -55,12 +55,12 @@ jobs: persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 + uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7 with: node-version: 22.17.1 - name: Setup PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: 8.3 diff --git a/.github/workflows/vortex-test-tooling.yml b/.github/workflows/vortex-test-tooling.yml index e5cc448a0d..b49aa902c3 100644 --- a/.github/workflows/vortex-test-tooling.yml +++ b/.github/workflows/vortex-test-tooling.yml @@ -37,7 +37,7 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Setup PHP - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # v2 with: php-version: ${{ matrix.php-versions }} coverage: pcov From 4d047447e11efe9dae1b4328a4f555e8e42372cd Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:46:10 +1100 Subject: [PATCH 40/71] Update PHP - Drupal core - Minor and patch to ~11.4.9. Forward-ported from main d5c6d1ef3ab03e0f236b1ad3d2dfe619aaa56745. --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index b4105b89b7..f0cb323235 100644 --- a/composer.json +++ b/composer.json @@ -13,8 +13,8 @@ "drupal/coffee": "^2.0.1", "drupal/config_split": "^2.0.2", "drupal/config_update": "^2@alpha", - "drupal/core-composer-scaffold": "~11.4.8", - "drupal/core-recommended": "~11.4.8", + "drupal/core-composer-scaffold": "~11.4.9", + "drupal/core-recommended": "~11.4.9", "drupal/deploy_steps": "^1.0.0-alpha1", "drupal/devel": "^5.5", "drupal/drupal_helpers": "^2.1.0", From a9ae095c843a44437e625ccaa6455bbfc280ab81 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:46:15 +1100 Subject: [PATCH 41/71] Update PHP - All packages except core - Minor and patch. Forward-ported from main c567ce56d2a57b0b09e5cf589452a019d87215a6. --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index f0cb323235..6f52fd8d39 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "drupal/reroute_email": "^2.3@RC", "drupal/robotstxt": "^1.6", "drupal/sdc_devel": "^1.0.3", - "drupal/search_api": "^1.41.0", + "drupal/search_api": "^1.42.0", "drupal/search_api_solr": "^4.4.0", "drupal/seckit": "^2.0.3", "drupal/shield": "^1.8", @@ -53,8 +53,8 @@ "phpcompatibility/php-compatibility": "^10.0@alpha", "phpspec/prophecy-phpunit": "^2.5", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.2.17", - "phpunit/phpunit": "^11.5.56", + "phpstan/phpstan": "^2.3.1", + "phpunit/phpunit": "^11.5.57", "pyrech/composer-changelogs": "^2.2", "softcreatr/jsonpath": "^0.10 || ^1.0", "vincentlanglet/twig-cs-fixer": "^4.1.1" From fe2d2cf6a39374a58cd433ba6233db213aed990c Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:46:17 +1100 Subject: [PATCH 42/71] Update renovatebot/github-action action to v46.3.8. Forward-ported from main 92e979da9d3ccab6c30906f4be8144527579bb67. --- .github/workflows/update-dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index 8db1580b84..e4eaa2e8b8 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -67,7 +67,7 @@ jobs: - name: Run Renovate if: steps.check-requirements.outputs.should_run == 'true' - uses: renovatebot/github-action@230ce922b08968d0a4f6f70f295601daff09ef1d # v46.3.7 + uses: renovatebot/github-action@f0f41e5f2e706165f6814b1d0f0d0e319de7d1d9 # v46.3.8 with: configurationFile: renovate.json token: ${{ secrets.RENOVATE_TOKEN }} From cc5d603e23b05cf2e02028bea8998a8e50f0bcde Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:46:24 +1100 Subject: [PATCH 43/71] Update dependency renovate/renovate to v44.132.5. Forward-ported from main 7b30c2a211e7eee308387359ca7913f92efa1f71. 2.x was still on 40.36.8 because the earlier image bumps on main were never ported. --- .circleci/update-dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/update-dependencies.yml b/.circleci/update-dependencies.yml index 8bea21f03f..060a152802 100644 --- a/.circleci/update-dependencies.yml +++ b/.circleci/update-dependencies.yml @@ -33,7 +33,7 @@ jobs: # Variables provided below can be overridden in the CircleCI project settings. update-dependencies: docker: - - image: renovate/renovate:40.36.8 + - image: renovate/renovate:44.132.5 environment: RENOVATE_PLATFORM: 'github' RENOVATE_AUTODISCOVER: false From 96713004c109053273b0aadd7a43aefdfafe7f5f Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:46:26 +1100 Subject: [PATCH 44/71] Update PHP - Drupal core - Minor and patch to ~11.4.10. Forward-ported from main 2d52533680a2221fb5ea2fc9cf4165df0e11699b. --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 6f52fd8d39..36782291d4 100644 --- a/composer.json +++ b/composer.json @@ -13,8 +13,8 @@ "drupal/coffee": "^2.0.1", "drupal/config_split": "^2.0.2", "drupal/config_update": "^2@alpha", - "drupal/core-composer-scaffold": "~11.4.9", - "drupal/core-recommended": "~11.4.9", + "drupal/core-composer-scaffold": "~11.4.10", + "drupal/core-recommended": "~11.4.10", "drupal/deploy_steps": "^1.0.0-alpha1", "drupal/devel": "^5.5", "drupal/drupal_helpers": "^2.1.0", From f95ba3a8e12f77bc20578e6393b36af0789d0719 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Wed, 21 Oct 2026 16:16:03 +1100 Subject: [PATCH 45/71] [#3220] Installed PCOV with PIE instead of PECL in the CLI image. (#3221) (cherry picked from commit cb3ff4c0ea22c592d25b83146626a31ba4c9e096) --- .docker/cli.dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.docker/cli.dockerfile b/.docker/cli.dockerfile index 1ba3777dd8..7e7a931987 100644 --- a/.docker/cli.dockerfile +++ b/.docker/cli.dockerfile @@ -62,8 +62,7 @@ ENV PHP_INI_SCAN_DIR="${PHP_INI_SCAN_DIR}:/app/drush/php-ini" # Add more tools. # hadolint ignore=DL3018 # the package set tracks the pinned base image RUN apk add --no-cache ncurses pv tzdata autoconf g++ make && \ - pecl install pcov && \ - docker-php-ext-enable pcov && \ + pie install --no-build-tools-check pecl/pcov && \ docker-php-ext-install pcntl && \ apk del g++ make autoconf From 5e4e84203a59948ce772adc18c5c83ae22942503 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Thu, 22 Oct 2026 22:03:25 +1100 Subject: [PATCH 46/71] [#3230] Cleared inherited 'CLAMAV_' variables in the settings tests. (#3231) (cherry picked from commit 922e0411884a6bcc35de349f0c1eb9b7a249e272) --- tests/phpunit/Drupal/SettingsTestCase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/phpunit/Drupal/SettingsTestCase.php b/tests/phpunit/Drupal/SettingsTestCase.php index 74ff0512e1..fe1ece5364 100644 --- a/tests/phpunit/Drupal/SettingsTestCase.php +++ b/tests/phpunit/Drupal/SettingsTestCase.php @@ -72,6 +72,7 @@ abstract class SettingsTestCase extends TestCase { 'DATABASE2_', // phpcs:ignore #;> MIGRATION 'REDIS_', + 'CLAMAV_', 'COMPOSE_', 'GITHUB_', 'PACKAGE_', From 210cc7766c7f2989776c73fe36cea4ac083512a1 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:47:18 +1100 Subject: [PATCH 47/71] Updated contrib modules, the platform PHP version and the demo command runner from the 1.42.0 release. Forward-ported the template-level parts of main bfe58858544baee59bb358fcf4ddf1a6b55e7b50: 'drupal_helpers', 'generated_content' and 'testmode' bumps, the platform PHP version matching the 26.9.0 images, and the 'proc_open()' runner in 'type-and-run.php'. The 'drevops/vortex-tooling' '~1.5.0' pin, release notes, recordings and audit allowlist expiries are main-only. --- .vortex/docs/.utils/type-and-run.php | 11 +++++++++-- composer.json | 8 ++++---- phpstan.neon | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.vortex/docs/.utils/type-and-run.php b/.vortex/docs/.utils/type-and-run.php index 2a0800d8dc..f507922145 100755 --- a/.vortex/docs/.utils/type-and-run.php +++ b/.vortex/docs/.utils/type-and-run.php @@ -34,5 +34,12 @@ echo "\n"; flush(); -passthru($cmd, $exit_code); -exit($exit_code); +// The command writes to the terminal itself rather than a pipe, so Docker +// Compose can open a console for its build progress. +$process = proc_open($cmd, [STDIN, STDOUT, STDERR], $pipes); +if (!is_resource($process)) { + fwrite(STDERR, sprintf("Failed to run: %s\n", $cmd)); + exit(1); +} + +exit(proc_close($process)); diff --git a/composer.json b/composer.json index 36782291d4..f7e6e6ed09 100644 --- a/composer.json +++ b/composer.json @@ -17,9 +17,9 @@ "drupal/core-recommended": "~11.4.10", "drupal/deploy_steps": "^1.0.0-alpha1", "drupal/devel": "^5.5", - "drupal/drupal_helpers": "^2.1.0", + "drupal/drupal_helpers": "^2.2.0", "drupal/environment_indicator": "^4.0.25", - "drupal/generated_content": "^2.1.0", + "drupal/generated_content": "^2.2.0", "drupal/migrate_plus": "^6.0.10", "drupal/migrate_tools": "^6.1.4", "drupal/navigation_extra_tools": "^1.3.2", @@ -34,7 +34,7 @@ "drupal/seckit": "^2.0.3", "drupal/shield": "^1.8", "drupal/stage_file_proxy": "^4.0.0", - "drupal/testmode": "^2.7.1", + "drupal/testmode": "^2.8.0", "drupal/xmlsitemap": "^2.0", "drush/drush": "^13.8.0" }, @@ -100,7 +100,7 @@ "bump-after-update": true, "discard-changes": true, "platform": { - "php": "8.4.21" + "php": "8.4.25" }, "policy": { "advisories": { diff --git a/phpstan.neon b/phpstan.neon index be76d74cd3..eba3023220 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -11,7 +11,7 @@ parameters: level: 7 - phpVersion: 80421 + phpVersion: 80425 paths: - web/modules/custom From a5d710a2c7e34b22bf1912d6ff52b81c1470d0a1 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:47:32 +1100 Subject: [PATCH 48/71] Updated container images to '26.10.0', Drupal core to '~11.4.11' and the platform PHP version. Forward-ported the template-level, non-JavaScript part of main 209e0e755dacf170e9567d431ce14c6f2ee04717: uselagoon images, Selenium Chromium 155.0 on the 'browser' service, the CircleCI Renovate image, Drupal core, 'drupal/shield' and the platform PHP version. The JavaScript major updates, lock files and '.vortex/' dependency refreshes are left for a dedicated dependency refresh on 2.x. --- .circleci/update-dependencies.yml | 2 +- .docker/clamav.dockerfile | 2 +- .docker/cli.dockerfile | 2 +- .docker/database.dockerfile | 2 +- .docker/nginx-drupal.dockerfile | 2 +- .docker/php.dockerfile | 2 +- .docker/solr.dockerfile | 2 +- composer.json | 8 ++++---- docker-compose.yml | 8 ++++---- phpstan.neon | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.circleci/update-dependencies.yml b/.circleci/update-dependencies.yml index 060a152802..b0ab023792 100644 --- a/.circleci/update-dependencies.yml +++ b/.circleci/update-dependencies.yml @@ -33,7 +33,7 @@ jobs: # Variables provided below can be overridden in the CircleCI project settings. update-dependencies: docker: - - image: renovate/renovate:44.132.5 + - image: renovate/renovate:44.176.2 environment: RENOVATE_PLATFORM: 'github' RENOVATE_AUTODISCOVER: false diff --git a/.docker/clamav.dockerfile b/.docker/clamav.dockerfile index 4601e973e1..ebf4c99fb0 100644 --- a/.docker/clamav.dockerfile +++ b/.docker/clamav.dockerfile @@ -8,7 +8,7 @@ # @see https://hub.docker.com/r/uselagoon/commons/tags # @see https://github.com/uselagoon/lagoon-images/tree/main/images/commons -FROM uselagoon/commons:26.9.0 AS commons +FROM uselagoon/commons:26.10.0 AS commons FROM clamav/clamav-debian:1.5.4 diff --git a/.docker/cli.dockerfile b/.docker/cli.dockerfile index 7e7a931987..3bc2c75ffc 100644 --- a/.docker/cli.dockerfile +++ b/.docker/cli.dockerfile @@ -8,7 +8,7 @@ # @see https://hub.docker.com/r/uselagoon/php-8.4-cli-drupal/tags # @see https://github.com/uselagoon/lagoon-images/tree/main/images/php-cli-drupal -FROM uselagoon/php-8.4-cli-drupal:26.9.0 +FROM uselagoon/php-8.4-cli-drupal:26.10.0 # Add missing variables. # @todo Remove once https://github.com/uselagoon/lagoon/issues/3121 is resolved. diff --git a/.docker/database.dockerfile b/.docker/database.dockerfile index 918bb74468..ca2633c686 100644 --- a/.docker/database.dockerfile +++ b/.docker/database.dockerfile @@ -8,7 +8,7 @@ # # The ARG value will be updated with a value passed from docker-compose.yml -ARG IMAGE=uselagoon/mysql-8.4:26.9.0 +ARG IMAGE=uselagoon/mysql-8.4:26.10.0 FROM ${IMAGE} # hadolint ignore=DL3066 # named account provided by the base image diff --git a/.docker/nginx-drupal.dockerfile b/.docker/nginx-drupal.dockerfile index 99a57768f3..1d49af876c 100644 --- a/.docker/nginx-drupal.dockerfile +++ b/.docker/nginx-drupal.dockerfile @@ -8,7 +8,7 @@ ARG CLI_IMAGE FROM ${CLI_IMAGE:-cli} AS cli -FROM uselagoon/nginx-drupal:26.9.0 +FROM uselagoon/nginx-drupal:26.10.0 # Webroot is used for Nginx web root configuration. ARG WEBROOT=web diff --git a/.docker/php.dockerfile b/.docker/php.dockerfile index 0c14aa995a..590a502ab3 100644 --- a/.docker/php.dockerfile +++ b/.docker/php.dockerfile @@ -9,7 +9,7 @@ ARG CLI_IMAGE FROM ${CLI_IMAGE:-cli} AS cli -FROM uselagoon/php-8.4-fpm:26.9.0 +FROM uselagoon/php-8.4-fpm:26.10.0 # hadolint ignore=DL3018 # the package set tracks the pinned base image RUN apk add --no-cache tzdata diff --git a/.docker/solr.dockerfile b/.docker/solr.dockerfile index ea40711f92..6bc701b625 100644 --- a/.docker/solr.dockerfile +++ b/.docker/solr.dockerfile @@ -3,7 +3,7 @@ # @see https://hub.docker.com/r/uselagoon/solr-9-drupal/tags # @see https://github.com/uselagoon/lagoon-images/blob/main/images/solr-drupal/9.Dockerfile -FROM uselagoon/solr-9-drupal:26.9.0 +FROM uselagoon/solr-9-drupal:26.10.0 # Solr jump-start config needs to be manually copied from the search_api_solr # Drupal module to .docker/config/solr/config-set. diff --git a/composer.json b/composer.json index f7e6e6ed09..e77c09fe41 100644 --- a/composer.json +++ b/composer.json @@ -13,8 +13,8 @@ "drupal/coffee": "^2.0.1", "drupal/config_split": "^2.0.2", "drupal/config_update": "^2@alpha", - "drupal/core-composer-scaffold": "~11.4.10", - "drupal/core-recommended": "~11.4.10", + "drupal/core-composer-scaffold": "~11.4.11", + "drupal/core-recommended": "~11.4.11", "drupal/deploy_steps": "^1.0.0-alpha1", "drupal/devel": "^5.5", "drupal/drupal_helpers": "^2.2.0", @@ -32,7 +32,7 @@ "drupal/search_api": "^1.42.0", "drupal/search_api_solr": "^4.4.0", "drupal/seckit": "^2.0.3", - "drupal/shield": "^1.8", + "drupal/shield": "^1.10", "drupal/stage_file_proxy": "^4.0.0", "drupal/testmode": "^2.8.0", "drupal/xmlsitemap": "^2.0", @@ -100,7 +100,7 @@ "bump-after-update": true, "discard-changes": true, "platform": { - "php": "8.4.25" + "php": "8.4.27" }, "policy": { "advisories": { diff --git a/docker-compose.yml b/docker-compose.yml index 77ef5e3697..1ad79961ea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -191,7 +191,7 @@ services: context: . dockerfile: .docker/database.dockerfile args: - IMAGE: "${VORTEX_DB_IMAGE:-uselagoon/mysql-8.4:26.9.0}" # Use custom database image (if defined) or fallback to standard database image. + IMAGE: "${VORTEX_DB_IMAGE:-uselagoon/mysql-8.4:26.10.0}" # Use custom database image (if defined) or fallback to standard database image. environment: <<: *default-environment <<: *default-user @@ -204,7 +204,7 @@ services: #;< MIGRATION database2: - image: "${VORTEX_DB2_IMAGE:-uselagoon/mysql-8.4:26.9.0}" # Use custom database image (if defined) or fallback to standard database image. + image: "${VORTEX_DB2_IMAGE:-uselagoon/mysql-8.4:26.10.0}" # Use custom database image (if defined) or fallback to standard database image. environment: <<: *default-environment MYSQL_DATABASE: drupal @@ -219,7 +219,7 @@ services: #;< SERVICE_CACHE cache: - image: uselagoon/valkey-8:26.9.0 + image: uselagoon/valkey-8:26.10.0 #;< HOSTING_LAGOON labels: lagoon.type: redis # Change to 'none' if dedicated Redis service is used. See https://docs.lagoon.sh/using-lagoon-advanced/service-types/ @@ -264,7 +264,7 @@ services: # Browser container, used for browser testing. browser: - image: selenium/standalone-chromium:152.0 + image: selenium/standalone-chromium:155.0 environment: <<: *default-environment <<: *default-volumes diff --git a/phpstan.neon b/phpstan.neon index eba3023220..19a015deef 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -11,7 +11,7 @@ parameters: level: 7 - phpVersion: 80425 + phpVersion: 80427 paths: - web/modules/custom From 929ee21f956c3e0ea0523170de64a41e2c34836c Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:53:09 +1100 Subject: [PATCH 49/71] [#3098] Enabled email rerouting in every cloud environment and moved 'reroute_email' to its own development modules block. Forward-ported from main 909660bdcd7a3fad3d48b206fe979bf4b239316b. The 2.x deploy step already installs every module outside production, so 'reroute_email' moved into its own fenced 'MODULE_REROUTE_EMAIL' block in 'EnableDevelopmentModulesDeployStep' instead of a provision script, and the BATS hunks were dropped. --- .../Handlers/ModulesHandlerProcessTest.php | 5 +- .../content/development/modules/README.mdx | 4 +- .../modules/contributed-modules.mdx | 15 +++--- .vortex/docs/content/development/settings.mdx | 12 +++-- .../Drupal/EnvironmentSettingsTest.php | 52 ++++++++++++++++++- .../phpunit/Drupal/SwitchableSettingsTest.php | 15 +++++- .../EnableDevelopmentModulesDeployStep.php | 5 +- .../modules/settings.reroute_email.php | 16 +++--- 8 files changed, 98 insertions(+), 26 deletions(-) diff --git a/.vortex/cli/tests/Functional/Handlers/ModulesHandlerProcessTest.php b/.vortex/cli/tests/Functional/Handlers/ModulesHandlerProcessTest.php index cd84923af9..a1de17cbb7 100644 --- a/.vortex/cli/tests/Functional/Handlers/ModulesHandlerProcessTest.php +++ b/.vortex/cli/tests/Functional/Handlers/ModulesHandlerProcessTest.php @@ -79,7 +79,10 @@ public static function dataProviderHandlerProcess(): \Iterator { static::cw(function ($test): void { $test->prompts[Modules::id()] = static::getModulesExcept('reroute_email'); }), - static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('drupal/reroute_email')), + static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains([ + 'drupal/reroute_email', + "install(['reroute_email'])", + ])), ]; yield 'modules_no_robotstxt' => [ static::cw(function ($test): void { diff --git a/.vortex/docs/content/development/modules/README.mdx b/.vortex/docs/content/development/modules/README.mdx index eaac313d36..05a1d35ab8 100644 --- a/.vortex/docs/content/development/modules/README.mdx +++ b/.vortex/docs/content/development/modules/README.mdx @@ -23,9 +23,9 @@ assertions in a single pass. |-----------|----------|--------| | Composer requirement | `require` in [`composer.json`](https://github.com/drevops/vortex/blob/main/composer.json) | Makes the module available to the site. ➡️ See [composer.json](../composer.mdx#require) | | Settings override | `web/sites/default/includes/modules/settings..php` | Applies configuration conditioned on the detected environment, reading values from environment variables. ➡️ See [Settings](../settings.mdx#per-module-overrides) | -| Config export exclusion | `$settings['config_exclude_modules']` in a settings override | Keeps a development-only module out of the exported configuration, so enabling it locally never dirties the config. ➡️ See [Settings](../settings.mdx#per-module-overrides) | +| Config export exclusion | `$settings['config_exclude_modules']` in a settings override | Keeps a module that never reaches production out of the exported configuration, so enabling it locally never dirties the config. ➡️ See [Settings](../settings.mdx#per-module-overrides) | | Provisioning | `CreateContentModelDeployStep` in `ys_base` | Applies the `recipes/page` content model in the `local`, `ci`, `dev` and `stage` environments. ➡️ See [Provision](../provision.mdx) | -| Development provisioning | `EnableDevelopmentModulesDeployStep` in `ys_base` | Sets the site name and installs the contrib, service, demo and development-only modules in the same four environments. ➡️ See [Provision](../provision.mdx) | +| Development provisioning | `EnableDevelopmentModulesDeployStep` in `ys_base` | Sets the site name and installs the contrib, service, demo and development-only modules and the email rerouting safety net in the same 4 environments. ➡️ See [Provision](../provision.mdx) | | Module dependency | [`ys_demo.info.yml`](https://github.com/drevops/vortex/blob/main/web/modules/custom/ys_demo/ys_demo.info.yml) | Installs the module as a dependency of the demo module. ➡️ See [Demo module](module-scaffold.mdx#demo-module) | A module can be required without being installed anywhere: the settings diff --git a/.vortex/docs/content/development/modules/contributed-modules.mdx b/.vortex/docs/content/development/modules/contributed-modules.mdx index 446b36bf3e..af0d32def3 100644 --- a/.vortex/docs/content/development/modules/contributed-modules.mdx +++ b/.vortex/docs/content/development/modules/contributed-modules.mdx @@ -166,9 +166,11 @@ intended recipients. This prevents accidental email delivery to real users in non-production environments while still allowing email functionality to be tested. +- **Installed:** During development provisioning by the `EnableDevelopmentModulesDeployStep` deploy step. + ### Configuration -[`settings.reroute_email.php`](https://github.com/drevops/vortex/blob/main/web/sites/default/includes/modules/settings.reroute_email.php) enables rerouting in every environment except `local`, `ci`, `stage` and `prod`. +[`settings.reroute_email.php`](https://github.com/drevops/vortex/blob/main/web/sites/default/includes/modules/settings.reroute_email.php) excludes the module from the exported configuration and enables rerouting in every environment except `local`, `ci` and `prod`. Rerouting replaces the recipient of an outgoing message with the configured address, unless that recipient matches `DRUPAL_REROUTE_EMAIL_ALLOWED`. With rerouting disabled, every message reaches its intended recipient. Rerouting is therefore disabled only where that delivery is either wanted or already intercepted by other means. @@ -179,15 +181,15 @@ Rerouting replaces the recipient of an outgoing message with the configured addr | Local | No | [Pygmy](../environment/pygmy.mdx) already catches outgoing mail | | CI | No | The [mail collector](../testing/behat.mdx#email) stores messages instead of sending them | | Dev | **Yes** | Prevents accidental delivery to real users | -| Stage | No | Stage may require real email delivery for UAT | +| Stage | **Yes** | Stage runs a copy of production content, so any address that survives database sanitization is real | | Prod | No | Production emails must reach actual recipients | -Rerouting is also enabled in any custom environments (e.g., PR environments) -that do not match the standard environment types listed above. +Rerouting is the default, so it is also enabled in any custom environments (e.g., +PR environments) that do not match the standard environment types listed above. Rerouting is off in `ci` so that tests can assert on the address a message was sent to. With rerouting on, every message would carry the rerouting address instead of the intended one. -A site that deselects this module during [installation](../../installation.mdx) still sends no mail from `ci`, because the mail collector stores messages there regardless. That site does send mail to real recipients in `dev` and in custom environments. +A site that deselects this module during [installation](../../installation.mdx) still sends no mail from `ci`, because the mail collector stores messages there regardless. That site does send mail to real recipients in `dev`, `stage` and custom environments. **Environment variables:** @@ -199,7 +201,8 @@ A site that deselects this module during [installation](../../installation.mdx) **Overriding default behavior:** Set `DRUPAL_REROUTE_EMAIL_DISABLED` to any non-empty value to completely disable -email rerouting in an environment where it would otherwise be enabled. +email rerouting in an environment where it would otherwise be enabled. To send +real mail from `stage` during UAT, set this variable there.
Example of the `Reroute Email` module `settings.reroute_email.php` file diff --git a/.vortex/docs/content/development/settings.mdx b/.vortex/docs/content/development/settings.mdx index 708e3affd1..e66b214222 100644 --- a/.vortex/docs/content/development/settings.mdx +++ b/.vortex/docs/content/development/settings.mdx @@ -373,11 +373,14 @@ tested. | CI | No | Automated tests do not send real emails | | Dev | **Yes** | Prevents accidental delivery to real users | | Preview | **Yes** | Prevents accidental delivery to real users | -| Stage | No | Stage may require real email delivery for UAT | +| Stage | **Yes** | Stage runs a copy of production content, so any address that survives database sanitization is real | | Prod | No | Production emails must reach actual recipients | -Rerouting is also enabled in any custom environments that do not match the -standard environment types listed above. +Rerouting is the default, so it is also enabled in any custom environments that +do not match the standard environment types listed above. + +The settings file excludes the module from the exported configuration, so the +development modules deploy step is the only place that installs it. **Environment variables:** @@ -389,7 +392,8 @@ standard environment types listed above. **Overriding default behavior:** Set `DRUPAL_REROUTE_EMAIL_DISABLED` to any non-empty value to completely disable -email rerouting in an environment where it would otherwise be enabled. +email rerouting in an environment where it would otherwise be enabled. To send +real mail from `stage` during UAT, set this variable there. import RerouteEmailModuleSettingsExample from '!!raw-loader!@site/../../web/sites/default/includes/modules/settings.reroute_email.php'; diff --git a/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 1b7ac2f55c..b61ddeac36 100644 --- a/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -342,6 +342,9 @@ public function testEnvironmentNoOverrides(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -448,6 +451,9 @@ public function testEnvironmentOverrides(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -519,6 +525,9 @@ public function testEnvironmentLocal(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -591,6 +600,9 @@ public function testEnvironmentLocalContainer(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -666,6 +678,9 @@ public function testEnvironmentCircleCi(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -740,6 +755,9 @@ public function testEnvironmentGha(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -810,6 +828,9 @@ public function testEnvironmentAcquiaDynamic(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -877,6 +898,9 @@ public function testEnvironmentAcquiaDev(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -923,7 +947,7 @@ public function testEnvironmentAcquiaStage(): void { $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; - $config['reroute_email.settings']['enable'] = FALSE; + $config['reroute_email.settings']['enable'] = TRUE; $config['reroute_email.settings']['address'] = 'webmaster@your-site-domain.example'; $config['reroute_email.settings']['allowed'] = '*@your-site-domain.example'; $config['shield.settings']['shield_enable'] = TRUE; @@ -944,6 +968,9 @@ public function testEnvironmentAcquiaStage(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -1008,6 +1035,9 @@ public function testEnvironmentAcquiaProd(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -1076,6 +1106,9 @@ public function testEnvironmentAcquiaConfigPathOverride(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -1151,6 +1184,9 @@ public function testEnvironmentAcquiaConfigVcsDirectoryFallback(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -1226,6 +1262,9 @@ public function testEnvironmentLagoonPreview(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -1303,6 +1342,9 @@ public function testEnvironmentLagoonDev(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -1358,7 +1400,7 @@ public function testEnvironmentLagoonTest(): void { $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; - $config['reroute_email.settings']['enable'] = FALSE; + $config['reroute_email.settings']['enable'] = TRUE; $config['reroute_email.settings']['address'] = 'webmaster@your-site-domain.example'; $config['reroute_email.settings']['allowed'] = '*@your-site-domain.example'; $config['shield.settings']['shield_enable'] = TRUE; @@ -1380,6 +1422,9 @@ public function testEnvironmentLagoonTest(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL @@ -1455,6 +1500,9 @@ public function testEnvironmentLagoonProd(): void { // phpcs:ignore #;< MODULE_GENERATED_CONTENT 'generated_content', // phpcs:ignore #;> MODULE_GENERATED_CONTENT + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + 'reroute_email', + // phpcs:ignore #;> MODULE_REROUTE_EMAIL // phpcs:ignore #;< MODULE_SDC_DEVEL 'sdc_devel', // phpcs:ignore #;> MODULE_SDC_DEVEL diff --git a/tests/phpunit/Drupal/SwitchableSettingsTest.php b/tests/phpunit/Drupal/SwitchableSettingsTest.php index 9e5bfe6edd..fb5fcd9116 100644 --- a/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -769,12 +769,12 @@ public static function dataProviderRerouteEmail(): \Iterator { ], ]; - // Stage: disabled by default. + // Stage: enabled by default. yield [ self::ENVIRONMENT_STAGE, [], [ - 'reroute_email.settings' => ['enable' => FALSE, 'address' => 'webmaster@your-site-domain.example', 'allowed' => '*@your-site-domain.example'], + 'reroute_email.settings' => ['enable' => TRUE, 'address' => 'webmaster@your-site-domain.example', 'allowed' => '*@your-site-domain.example'], ], ]; @@ -809,6 +809,17 @@ public static function dataProviderRerouteEmail(): \Iterator { ], ]; + // Stage with DRUPAL_REROUTE_EMAIL_DISABLED: forced off. + yield [ + self::ENVIRONMENT_STAGE, + [ + 'DRUPAL_REROUTE_EMAIL_DISABLED' => 1, + ], + [ + 'reroute_email.settings' => ['enable' => FALSE], + ], + ]; + // Custom address and allowed list. yield [ self::ENVIRONMENT_DEV, diff --git a/web/modules/custom/ys_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/web/modules/custom/ys_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 8617b60685..15e2409ed3 100644 --- a/web/modules/custom/ys_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/web/modules/custom/ys_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -87,7 +87,6 @@ public function run(): void { 'navigation_extra_tools', 'pathauto', 'redirect', - 'reroute_email', 'robotstxt', 'shield', 'stage_file_proxy', @@ -116,6 +115,10 @@ public function run(): void { $this->moduleInstaller->install(['devel']); // phpcs:ignore #;> MODULE_DEVEL + // phpcs:ignore #;< MODULE_REROUTE_EMAIL + $this->moduleInstaller->install(['reroute_email']); + // phpcs:ignore #;> MODULE_REROUTE_EMAIL + // phpcs:ignore #;< CUSTOM_MODULE_SEARCH $this->moduleInstaller->install(['ys_search']); // phpcs:ignore #;> CUSTOM_MODULE_SEARCH diff --git a/web/sites/default/includes/modules/settings.reroute_email.php b/web/sites/default/includes/modules/settings.reroute_email.php index d50c66a338..5408b1c8a6 100644 --- a/web/sites/default/includes/modules/settings.reroute_email.php +++ b/web/sites/default/includes/modules/settings.reroute_email.php @@ -9,26 +9,26 @@ use DrevOps\EnvironmentDetector\Environment; +$settings['config_exclude_modules'][] = 'reroute_email'; + // Default reroute email address and allowed list. $config['reroute_email.settings']['address'] = getenv('DRUPAL_REROUTE_EMAIL_ADDRESS') ?: 'webmaster@your-site-domain.example'; $config['reroute_email.settings']['allowed'] = getenv('DRUPAL_REROUTE_EMAIL_ALLOWED') ?: '*@your-site-domain.example'; -// Enable rerouting in all environments except local, ci, stage and prod. -// This covers dev and any custom environments (e.g., PR environments). -if (!in_array($settings['environment'], [ +if (in_array($settings['environment'], [ Environment::LOCAL, Environment::CI, - Environment::STAGE, Environment::PRODUCTION, ])) { + // Deliver every message to its intended recipient. Local and CI capture + // outgoing mail by other means, and production sends to real recipients. + $config['reroute_email.settings']['enable'] = FALSE; +} +else { // Send every outgoing message to the address above instead of to its // intended recipient, unless that recipient matches the allowed list. $config['reroute_email.settings']['enable'] = TRUE; } -else { - // Deliver every message to its intended recipient. - $config['reroute_email.settings']['enable'] = FALSE; -} // Allow an environment to opt out of the rerouting set above. if (!empty(getenv('DRUPAL_REROUTE_EMAIL_DISABLED'))) { From 4f6c66eee2af6fd80c3790d1a164ec779d1e9c9d Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:53:18 +1100 Subject: [PATCH 50/71] [#3103] Corrected stale stage mail comment in 'dataProviderMailCollector()'. Forward-ported from main db498d6526a4fc5e42f0cb9b2752a104525625c4. Applied as is to the matching provider comment in the 2.x 'SwitchableSettingsTest'. --- tests/phpunit/Drupal/SwitchableSettingsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/Drupal/SwitchableSettingsTest.php b/tests/phpunit/Drupal/SwitchableSettingsTest.php index fb5fcd9116..e8c2b501fe 100644 --- a/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1048,7 +1048,7 @@ public static function dataProviderMailCollector(): \Iterator { ], ]; - // Stage: delivered to the original recipients. + // Stage: rerouted, then delivered to the rerouting address. yield [ self::ENVIRONMENT_STAGE, [], From 35a1a993eca4a5cefbbea18bbb5f129c71dea614 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:57:38 +1100 Subject: [PATCH 51/71] [#3100] Corrected the contrib path guard in 'settings.fast404.php' and covered it with unit and functional tests. Forward-ported from main e28b8de80cb099b08cbc89eb0476eef027c5865e. The settings file is renamed to 'settings.fast_404.php', the 'fast_404' option lands in the 2.x CLI 'Modules' handler, and the Ahoy workflow subtest reuses the 2.x 'webserver' page fetch helper. --- .vortex/cli/src/Prompts/Handlers/Modules.php | 1 + .../Handlers/ModulesHandlerProcessTest.php | 6 + .../Handlers/ModulesHandlerDiscoveryTest.php | 1 + .vortex/docs/content/development/composer.mdx | 1 + .../modules/contributed-modules.mdx | 10 + .vortex/docs/cspell.json | 1 + .../phpunit/Functional/AhoyWorkflowTest.php | 2 + .../Traits/Subtests/SubtestAhoyTrait.php | 16 ++ composer.json | 1 + .../Drupal/EnvironmentSettingsTest.php | 208 ++++++++++++++++++ tests/phpunit/Drupal/SettingsTestCase.php | 41 ++++ .../phpunit/Drupal/SwitchableSettingsTest.php | 123 +++++++++++ ...ings.fast404.php => settings.fast_404.php} | 9 +- 13 files changed, 414 insertions(+), 6 deletions(-) rename web/sites/default/includes/modules/{settings.fast404.php => settings.fast_404.php} (65%) diff --git a/.vortex/cli/src/Prompts/Handlers/Modules.php b/.vortex/cli/src/Prompts/Handlers/Modules.php index fa8d2d3045..99a4f20cec 100644 --- a/.vortex/cli/src/Prompts/Handlers/Modules.php +++ b/.vortex/cli/src/Prompts/Handlers/Modules.php @@ -122,6 +122,7 @@ public static function getAvailableModules(): array { 'devel' => 'Devel', 'drupal_helpers' => 'Drupal helpers', 'environment_indicator' => 'Environment indicator', + 'fast_404' => 'Fast 404', 'generated_content' => 'Generated content', 'navigation_extra_tools' => 'Navigation extra tools', 'pathauto' => 'Pathauto', diff --git a/.vortex/cli/tests/Functional/Handlers/ModulesHandlerProcessTest.php b/.vortex/cli/tests/Functional/Handlers/ModulesHandlerProcessTest.php index a1de17cbb7..88ec0d531c 100644 --- a/.vortex/cli/tests/Functional/Handlers/ModulesHandlerProcessTest.php +++ b/.vortex/cli/tests/Functional/Handlers/ModulesHandlerProcessTest.php @@ -48,6 +48,12 @@ public static function dataProviderHandlerProcess(): \Iterator { }), static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('environment_indicator')), ]; + yield 'modules_no_fast_404' => [ + static::cw(function ($test): void { + $test->prompts[Modules::id()] = static::getModulesExcept('fast_404'); + }), + static::cw(fn(FunctionalTestCase $test) => $test->assertSutNotContains('fast_404')), + ]; yield 'modules_no_generated_content' => [ static::cw(function ($test): void { $test->prompts[Modules::id()] = static::getModulesExcept('generated_content'); diff --git a/.vortex/cli/tests/Unit/Handlers/ModulesHandlerDiscoveryTest.php b/.vortex/cli/tests/Unit/Handlers/ModulesHandlerDiscoveryTest.php index ecd3300f02..39ba2c9ce7 100644 --- a/.vortex/cli/tests/Unit/Handlers/ModulesHandlerDiscoveryTest.php +++ b/.vortex/cli/tests/Unit/Handlers/ModulesHandlerDiscoveryTest.php @@ -44,6 +44,7 @@ function (AbstractHandlerDiscoveryTestCase $test, Config $config): void { 'drupal/devel' => '^5.5', 'drupal/drupal_helpers' => '^2.0.1', 'drupal/environment_indicator' => '^4.0.25', + 'drupal/fast_404' => '^3.7', 'drupal/generated_content' => '^2.0.1', 'drupal/navigation_extra_tools' => '^1.3.2', 'drupal/pathauto' => '^1.14', diff --git a/.vortex/docs/content/development/composer.mdx b/.vortex/docs/content/development/composer.mdx index 97d828af08..2946bdb5e3 100644 --- a/.vortex/docs/content/development/composer.mdx +++ b/.vortex/docs/content/development/composer.mdx @@ -554,6 +554,7 @@ where each module is installed. | [`drupal/devel`](https://www.drupal.org/project/devel) | A suite of development tools for inspecting variables, entities and the service container while debugging. | [Settings](settings.mdx#per-module-overrides) | | [`drupal/drupal_helpers`](https://www.drupal.org/project/drupal_helpers) | A collection of helper functions that simplify writing update hooks and deployment operations. | [Drupal helpers](modules/drupal-helpers.mdx) | | [`drupal/environment_indicator`](https://www.drupal.org/project/environment_indicator) | Shows a colored banner identifying the current environment to prevent accidental changes on the wrong site. | [Settings](settings.mdx#per-module-overrides) | +| [`drupal/fast_404`](https://www.drupal.org/project/fast_404) | Answers requests for missing files with a 404 before Drupal bootstraps, saving the bootstrap that core's own fast 404 still performs. | [Settings](settings.mdx#per-module-overrides) | | [`drupal/generated_content`](https://www.drupal.org/project/generated_content) | Generates deterministic placeholder content from declarative definitions for development and testing. | [Generated content](modules/generated-content.mdx), [Settings](settings.mdx#per-module-overrides) | | [`drupal/migrate_plus`](https://www.drupal.org/project/migrate_plus) | Extends the core Migrate API with extra source and process plugins and configuration-entity migrations. | [Migrations](migrations.mdx) | | [`drupal/migrate_tools`](https://www.drupal.org/project/migrate_tools) | Provides Drush commands and a UI to run, roll back and monitor migrations. | [Migrations](migrations.mdx) | diff --git a/.vortex/docs/content/development/modules/contributed-modules.mdx b/.vortex/docs/content/development/modules/contributed-modules.mdx index af0d32def3..5047a66fe3 100644 --- a/.vortex/docs/content/development/modules/contributed-modules.mdx +++ b/.vortex/docs/content/development/modules/contributed-modules.mdx @@ -77,6 +77,16 @@ No settings override. [`settings.environment_indicator.php`](https://github.com/drevops/vortex/blob/main/web/sites/default/includes/modules/settings.environment_indicator.php) names the indicator after the detected environment and colors it per environment - red for production, yellow for stage, green for dev - with the toolbar integration and favicon marker turned on. +## Fast 404 + +[Fast 404](https://www.drupal.org/project/fast_404) answers requests for missing files without bootstrapping Drupal. Drupal core already returns a lightweight 404 for the same file extensions, but only after a full bootstrap. On a site serving many such requests, Fast 404 saves that bootstrap. + +- **Installed:** Never enabled as a Drupal module. The handler runs from the settings file before the module system exists, so requiring the package is enough. + +### Configuration + +[`settings.fast_404.php`](https://github.com/drevops/vortex/blob/main/web/sites/default/includes/modules/settings.fast_404.php) sets the file extensions to intercept, allowlists the front controller and the other entry-point scripts, allows anonymous access to image style derivatives and calls `fast404_preboot()` with those settings. + ## Generated Content [Generated content](https://www.drupal.org/project/generated_content) generates deterministic placeholder content from declarative definitions for development and testing. diff --git a/.vortex/docs/cspell.json b/.vortex/docs/cspell.json index 1964b6de88..6d56b73064 100644 --- a/.vortex/docs/cspell.json +++ b/.vortex/docs/cspell.json @@ -77,6 +77,7 @@ "phpcompatibility", "phpspec", "phpstorm", + "preboot", "pyrech", "redis", "renovatebot", diff --git a/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php b/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php index de1a2a0cb4..35b2f417aa 100644 --- a/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php +++ b/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php @@ -70,6 +70,8 @@ public function testAhoyWorkflowStateless(): void { $this->subtestAhoyLintTests(); + $this->subtestAhoyFast404(); + $this->subtestAhoyReset(); $this->subtestAhoyResetHard(); diff --git a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php index b9ed77dbb9..7b44d3804b 100644 --- a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php +++ b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php @@ -1021,6 +1021,22 @@ protected function subtestAhoyRedis(): void { $this->logStepFinish(); } + protected function subtestAhoyFast404(): void { + $this->logStepStart(); + + $this->logSubstep('Assert that the preboot error page is served for a missing asset'); + // Drupal core serves a near-identical 404 page for the same extensions, + // so the DOCTYPE from `settings.fast_404.php` is what tells the two apart. + $this->assertWebpageContains('/missing.png', '-//W3C//DTD XHTML+RDFa 1.0//EN', 'Error page from `settings.fast_404.php` should be served'); + $this->assertWebpageContains('/missing.png', 'The requested URL "/missing.png" was not found on this server.', 'Error page should report the request path resolved before Drupal bootstraps'); + + $this->logSubstep('Assert that a route served by Drupal is not intercepted'); + $this->assertWebpageNotContains('/robots.txt', '-//W3C//DTD XHTML+RDFa 1.0//EN', '`robots.txt` is served by a module, so the preboot handler must let it through'); + $this->assertWebpageContains('/robots.txt', 'User-agent: *', '`robots.txt` should be served by Drupal'); + + $this->logStepFinish(); + } + protected function substepWarmCaches(): void { $this->logNote('Warming up caches'); $this->cmd('ahoy drush cr'); diff --git a/composer.json b/composer.json index e77c09fe41..0131c9e4ce 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,7 @@ "drupal/devel": "^5.5", "drupal/drupal_helpers": "^2.2.0", "drupal/environment_indicator": "^4.0.25", + "drupal/fast_404": "^3.7", "drupal/generated_content": "^2.2.0", "drupal/migrate_plus": "^6.0.10", "drupal/migrate_tools": "^6.1.4", diff --git a/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/tests/phpunit/Drupal/EnvironmentSettingsTest.php index b61ddeac36..dbf0b06d2c 100644 --- a/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -355,6 +355,19 @@ public function testEnvironmentNoOverrides(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_SUT; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -465,6 +478,19 @@ public function testEnvironmentOverrides(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_SUT; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'custom_public'; $settings['file_private_path'] = 'custom_private'; $settings['file_temp_path'] = 'custom_temp'; @@ -538,6 +564,19 @@ public function testEnvironmentLocal(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_LOCAL; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -613,6 +652,19 @@ public function testEnvironmentLocalContainer(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_LOCAL; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -691,6 +743,19 @@ public function testEnvironmentCircleCi(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_CI; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -768,6 +833,19 @@ public function testEnvironmentGha(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_CI; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -841,6 +919,19 @@ public function testEnvironmentAcquiaDynamic(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_PREVIEW; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -911,6 +1002,19 @@ public function testEnvironmentAcquiaDev(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_DEV; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -981,6 +1085,19 @@ public function testEnvironmentAcquiaStage(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_STAGE; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -1048,6 +1165,19 @@ public function testEnvironmentAcquiaProd(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_PROD; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -1120,6 +1250,19 @@ public function testEnvironmentAcquiaConfigPathOverride(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_DEV; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -1199,6 +1342,19 @@ public function testEnvironmentAcquiaConfigVcsDirectoryFallback(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_DEV; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -1276,6 +1432,19 @@ public function testEnvironmentLagoonPreview(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_PREVIEW; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -1356,6 +1525,19 @@ public function testEnvironmentLagoonDev(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_DEV; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -1436,6 +1618,19 @@ public function testEnvironmentLagoonTest(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_STAGE; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -1514,6 +1709,19 @@ public function testEnvironmentLagoonProd(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_PROD; + // phpcs:ignore #;< MODULE_FAST_404 + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'install.php', + 'cron.php', + 'update.php', + 'xmlrpc.php', + ]; + // phpcs:ignore #;> MODULE_FAST_404 $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; diff --git a/tests/phpunit/Drupal/SettingsTestCase.php b/tests/phpunit/Drupal/SettingsTestCase.php index fe1ece5364..5e009e7e7f 100644 --- a/tests/phpunit/Drupal/SettingsTestCase.php +++ b/tests/phpunit/Drupal/SettingsTestCase.php @@ -237,6 +237,47 @@ protected function requireSettingsFile(array $pre_settings = [], array $pre_conf $this->databases = $databases; } + /** + * Require a per-module settings file with an explicit contrib path. + * + * Per-module settings files guarded by the presence of a module directory + * are unreachable through the site's own contrib path when the module is not + * required by the project. + * + * @param string $module + * Module name as it appears in the `settings..php` file name. + * @param string $contrib_path + * Path to the contrib modules directory to expose to the settings file. + * @param array $pre_settings + * Array of settings to pre-populate. + * @param array $pre_config + * Array of configs to pre-populate. + */ + protected function requireModuleSettingsFile(string $module, string $contrib_path, array $pre_settings = [], array $pre_config = []): void { + $app_root = getcwd() . '/web'; + + if (!file_exists($app_root)) { + throw new \RuntimeException('Could not determine application root.'); + } + + $site_path = 'sites/default'; + $file = implode(DIRECTORY_SEPARATOR, [$app_root, $site_path, 'includes', 'modules', sprintf('settings.%s.php', $module)]); + + if (!file_exists($file)) { + throw new \RuntimeException(sprintf('Settings file %s does not exist.', $file)); + } + + $config = $pre_config; + $settings = $pre_settings; + + require $file; + + $this->app_root = $app_root; + $this->site_path = $site_path; + $this->config = $config; + $this->settings = $settings; + } + /** * Assert that config retrieved from the real settings file match test data. * diff --git a/tests/phpunit/Drupal/SwitchableSettingsTest.php b/tests/phpunit/Drupal/SwitchableSettingsTest.php index e8c2b501fe..173c3478bd 100644 --- a/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -4,6 +4,10 @@ namespace Drupal; +// phpcs:ignore #;< MODULE_FAST_404 +use PHPUnit\Framework\Attributes\PreserveGlobalState; +use PHPUnit\Framework\Attributes\RunInSeparateProcess; +// phpcs:ignore #;> MODULE_FAST_404 use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; @@ -19,6 +23,25 @@ #[Group('drupal_settings')] class SwitchableSettingsTest extends SettingsTestCase { + // phpcs:ignore #;< MODULE_FAST_404 + + /** + * Path to the contrib modules directory fixture. + */ + protected ?string $contribFixture = NULL; + + /** + * {@inheritdoc} + */ + protected function tearDown(): void { + if (!is_null($this->contribFixture)) { + $this->removeContribFixture($this->contribFixture); + } + + parent::tearDown(); + } + + // phpcs:ignore #;> MODULE_FAST_404 // phpcs:ignore #;< SERVICE_ANTIVIRUS /** @@ -232,6 +255,106 @@ public static function dataProviderEnvironmentIndicator(): \Iterator { } // phpcs:ignore #;> MODULE_ENVIRONMENT_INDICATOR + // phpcs:ignore #;< MODULE_FAST_404 + + /** + * Test Fast 404 settings. + * + * Runs isolated so that the module stub owns the 'fast404_preboot()' + * declaration and its invocation marker is conclusive. + */ + #[DataProvider('dataProviderFast404')] + #[RunInSeparateProcess] + #[PreserveGlobalState(FALSE)] + public function testFast404(bool $module_installed, array $expected_present, array $expected_absent = []): void { + $contrib_path = $this->createContribFixture($module_installed); + + $this->requireModuleSettingsFile('fast_404', $contrib_path); + + $this->assertSettingsContains($expected_present); + $this->assertSettingsNotContains($expected_absent); + $this->assertSame($module_installed, file_exists($contrib_path . '/fast_404/preboot'), 'Preboot invocation'); + } + + /** + * Data provider for testFast404(). + */ + public static function dataProviderFast404(): \Iterator { + yield 'module installed' => [ + TRUE, + [ + 'fast404_exts' => '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i', + 'fast404_allow_anon_imagecache' => TRUE, + 'fast404_whitelist' => ['index.php', 'rss.xml', 'install.php', 'cron.php', 'update.php', 'xmlrpc.php'], + 'fast404_html' => '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

', + ], + ]; + yield 'module not installed' => [ + FALSE, + [], + [ + 'fast404_exts' => NULL, + 'fast404_allow_anon_imagecache' => NULL, + 'fast404_whitelist' => NULL, + 'fast404_html' => NULL, + ], + ]; + } + + /** + * Create a contrib modules directory fixture. + * + * The Fast 404 module is not required by the project, so its settings file + * guard can only be satisfied by a stub. + * + * @param bool $with_fast404 + * Create a stub of the Fast 404 module within the fixture. The stub marks + * the directory when its preboot function is called. + * + * @return string + * Path to the contrib modules directory fixture. + */ + protected function createContribFixture(bool $with_fast404): string { + $this->contribFixture = getcwd() . '/.artifacts/tmp/' . uniqid('contrib-'); + + mkdir($this->contribFixture, 0777, TRUE); + + if ($with_fast404) { + $stub = <<<'PHP' + contribFixture . '/fast_404'); + file_put_contents($this->contribFixture . '/fast_404/fast404.inc', $stub); + } + + return $this->contribFixture; + } + + /** + * Remove the contrib modules directory fixture. + * + * @param string $path + * Path to the contrib modules directory fixture. + */ + protected function removeContribFixture(string $path): void { + foreach (glob($path . '/*/*') ?: [] as $file) { + unlink($file); + } + + foreach (glob($path . '/*', GLOB_ONLYDIR) ?: [] as $dir) { + rmdir($dir); + } + + rmdir($path); + } + + // phpcs:ignore #;> MODULE_FAST_404 // phpcs:ignore #;< SERVICE_CACHE /** diff --git a/web/sites/default/includes/modules/settings.fast404.php b/web/sites/default/includes/modules/settings.fast_404.php similarity index 65% rename from web/sites/default/includes/modules/settings.fast404.php rename to web/sites/default/includes/modules/settings.fast_404.php index 148f7d255f..d5fcf8950d 100644 --- a/web/sites/default/includes/modules/settings.fast404.php +++ b/web/sites/default/includes/modules/settings.fast_404.php @@ -7,9 +7,8 @@ declare(strict_types=1); -if (file_exists($contrib_path . '/fast404/fast404.inc')) { - // @codeCoverageIgnoreStart - $settings['fast404_exts'] = '/^(?!robots).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +if (file_exists($contrib_path . '/fast_404/fast404.inc')) { + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', @@ -19,10 +18,8 @@ 'update.php', 'xmlrpc.php', ]; - $settings['fast404_string_whitelisting'] = ['/advagg_']; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; - include_once $contrib_path . '/fast404/fast404.inc'; + include_once $contrib_path . '/fast_404/fast404.inc'; // @phpstan-ignore-next-line fast404_preboot($settings); - // @codeCoverageIgnoreEnd } From 0fc3402c5c9cdc86b1e6b8dfd3623c1ec0fc86ee Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sun, 25 Oct 2026 23:58:50 +1100 Subject: [PATCH 52/71] Adopted the documented Fast 404 settings and covered them with tests. Forward-ported from main 1447fe572fc3b232bec9a990ed4d4760436c6474. Applied as is, with the Ahoy workflow subtest requests sent to the 2.x 'webserver' service instead of 'nginx'. --- .../modules/contributed-modules.mdx | 2 +- .../Traits/Subtests/SubtestAhoyTrait.php | 21 +++- .../Drupal/EnvironmentSettingsTest.php | 112 ++++++++++-------- .../phpunit/Drupal/SwitchableSettingsTest.php | 10 +- .../includes/modules/settings.fast_404.php | 41 ++++++- 5 files changed, 129 insertions(+), 57 deletions(-) diff --git a/.vortex/docs/content/development/modules/contributed-modules.mdx b/.vortex/docs/content/development/modules/contributed-modules.mdx index 5047a66fe3..1b1ae151b1 100644 --- a/.vortex/docs/content/development/modules/contributed-modules.mdx +++ b/.vortex/docs/content/development/modules/contributed-modules.mdx @@ -85,7 +85,7 @@ No settings override. ### Configuration -[`settings.fast_404.php`](https://github.com/drevops/vortex/blob/main/web/sites/default/includes/modules/settings.fast_404.php) sets the file extensions to intercept, allowlists the front controller and the other entry-point scripts, allows anonymous access to image style derivatives and calls `fast404_preboot()` with those settings. +[`settings.fast_404.php`](https://github.com/drevops/vortex/blob/main/web/sites/default/includes/modules/settings.fast_404.php) sets the file extensions to intercept, allowlists the front controller and the other entry-point scripts, brings image style derivatives under the same rules and calls `fast404_preboot()` with those settings. Anonymous requests can't force derivative generation. Path checking against the router and the URL aliases is off, because it queries the database before Drupal has connected to it. ## Generated Content diff --git a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php index 7b44d3804b..062602f17a 100644 --- a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php +++ b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php @@ -1024,16 +1024,31 @@ protected function subtestAhoyRedis(): void { protected function subtestAhoyFast404(): void { $this->logStepStart(); - $this->logSubstep('Assert that the preboot error page is served for a missing asset'); // Drupal core serves a near-identical 404 page for the same extensions, // so the DOCTYPE from `settings.fast_404.php` is what tells the two apart. - $this->assertWebpageContains('/missing.png', '-//W3C//DTD XHTML+RDFa 1.0//EN', 'Error page from `settings.fast_404.php` should be served'); + $error_page = '-//W3C//DTD XHTML+RDFa 1.0//EN'; + $derivative = '/sites/default/files/styles/large/public/missing.jpg'; + + $this->logSubstep('Assert that the preboot error page is served for a missing asset'); + $this->assertWebpageContains('/missing.png', $error_page, 'Error page from `settings.fast_404.php` should be served'); $this->assertWebpageContains('/missing.png', 'The requested URL "/missing.png" was not found on this server.', 'Error page should report the request path resolved before Drupal bootstraps'); + $this->cmd('ahoy cli curl -- -sSL -o /dev/null -w "%{http_code}" http://webserver:8080/missing.png | grep -q 404', txt: 'Missing asset should be answered with a 404 status'); + + $this->logSubstep('Assert that a missing image derivative is served the error page'); + $this->assertWebpageContains($derivative, $error_page, 'Image derivatives should fall under the static file rules for anonymous users'); + $this->cmd('ahoy cli curl -- -sSL -o /dev/null -w "%{http_code}" http://webserver:8080' . $derivative . ' | grep -q 404', txt: 'Missing image derivative should be answered with a 404 status'); $this->logSubstep('Assert that a route served by Drupal is not intercepted'); - $this->assertWebpageNotContains('/robots.txt', '-//W3C//DTD XHTML+RDFa 1.0//EN', '`robots.txt` is served by a module, so the preboot handler must let it through'); + $this->assertWebpageNotContains('/robots.txt', $error_page, '`robots.txt` is served by a module, so the preboot handler must let it through'); $this->assertWebpageContains('/robots.txt', 'User-agent: *', '`robots.txt` should be served by Drupal'); + $this->logSubstep('Assert that a missing page without an extension is left to Drupal'); + $this->assertWebpageNotContains('/some-missing-page', $error_page, 'Path checking is disabled, so Drupal answers paths that carry no file extension'); + // The settings script only ever appears on a page Drupal itself rendered, + // so it separates a Drupal 404 from a web server one. + $this->assertWebpageContains('/some-missing-page', 'drupal-settings-json', 'Drupal should render the 404 page for a path that carries no file extension'); + $this->cmd('ahoy cli curl -- -sSL -o /dev/null -w "%{http_code}" http://webserver:8080/some-missing-page | grep -q 404', txt: 'Missing page should be answered with a 404 status'); + $this->logStepFinish(); } diff --git a/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/tests/phpunit/Drupal/EnvironmentSettingsTest.php index dbf0b06d2c..69ec7e28fa 100644 --- a/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -356,15 +356,16 @@ public function testEnvironmentNoOverrides(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_SUT; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -479,15 +480,16 @@ public function testEnvironmentOverrides(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_SUT; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -565,15 +567,16 @@ public function testEnvironmentLocal(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_LOCAL; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -653,15 +656,16 @@ public function testEnvironmentLocalContainer(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_LOCAL; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -744,15 +748,16 @@ public function testEnvironmentCircleCi(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_CI; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -834,15 +839,16 @@ public function testEnvironmentGha(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_CI; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -920,15 +926,16 @@ public function testEnvironmentAcquiaDynamic(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_PREVIEW; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -1003,15 +1010,16 @@ public function testEnvironmentAcquiaDev(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_DEV; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -1086,15 +1094,16 @@ public function testEnvironmentAcquiaStage(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_STAGE; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -1166,15 +1175,16 @@ public function testEnvironmentAcquiaProd(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_PROD; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -1251,15 +1261,16 @@ public function testEnvironmentAcquiaConfigPathOverride(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_DEV; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -1343,15 +1354,16 @@ public function testEnvironmentAcquiaConfigVcsDirectoryFallback(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_DEV; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -1433,15 +1445,16 @@ public function testEnvironmentLagoonPreview(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_PREVIEW; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -1526,15 +1539,16 @@ public function testEnvironmentLagoonDev(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_DEV; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -1619,15 +1633,16 @@ public function testEnvironmentLagoonTest(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_STAGE; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 @@ -1710,15 +1725,16 @@ public function testEnvironmentLagoonProd(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_PROD; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_allow_anon_imagecache'] = FALSE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; // phpcs:ignore #;> MODULE_FAST_404 diff --git a/tests/phpunit/Drupal/SwitchableSettingsTest.php b/tests/phpunit/Drupal/SwitchableSettingsTest.php index 173c3478bd..ed08e8e5f3 100644 --- a/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -284,8 +284,11 @@ public static function dataProviderFast404(): \Iterator { TRUE, [ 'fast404_exts' => '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i', - 'fast404_allow_anon_imagecache' => TRUE, - 'fast404_whitelist' => ['index.php', 'rss.xml', 'install.php', 'cron.php', 'update.php', 'xmlrpc.php'], + 'fast404_allow_anon_imagecache' => FALSE, + 'fast404_url_whitelisting' => TRUE, + 'fast404_whitelist' => ['index.php', 'rss.xml', 'cron.php', 'xmlrpc.php'], + 'fast404_path_check' => FALSE, + 'fast404_respect_redirect' => FALSE, 'fast404_html' => '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

', ], ]; @@ -295,7 +298,10 @@ public static function dataProviderFast404(): \Iterator { [ 'fast404_exts' => NULL, 'fast404_allow_anon_imagecache' => NULL, + 'fast404_url_whitelisting' => NULL, 'fast404_whitelist' => NULL, + 'fast404_path_check' => NULL, + 'fast404_respect_redirect' => NULL, 'fast404_html' => NULL, ], ]; diff --git a/web/sites/default/includes/modules/settings.fast_404.php b/web/sites/default/includes/modules/settings.fast_404.php index d5fcf8950d..20312a4091 100644 --- a/web/sites/default/includes/modules/settings.fast_404.php +++ b/web/sites/default/includes/modules/settings.fast_404.php @@ -8,18 +8,53 @@ declare(strict_types=1); if (file_exists($contrib_path . '/fast_404/fast404.inc')) { + // Disallowed extensions. Any extension set here will not be served by Drupal + // and will get a Fast 404. This does not affect actual files on the + // filesystem, as requests hit them before defaulting to a Drupal request. $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; - $settings['fast404_allow_anon_imagecache'] = TRUE; + + // Image derivative URLs fall under the same rules as any other static file. + // Anonymous requests no longer create derivatives, so the site cannot be + // taken down by hammering it with image style paths. + $settings['fast404_allow_anon_imagecache'] = FALSE; + + // Check requests against a whitelist before the extension list. Modules that + // serve their own PHP files need to be whitelisted below if they bootstrap + // Drupal. + $settings['fast404_url_whitelisting'] = TRUE; + + // Files and URLs allowed while URL whitelisting is enabled. $settings['fast404_whitelist'] = [ 'index.php', 'rss.xml', - 'install.php', 'cron.php', - 'update.php', 'xmlrpc.php', ]; + + // Check whether the requested path corresponds to a real page by consulting + // the router and the URL aliases. This finds 404s earlier at the cost of + // adding the lookup to regular page loads. The lookup queries the database + // before Drupal has connected to it, so every path other than the front page + // answers with a redirect to the installer. Enable it once the module is + // patched with + // https://www.drupal.org/files/issues/2022-10-05/fast_404-db_preboot_errors_d9.4-2961512-23.patch + // @see https://www.drupal.org/project/fast_404/issues/2961512 + $settings['fast404_path_check'] = FALSE; + + // The path check runs before the Redirect module, so it consults the + // redirect table to avoid answering a configured redirect with a 404. Enable + // it alongside the path check above. + $settings['fast404_respect_redirect'] = FALSE; + + // Body of the 404 response. The '@path' token is replaced with the path + // being requested relative to the executed script. $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + include_once $contrib_path . '/fast_404/fast404.inc'; + // Each answered request logs a TypeError after the response is sent, because + // the module passes an array where an exception is expected. Patch it with + // https://www.drupal.org/files/issues/2023-08-24/fast_404_3x-3194034-10.patch + // @see https://www.drupal.org/project/fast_404/issues/3194034 // @phpstan-ignore-next-line fast404_preboot($settings); } From 2bc312b39830cb1a8747dca067acc6591782a313 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:00:09 +1100 Subject: [PATCH 53/71] [#3211] Fixed Fast 404 blocking missing image style derivatives by setting 'fast404_allow_anon_imagecache' to 'TRUE'. Forward-ported from main b3af19a76bee799016032b20a8b7ac07fa02fbc6. Applied on top of the adopted Fast 404 settings, with the derivative generation subtest requests sent to the 2.x 'webserver' service instead of 'nginx'. --- .../modules/contributed-modules.mdx | 2 +- .vortex/docs/cspell.json | 1 + .../Traits/Subtests/SubtestAhoyTrait.php | 64 ++++++++++++++++++- .../Drupal/EnvironmentSettingsTest.php | 32 +++++----- .../phpunit/Drupal/SwitchableSettingsTest.php | 2 +- .../includes/modules/settings.fast_404.php | 9 +-- 6 files changed, 86 insertions(+), 24 deletions(-) diff --git a/.vortex/docs/content/development/modules/contributed-modules.mdx b/.vortex/docs/content/development/modules/contributed-modules.mdx index 1b1ae151b1..0213620168 100644 --- a/.vortex/docs/content/development/modules/contributed-modules.mdx +++ b/.vortex/docs/content/development/modules/contributed-modules.mdx @@ -85,7 +85,7 @@ No settings override. ### Configuration -[`settings.fast_404.php`](https://github.com/drevops/vortex/blob/main/web/sites/default/includes/modules/settings.fast_404.php) sets the file extensions to intercept, allowlists the front controller and the other entry-point scripts, brings image style derivatives under the same rules and calls `fast404_preboot()` with those settings. Anonymous requests can't force derivative generation. Path checking against the router and the URL aliases is off, because it queries the database before Drupal has connected to it. +[`settings.fast_404.php`](https://github.com/drevops/vortex/blob/main/web/sites/default/includes/modules/settings.fast_404.php) sets the file extensions to intercept, allowlists the front controller and the other entry-point scripts, passes requests for missing image style derivatives to Drupal and calls `fast404_preboot()` with those settings. Drupal generates a derivative only for a URL with a valid `itok` token, so these requests can't generate arbitrary derivatives. Path checking against the router and the URL aliases is off, because it queries the database before Drupal has connected to it. ## Generated Content diff --git a/.vortex/docs/cspell.json b/.vortex/docs/cspell.json index 6d56b73064..edb7966d92 100644 --- a/.vortex/docs/cspell.json +++ b/.vortex/docs/cspell.json @@ -56,6 +56,7 @@ "hadolint", "hotfixes", "htpasswd", + "itok", "jsonpath", "lagooncli", "lando", diff --git a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php index 062602f17a..420bec9cde 100644 --- a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php +++ b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php @@ -1034,8 +1034,9 @@ protected function subtestAhoyFast404(): void { $this->assertWebpageContains('/missing.png', 'The requested URL "/missing.png" was not found on this server.', 'Error page should report the request path resolved before Drupal bootstraps'); $this->cmd('ahoy cli curl -- -sSL -o /dev/null -w "%{http_code}" http://webserver:8080/missing.png | grep -q 404', txt: 'Missing asset should be answered with a 404 status'); - $this->logSubstep('Assert that a missing image derivative is served the error page'); - $this->assertWebpageContains($derivative, $error_page, 'Image derivatives should fall under the static file rules for anonymous users'); + $this->logSubstep('Assert that a missing image derivative is left to Drupal'); + $this->assertWebpageNotContains($derivative, $error_page, 'Image derivatives are exempt from the static file rules, so the preboot handler must let them through'); + $this->assertWebpageContains($derivative, 'drupal-settings-json', 'Drupal should render the 404 page for a derivative of a missing image'); $this->cmd('ahoy cli curl -- -sSL -o /dev/null -w "%{http_code}" http://webserver:8080' . $derivative . ' | grep -q 404', txt: 'Missing image derivative should be answered with a 404 status'); $this->logSubstep('Assert that a route served by Drupal is not intercepted'); @@ -1049,6 +1050,27 @@ protected function subtestAhoyFast404(): void { $this->assertWebpageContains('/some-missing-page', 'drupal-settings-json', 'Drupal should render the 404 page for a path that carries no file extension'); $this->cmd('ahoy cli curl -- -sSL -o /dev/null -w "%{http_code}" http://webserver:8080/some-missing-page | grep -q 404', txt: 'Missing page should be answered with a 404 status'); + $this->logSubstep('Create an image style and source images for derivative generation'); + // An image style without effects keeps the '.png' extension of the source + // image, which the Fast 404 extension pattern matches. + // The command parser treats a backslash as an escape character, so the + // evaluated code uses the global 'Drupal' class instead of namespaced + // class names. + $this->cmd('docker compose exec -T cli drush php:eval ' . escapeshellarg('Drupal::entityTypeManager()->getStorage("image_style")->create(["name" => "fast404_test", "label" => "Fast 404 test"])->save();'), txt: 'Image style without effects should be created'); + $this->cmd('docker compose exec -T cli cp web/core/misc/druplicon.png web/sites/default/files/fast404-anonymous.png', txt: 'Source image for the anonymous request should be created'); + $this->cmd('docker compose exec -T cli cp web/core/misc/druplicon.png web/sites/default/files/fast404-authenticated.png', txt: 'Source image for the logged-in request should be created'); + + $this->logSubstep('Assert that a missing derivative of an existing image is generated with a valid token for an anonymous user'); + $this->assertImageDerivativeGeneratedWithValidToken('fast404_test', 'fast404-anonymous.png', 'Missing derivative should be generated for an anonymous user'); + + $this->logSubstep('Assert that a missing derivative of an existing image is generated with a valid token for a logged-in user'); + $this->assertImageDerivativeGeneratedWithValidToken('fast404_test', 'fast404-authenticated.png', 'Missing derivative should be generated for a logged-in user', $this->fetchSessionCookie()); + + $this->logSubstep('Cleanup after test'); + // Deleting the image style also deletes its derivatives. + $this->cmd('docker compose exec -T cli drush php:eval ' . escapeshellarg('Drupal::entityTypeManager()->getStorage("image_style")->load("fast404_test")->delete();'), txt: 'Image style should be deleted'); + $this->cmd('docker compose exec -T cli rm -f web/sites/default/files/fast404-anonymous.png web/sites/default/files/fast404-authenticated.png', txt: 'Source images should be removed'); + $this->logStepFinish(); } @@ -1068,6 +1090,44 @@ protected function assertWebpageNotContains(string $path, string $content, strin $this->assertStringNotContainsString($content, $fetched, $message ?: sprintf('Webpage at %s should not contain: %s', $path, $content)); } + protected function assertImageDerivativeGeneratedWithValidToken(string $style, string $filename, string $message, string $cookie = ''): void { + $derivative = sprintf('web/sites/default/files/styles/%s/public/%s', $style, $filename); + $url = sprintf('http://webserver:8080/sites/default/files/styles/%s/public/%s', $style, $filename); + $curl = 'docker compose exec -T cli curl -sS -o /dev/null -w "%{http_code} %{content_type}"' . ($cookie === '' ? '' : ' -b ' . escapeshellarg($cookie)); + + // The derivative must not exist yet, or the web server would serve it as a + // static file without passing the request to PHP. + $this->cmd('docker compose exec -T cli test ! -f ' . $derivative, txt: 'Image derivative should not exist before it is requested'); + + $this->cmd($curl . ' ' . escapeshellarg($url), '404', 'Image derivative request without a token should be answered with a 404 status'); + $this->cmd($curl . ' ' . escapeshellarg($url . '?itok=invalid'), '404', 'Image derivative request with an invalid token should be answered with a 404 status'); + $this->cmd('docker compose exec -T cli test ! -f ' . $derivative, txt: 'Image derivative should not be generated without a valid token'); + + $token = trim($this->cmd('docker compose exec -T cli drush php:eval ' . escapeshellarg(sprintf('print Drupal::entityTypeManager()->getStorage("image_style")->load("%s")->getPathToken("public://%s");', $style, $filename)))->getOutput()); + $this->assertNotEmpty($token, 'Image derivative token should be generated'); + + $this->cmd($curl . ' ' . escapeshellarg($url . '?itok=' . $token), '200 image/png', $message); + $this->cmd('docker compose exec -T cli test -f ' . $derivative, txt: 'Image derivative should be saved after it is requested'); + } + + protected function fetchSessionCookie(): string { + $login_output = $this->cmd('ahoy login', txt: 'One-time login link should be generated')->getOutput(); + if (preg_match('#/user/reset/\d+/\d+/[\w-]+/login#', (string) $login_output, $link_match) !== 1) { + $this->fail('Output of `ahoy login` should contain a one-time login link'); + } + + $headers = $this->cmd('docker compose exec -T cli curl -sS -o /dev/null -D - ' . escapeshellarg('http://webserver:8080' . $link_match[0]), txt: 'One-time login link should be opened')->getOutput(); + if (preg_match('/^set-cookie:\s*(S?SESS\w+=[^;\s]+)/mi', $headers, $cookie_match) !== 1) { + $this->fail('Opening the one-time login link should start a session'); + } + + // A failed login also sets a session cookie, so the cookie must open a + // page that requires a logged-in user. + $this->cmd('docker compose exec -T cli curl -sS -o /dev/null -w "%{http_code}" -b ' . escapeshellarg($cookie_match[1]) . ' http://webserver:8080/user/1/edit', '200', 'Session should belong to a logged-in user'); + + return $cookie_match[1]; + } + protected function subtestAhoyMigrationFilesPresent(): void { $this->logStepStart(); diff --git a/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 69ec7e28fa..49b6ed24e9 100644 --- a/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -356,7 +356,7 @@ public function testEnvironmentNoOverrides(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_SUT; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -480,7 +480,7 @@ public function testEnvironmentOverrides(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_SUT; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -567,7 +567,7 @@ public function testEnvironmentLocal(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_LOCAL; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -656,7 +656,7 @@ public function testEnvironmentLocalContainer(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_LOCAL; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -748,7 +748,7 @@ public function testEnvironmentCircleCi(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_CI; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -839,7 +839,7 @@ public function testEnvironmentGha(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_CI; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -926,7 +926,7 @@ public function testEnvironmentAcquiaDynamic(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_PREVIEW; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -1010,7 +1010,7 @@ public function testEnvironmentAcquiaDev(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_DEV; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -1094,7 +1094,7 @@ public function testEnvironmentAcquiaStage(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_STAGE; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -1175,7 +1175,7 @@ public function testEnvironmentAcquiaProd(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_PROD; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -1261,7 +1261,7 @@ public function testEnvironmentAcquiaConfigPathOverride(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_DEV; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -1354,7 +1354,7 @@ public function testEnvironmentAcquiaConfigVcsDirectoryFallback(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_DEV; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -1445,7 +1445,7 @@ public function testEnvironmentLagoonPreview(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_PREVIEW; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -1539,7 +1539,7 @@ public function testEnvironmentLagoonDev(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_DEV; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -1633,7 +1633,7 @@ public function testEnvironmentLagoonTest(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_STAGE; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; @@ -1725,7 +1725,7 @@ public function testEnvironmentLagoonProd(): void { $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_PROD; // phpcs:ignore #;< MODULE_FAST_404 - $settings['fast404_allow_anon_imagecache'] = FALSE; + $settings['fast404_allow_anon_imagecache'] = TRUE; $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; $settings['fast404_path_check'] = FALSE; diff --git a/tests/phpunit/Drupal/SwitchableSettingsTest.php b/tests/phpunit/Drupal/SwitchableSettingsTest.php index ed08e8e5f3..d96670be59 100644 --- a/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -284,7 +284,7 @@ public static function dataProviderFast404(): \Iterator { TRUE, [ 'fast404_exts' => '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i', - 'fast404_allow_anon_imagecache' => FALSE, + 'fast404_allow_anon_imagecache' => TRUE, 'fast404_url_whitelisting' => TRUE, 'fast404_whitelist' => ['index.php', 'rss.xml', 'cron.php', 'xmlrpc.php'], 'fast404_path_check' => FALSE, diff --git a/web/sites/default/includes/modules/settings.fast_404.php b/web/sites/default/includes/modules/settings.fast_404.php index 20312a4091..4af6f182ea 100644 --- a/web/sites/default/includes/modules/settings.fast_404.php +++ b/web/sites/default/includes/modules/settings.fast_404.php @@ -13,10 +13,11 @@ // filesystem, as requests hit them before defaulting to a Drupal request. $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; - // Image derivative URLs fall under the same rules as any other static file. - // Anonymous requests no longer create derivatives, so the site cannot be - // taken down by hammering it with image style paths. - $settings['fast404_allow_anon_imagecache'] = FALSE; + // Requests for missing image style derivatives are passed to Drupal, which + // generates each derivative on its first request. Drupal generates a + // derivative only for a URL with a valid 'itok' token, so these requests + // cannot generate arbitrary derivatives. + $settings['fast404_allow_anon_imagecache'] = TRUE; // Check requests against a whitelist before the extension list. Modules that // serve their own PHP files need to be whitelisted below if they bootstrap From 108970c9d8ec2cc3f3b0f3e2b49fdaaf3b31a252 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:03:05 +1100 Subject: [PATCH 54/71] [#3112] Settled one environment variable guard form across the Drupal settings includes. Forward-ported from main 37eb7214eed3c8ced35b2d4c425de614d4faa6bc. Applied to the 2.x module includes and their tests only; the provider settings files, the 'ENVIRONMENT_TYPE' override block and the 'DRUPAL_TMP_PATH_IS_SHARED' handling live in 'drevops/environment-detector' on 2.x, so those hunks, the Acquia temp path test and the matching docs were dropped. --- .../modules/contributed-modules.mdx | 33 ++- .vortex/docs/content/development/settings.mdx | 41 ++- .../phpunit/Drupal/SwitchableSettingsTest.php | 261 +++++++++++------- .../includes/modules/settings.clamav.php | 2 +- .../includes/modules/settings.redis.php | 2 +- .../modules/settings.reroute_email.php | 2 +- .../includes/modules/settings.shield.php | 17 +- 7 files changed, 229 insertions(+), 129 deletions(-) diff --git a/.vortex/docs/content/development/modules/contributed-modules.mdx b/.vortex/docs/content/development/modules/contributed-modules.mdx index 0213620168..e8d036cf31 100644 --- a/.vortex/docs/content/development/modules/contributed-modules.mdx +++ b/.vortex/docs/content/development/modules/contributed-modules.mdx @@ -15,13 +15,13 @@ sidebar_position: 2 ### Configuration -[`settings.clamav.php`](https://github.com/drevops/vortex/blob/main/web/sites/default/includes/modules/settings.clamav.php) selects daemon or executable mode and points the daemon at the ClamAV service, but only when `DRUPAL_CLAMAV_ENABLED` is set. +[`settings.clamav.php`](https://github.com/drevops/vortex/blob/main/web/sites/default/includes/modules/settings.clamav.php) selects daemon or executable mode and points the daemon at the ClamAV service, but only when `DRUPAL_CLAMAV_ENABLED` is set to `1`. -| Variable | Purpose | -|------------------------------|------------------------------------| -| `DRUPAL_CLAMAV_ENABLED` | Applies the override only when set | -| `DRUPAL_CLAMAV_MODE` | Selects daemon or executable mode | -| `CLAMAV_HOST`, `CLAMAV_PORT` | Daemon host and port | +| Variable | Purpose | +|------------------------------|-------------------------------------------| +| `DRUPAL_CLAMAV_ENABLED` | Applies the override only when set to `1` | +| `DRUPAL_CLAMAV_MODE` | Selects daemon or executable mode | +| `CLAMAV_HOST`, `CLAMAV_PORT` | Daemon host and port | ## Coffee @@ -163,10 +163,10 @@ No settings override. [`settings.redis.php`](https://github.com/drevops/vortex/blob/main/web/sites/default/includes/modules/settings.redis.php) makes Redis the default cache backend, registers the module container YAML files and swaps the bootstrap container over - all gated on `DRUPAL_REDIS_ENABLED` and on the `redis` PHP extension being loaded, so a two-stage deployment can provision the service before switching the cache. -| Variable | Purpose | -|------------------------------------|------------------------------------| -| `DRUPAL_REDIS_ENABLED` | Applies the override only when set | -| `REDIS_HOST`, `REDIS_SERVICE_PORT` | Connection host and port | +| Variable | Purpose | +|------------------------------------|-------------------------------------------| +| `DRUPAL_REDIS_ENABLED` | Applies the override only when set to `1` | +| `REDIS_HOST`, `REDIS_SERVICE_PORT` | Connection host and port | ## Reroute Email @@ -210,8 +210,8 @@ A site that deselects this module during [installation](../../installation.mdx) **Overriding default behavior:** -Set `DRUPAL_REROUTE_EMAIL_DISABLED` to any non-empty value to completely disable -email rerouting in an environment where it would otherwise be enabled. To send +Set `DRUPAL_REROUTE_EMAIL_DISABLED` to `1` to completely disable email rerouting +in an environment where it would otherwise be enabled. To send real mail from `stage` during UAT, set this variable there.
@@ -290,14 +290,13 @@ No settings override. | `DRUPAL_SHIELD_USER` | | HTTP authentication username | | `DRUPAL_SHIELD_PASS` | | HTTP authentication password | | `DRUPAL_SHIELD_PRINT` | | Message shown in the authentication popup (module default when unset) | -| `DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE` | | Set to any non-empty value to keep the `/.well-known/acme-challenge/*` path open for Let's Encrypt certificate generation | +| `DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE` | | Set to `1` to keep the `/.well-known/acme-challenge/*` path open for Let's Encrypt certificate generation | **Overriding default behavior:** -Set `DRUPAL_SHIELD_DISABLED` to any non-empty value to completely disable Shield -in an environment where it would otherwise be enabled. This is useful for -temporary access during debugging or when an environment does not require -protection. +Set `DRUPAL_SHIELD_DISABLED` to `1` to completely disable Shield in an +environment where it would otherwise be enabled. This is useful for temporary +access during debugging or when an environment does not require protection.
Example of the `Shield` module `settings.shield.php` file diff --git a/.vortex/docs/content/development/settings.mdx b/.vortex/docs/content/development/settings.mdx index e66b214222..8c82d26f85 100644 --- a/.vortex/docs/content/development/settings.mdx +++ b/.vortex/docs/content/development/settings.mdx @@ -339,14 +339,13 @@ control there. | `DRUPAL_SHIELD_USER` | | HTTP authentication username | | `DRUPAL_SHIELD_PASS` | | HTTP authentication password | | `DRUPAL_SHIELD_PRINT` | | Message shown in the authentication popup (module default when unset) | -| `DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE` | | Set to any non-empty value to keep the `/.well-known/acme-challenge/*` path open for Let's Encrypt certificate generation | +| `DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE` | | Set to `1` to keep the `/.well-known/acme-challenge/*` path open for Let's Encrypt certificate generation | **Overriding default behavior:** -Set `DRUPAL_SHIELD_DISABLED` to any non-empty value to completely disable Shield -in an environment where it would otherwise be enabled. This is useful for -temporary access during debugging or when an environment does not require -protection. +Set `DRUPAL_SHIELD_DISABLED` to `1` to completely disable Shield in an +environment where it would otherwise be enabled. This is useful for temporary +access during debugging or when an environment does not require protection. import ShieldModuleSettingsExample from '!!raw-loader!@site/../../web/sites/default/includes/modules/settings.shield.php'; @@ -391,9 +390,9 @@ development modules deploy step is the only place that installs it. **Overriding default behavior:** -Set `DRUPAL_REROUTE_EMAIL_DISABLED` to any non-empty value to completely disable -email rerouting in an environment where it would otherwise be enabled. To send -real mail from `stage` during UAT, set this variable there. +Set `DRUPAL_REROUTE_EMAIL_DISABLED` to `1` to completely disable email rerouting +in an environment where it would otherwise be enabled. To send real mail from +`stage` during UAT, set this variable there. import RerouteEmailModuleSettingsExample from '!!raw-loader!@site/../../web/sites/default/includes/modules/settings.reroute_email.php'; @@ -452,6 +451,32 @@ Prefix all such variables with `DRUPAL_` (e.g. `DRUPAL_MY_SETTING`) to distinguish them from other environment variables.
Always define a default hardcoded value for each environment variable. +- **Guard a variable by what it holds.**
+A _boolean flag_ switches behavior on and is read with +`getenv('DRUPAL_MY_FLAG') === '1'`. Every other value leaves the behavior off, +including an unset variable, an empty string, `0`, `true` and `yes`.
+A _value carrier_ holds a value the code uses and is read with +`!empty(getenv('DRUPAL_MY_VALUE'))`. When the code needs the value after the +guard, assign it to a variable first.
+Compare with `===` and `!==`, never with `==`. + +:::warning Flags accept only `1` + +Setting a shipped flag to `true`, `yes`, `on` or any other non-empty value +leaves the behavior **off**. Set each of these flags to `1` in your hosting +provider's environment variables: `DRUPAL_CLAMAV_ENABLED`, +`DRUPAL_REDIS_ENABLED`, `DRUPAL_REROUTE_EMAIL_DISABLED`, +`DRUPAL_SHIELD_DISABLED`, `DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE` and +`DRUPAL_SETTINGS_LOCAL_SKIP`. + +::: + +- **Gate on the presence of a contributed module only when the file needs it.**
+`file_exists($contrib_path . '/my_module')` belongs in an override file that +loads a file from the module directory or registers its paths. An override file +that only writes `$config` or `$settings` skips this guard, because Drupal +ignores overrides for a module that is not installed. + - **Use conditions based on _environment type_ within per-module override files.**
This allows for environment-specific configuration without cluttering the main `settings.php` file.
diff --git a/tests/phpunit/Drupal/SwitchableSettingsTest.php b/tests/phpunit/Drupal/SwitchableSettingsTest.php index d96670be59..9a7b7211b2 100644 --- a/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -45,59 +45,84 @@ protected function tearDown(): void { // phpcs:ignore #;< SERVICE_ANTIVIRUS /** - * Test ClamAV configs in Daemon mode with defaults. + * Test ClamAV config. */ - public function testClamavDaemonCustom(): void { - $this->setEnvVars([ - 'DRUPAL_CLAMAV_ENABLED' => TRUE, - 'DRUPAL_CLAMAV_MODE' => 'daemon', - 'CLAMAV_HOST' => 'custom_clamav_host', - 'CLAMAV_PORT' => 3333, - ]); + #[DataProvider('dataProviderClamav')] + public function testClamav(array $vars, array $expected_present, array $expected_absent = []): void { + $this->setEnvVars($vars); $this->requireSettingsFile(); - $config['clamav.settings']['scan_mode'] = 0; - $config['clamav.settings']['mode_daemon_tcpip']['hostname'] = 'custom_clamav_host'; - $config['clamav.settings']['mode_daemon_tcpip']['port'] = 3333; - - $this->assertConfigContains($config); + $this->assertConfigContains($expected_present); + $this->assertConfigNotContains($expected_absent); } /** - * Test ClamAV configs in Executable mode. + * Data provider for testClamav(). */ - public function testClamavExecutable(): void { - $this->setEnvVars([ - 'DRUPAL_CLAMAV_ENABLED' => TRUE, - 'CLAMAV_HOST' => 'custom_clamav_host', - 'CLAMAV_PORT' => 3333, - ]); - - $this->requireSettingsFile(); + public static function dataProviderClamav(): \Iterator { + yield 'daemon mode with custom host and port' => [ + [ + 'DRUPAL_CLAMAV_ENABLED' => 1, + 'DRUPAL_CLAMAV_MODE' => 'daemon', + 'CLAMAV_HOST' => 'custom_clamav_host', + 'CLAMAV_PORT' => 3333, + ], + [ + 'clamav.settings' => [ + 'scan_mode' => 0, + 'mode_daemon_tcpip' => ['hostname' => 'custom_clamav_host', 'port' => 3333], + ], + ], + ]; - $config['clamav.settings']['scan_mode'] = 1; - $config['clamav.settings']['executable_path'] = '/usr/bin/clamscan'; + yield 'daemon mode with defaults' => [ + [ + 'DRUPAL_CLAMAV_ENABLED' => 1, + 'DRUPAL_CLAMAV_MODE' => 'daemon', + ], + [ + 'clamav.settings' => [ + 'scan_mode' => 0, + 'mode_daemon_tcpip' => ['hostname' => 'antivirus', 'port' => 3310], + ], + ], + ]; - $this->assertConfigContains($config); - } + yield 'executable mode' => [ + [ + 'DRUPAL_CLAMAV_ENABLED' => 1, + 'CLAMAV_HOST' => 'custom_clamav_host', + 'CLAMAV_PORT' => 3333, + ], + [ + 'clamav.settings' => ['scan_mode' => 1, 'executable_path' => '/usr/bin/clamscan'], + ], + ]; - /** - * Test ClamAV configs in Daemon mode with defaults. - */ - public function testClamavDaemonDefaults(): void { - $this->setEnvVars([ - 'DRUPAL_CLAMAV_ENABLED' => TRUE, - 'DRUPAL_CLAMAV_MODE' => 'daemon', - ]); + yield 'variable not set' => [ + [], + [], + ['clamav.settings' => ['scan_mode' => NULL]], + ]; - $this->requireSettingsFile(); + yield 'variable set to an empty value' => [ + ['DRUPAL_CLAMAV_ENABLED' => ''], + [], + ['clamav.settings' => ['scan_mode' => NULL]], + ]; - $config['clamav.settings']['scan_mode'] = 0; - $config['clamav.settings']['mode_daemon_tcpip']['hostname'] = 'antivirus'; - $config['clamav.settings']['mode_daemon_tcpip']['port'] = 3310; + yield 'variable set to zero' => [ + ['DRUPAL_CLAMAV_ENABLED' => '0'], + [], + ['clamav.settings' => ['scan_mode' => NULL]], + ]; - $this->assertConfigContains($config); + yield 'variable set to a non-numeric truthy value' => [ + ['DRUPAL_CLAMAV_ENABLED' => 'true'], + [], + ['clamav.settings' => ['scan_mode' => NULL]], + ]; } // phpcs:ignore #;> SERVICE_ANTIVIRUS @@ -366,74 +391,80 @@ protected function removeContribFixture(string $path): void { /** * Test Redis settings. */ - public function testRedis(): void { - $this->setEnvVars([ - 'DRUPAL_REDIS_ENABLED' => 1, - 'REDIS_HOST' => 'redis_host', - 'REDIS_SERVICE_PORT' => 1234, - 'VORTEX_REDIS_EXTENSION_LOADED' => 1, - ]); + #[DataProvider('dataProviderRedis')] + public function testRedis(array $vars, bool $expected_enabled, array $expected_settings): void { + $this->setEnvVars($vars); $this->requireSettingsFile(); - $settings['redis.connection']['interface'] = 'PhpRedis'; - $settings['redis.connection']['host'] = 'redis_host'; - $settings['redis.connection']['port'] = 1234; - $settings['cache']['default'] = 'cache.backend.redis'; - - $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); + $this->assertSame($expected_enabled, array_key_exists('bootstrap_container_definition', $this->settings), 'Bootstrap container definition'); unset($this->settings['bootstrap_container_definition']); - $this->assertSettingsContains($settings); - } - - /** - * Test Redis settings with REDIS_* environment variables. - */ - public function testRedisVariables(): void { - $this->setEnvVars([ - 'DRUPAL_REDIS_ENABLED' => 1, - 'REDIS_HOST' => 'redis_host', - 'REDIS_SERVICE_PORT' => 6380, - 'VORTEX_REDIS_EXTENSION_LOADED' => 1, - ]); + if ($expected_enabled) { + $this->assertSettingsContains($expected_settings); - $this->requireSettingsFile(); - - $settings['redis.connection']['interface'] = 'PhpRedis'; - $settings['redis.connection']['host'] = 'redis_host'; - $settings['redis.connection']['port'] = 6380; - $settings['cache']['default'] = 'cache.backend.redis'; - - $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); - unset($this->settings['bootstrap_container_definition']); + return; + } - $this->assertSettingsContains($settings); + $this->assertSettingsNotContains($expected_settings); } /** - * Test Redis settings with custom port. + * Data provider for testRedis(). */ - public function testRedisCustomPort(): void { - $this->setEnvVars([ - 'DRUPAL_REDIS_ENABLED' => 1, - 'REDIS_HOST' => 'custom_redis_host', - 'REDIS_SERVICE_PORT' => 6380, - 'VORTEX_REDIS_EXTENSION_LOADED' => 1, - ]); + public static function dataProviderRedis(): \Iterator { + $disabled_settings = ['redis.connection' => ['interface' => NULL], 'cache' => ['default' => NULL]]; - $this->requireSettingsFile(); + yield 'default port' => [ + [ + 'DRUPAL_REDIS_ENABLED' => 1, + 'REDIS_HOST' => 'redis_host', + 'VORTEX_REDIS_EXTENSION_LOADED' => 1, + ], + TRUE, + [ + 'redis.connection' => ['interface' => 'PhpRedis', 'host' => 'redis_host', 'port' => '6379'], + 'cache' => ['default' => 'cache.backend.redis'], + ], + ]; + + yield 'custom host and port' => [ + [ + 'DRUPAL_REDIS_ENABLED' => 1, + 'REDIS_HOST' => 'custom_redis_host', + 'REDIS_SERVICE_PORT' => 6380, + 'VORTEX_REDIS_EXTENSION_LOADED' => 1, + ], + TRUE, + [ + 'redis.connection' => ['interface' => 'PhpRedis', 'host' => 'custom_redis_host', 'port' => 6380], + 'cache' => ['default' => 'cache.backend.redis'], + ], + ]; - // Test custom Redis configuration. - $settings['redis.connection']['interface'] = 'PhpRedis'; - $settings['redis.connection']['host'] = 'custom_redis_host'; - $settings['redis.connection']['port'] = 6380; - $settings['cache']['default'] = 'cache.backend.redis'; + yield 'variable not set' => [ + ['VORTEX_REDIS_EXTENSION_LOADED' => 1], + FALSE, + $disabled_settings, + ]; - $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); - unset($this->settings['bootstrap_container_definition']); + yield 'variable set to an empty value' => [ + ['DRUPAL_REDIS_ENABLED' => '', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], + FALSE, + $disabled_settings, + ]; + + yield 'variable set to zero' => [ + ['DRUPAL_REDIS_ENABLED' => '0', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], + FALSE, + $disabled_settings, + ]; - $this->assertSettingsContains($settings); + yield 'variable set to a non-numeric truthy value' => [ + ['DRUPAL_REDIS_ENABLED' => 'true', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], + FALSE, + $disabled_settings, + ]; } // phpcs:ignore #;> SERVICE_CACHE @@ -658,7 +689,7 @@ public static function dataProviderShield(): \Iterator { 'DRUPAL_SHIELD_DISABLED' => 'false', ], [ - 'shield.settings' => ['shield_enable' => FALSE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], + 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], ], ]; yield [ @@ -670,7 +701,19 @@ public static function dataProviderShield(): \Iterator { 'DRUPAL_SHIELD_DISABLED' => 'true', ], [ - 'shield.settings' => ['shield_enable' => FALSE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], + 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], + ], + ]; + yield [ + self::ENVIRONMENT_DEV, + [ + 'DRUPAL_SHIELD_USER' => 'drupal_shield_user', + 'DRUPAL_SHIELD_PASS' => 'drupal_shield_pass', + 'DRUPAL_SHIELD_PRINT' => 'drupal_shield_print', + 'DRUPAL_SHIELD_DISABLED' => '01', + ], + [ + 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], ], ]; @@ -785,6 +828,24 @@ public static function dataProviderShield(): \Iterator { 'shield.settings' => ['method' => NULL, 'paths' => NULL], ], ]; + // ACME challenge with a non-numeric truthy value - should not set. + yield [ + self::ENVIRONMENT_DEV, + [ + 'DRUPAL_SHIELD_USER' => 'drupal_shield_user', + 'DRUPAL_SHIELD_PASS' => 'drupal_shield_pass', + 'DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE' => 'true', + ], + [ + 'shield.settings' => [ + 'shield_enable' => TRUE, + 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], + ], + ], + [ + 'shield.settings' => ['method' => NULL, 'paths' => NULL], + ], + ]; yield [ self::ENVIRONMENT_DEV, @@ -993,6 +1054,18 @@ public static function dataProviderRerouteEmail(): \Iterator { 'reroute_email.settings' => ['enable' => FALSE], ], ]; + + // DRUPAL_REROUTE_EMAIL_DISABLED with a non-numeric truthy value: not + // disabled. + yield [ + self::ENVIRONMENT_DEV, + [ + 'DRUPAL_REROUTE_EMAIL_DISABLED' => 'true', + ], + [ + 'reroute_email.settings' => ['enable' => TRUE], + ], + ]; } // phpcs:ignore #;> MODULE_REROUTE_EMAIL diff --git a/web/sites/default/includes/modules/settings.clamav.php b/web/sites/default/includes/modules/settings.clamav.php index 31c129f2b1..d3996264f4 100644 --- a/web/sites/default/includes/modules/settings.clamav.php +++ b/web/sites/default/includes/modules/settings.clamav.php @@ -7,7 +7,7 @@ declare(strict_types=1); -if (file_exists($contrib_path . '/clamav') && !empty(getenv('DRUPAL_CLAMAV_ENABLED'))) { +if (getenv('DRUPAL_CLAMAV_ENABLED') === '1') { $clamav_mode = getenv('DRUPAL_CLAMAV_MODE') ?: NULL; if (in_array(strtolower((string) $clamav_mode), ['0', 'daemon'], TRUE)) { // Drupal\clamav\Config::MODE_DAEMON. diff --git a/web/sites/default/includes/modules/settings.redis.php b/web/sites/default/includes/modules/settings.redis.php index 6871347e44..f6e5612e5f 100644 --- a/web/sites/default/includes/modules/settings.redis.php +++ b/web/sites/default/includes/modules/settings.redis.php @@ -26,7 +26,7 @@ // variables would need to be removed. The next deployment (#3) would use // project-wide env variable (and since it has the same value '1' as removed // per-env variable - there will be no change in how code works). -if (file_exists($contrib_path . '/redis') && !empty(getenv('DRUPAL_REDIS_ENABLED'))) { +if (file_exists($contrib_path . '/redis') && getenv('DRUPAL_REDIS_ENABLED') === '1') { // Some providers use `REDIS_`-prefixed environment variables. $settings['redis.connection']['host'] = getenv('REDIS_HOST') ?: 'cache'; $settings['redis.connection']['port'] = getenv('REDIS_SERVICE_PORT') ?: '6379'; diff --git a/web/sites/default/includes/modules/settings.reroute_email.php b/web/sites/default/includes/modules/settings.reroute_email.php index 5408b1c8a6..6d5f5a8de4 100644 --- a/web/sites/default/includes/modules/settings.reroute_email.php +++ b/web/sites/default/includes/modules/settings.reroute_email.php @@ -31,7 +31,7 @@ } // Allow an environment to opt out of the rerouting set above. -if (!empty(getenv('DRUPAL_REROUTE_EMAIL_DISABLED'))) { +if (getenv('DRUPAL_REROUTE_EMAIL_DISABLED') === '1') { // Deliver every message to its intended recipient. $config['reroute_email.settings']['enable'] = FALSE; } diff --git a/web/sites/default/includes/modules/settings.shield.php b/web/sites/default/includes/modules/settings.shield.php index 36bbbba2df..acc592a0ce 100644 --- a/web/sites/default/includes/modules/settings.shield.php +++ b/web/sites/default/includes/modules/settings.shield.php @@ -33,23 +33,26 @@ } // Set credentials, but only if the environment variables are present. -if (!empty(getenv('DRUPAL_SHIELD_USER')) && !empty(getenv('DRUPAL_SHIELD_PASS'))) { - $config['shield.settings']['credentials']['shield']['user'] = getenv('DRUPAL_SHIELD_USER'); - $config['shield.settings']['credentials']['shield']['pass'] = getenv('DRUPAL_SHIELD_PASS'); +$shield_user = getenv('DRUPAL_SHIELD_USER'); +$shield_pass = getenv('DRUPAL_SHIELD_PASS'); +if (!empty($shield_user) && !empty($shield_pass)) { + $config['shield.settings']['credentials']['shield']['user'] = $shield_user; + $config['shield.settings']['credentials']['shield']['pass'] = $shield_pass; } // Allow to override the title of the shield pop-up. -if (getenv('DRUPAL_SHIELD_PRINT')) { - $config['shield.settings']['print'] = getenv('DRUPAL_SHIELD_PRINT'); +$shield_print = getenv('DRUPAL_SHIELD_PRINT'); +if (!empty($shield_print)) { + $config['shield.settings']['print'] = $shield_print; } // Allow to disable Shield completely in the environment. -if (!empty(getenv('DRUPAL_SHIELD_DISABLED'))) { +if (getenv('DRUPAL_SHIELD_DISABLED') === '1') { $config['shield.settings']['shield_enable'] = FALSE; } // Allow ACME challenge path for Let's Encrypt certificate generation. -if (!empty(getenv('DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE'))) { +if (getenv('DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE') === '1') { $config['shield.settings']['method'] = 0; $shield_acme_path = '/.well-known/acme-challenge/*'; $shield_existing_paths = $config['shield.settings']['paths'] ?? ''; From 81a164e1687944c6cfe715e676001f3745318838 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:05:41 +1100 Subject: [PATCH 55/71] [#3105] Matched the prod domain placeholder case in the Acquia purge-cache task. Forward-ported from main 68a6a1b92b4bdf10f237a4f1909e01a18c9fec68. Added the bare uppercase '$TARGET_ENV_REMAP' and '$TARGET_ENV' placeholders to the PHP prod strip and interpolation, keeping the lowercase forms, and ported the BATS cases as a 'TaskPurgeCacheAcquiaTest' data provider. --- .../src/vortex-task-purge-cache-acquia | 4 ++ .../tests/Unit/TaskPurgeCacheAcquiaTest.php | 51 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/.vortex/tooling/src/vortex-task-purge-cache-acquia b/.vortex/tooling/src/vortex-task-purge-cache-acquia index 8191bd058a..68c08288e4 100755 --- a/.vortex/tooling/src/vortex-task-purge-cache-acquia +++ b/.vortex/tooling/src/vortex-task-purge-cache-acquia @@ -47,6 +47,8 @@ function purge_interpolate_domain(string $domain, string $target_env): ?string { if ($target_env === 'prod') { $domain = str_replace('$target_env_remap.', '', $domain); $domain = str_replace('$target_env.', '', $domain); + $domain = str_replace('$TARGET_ENV_REMAP.', '', $domain); + $domain = str_replace('$TARGET_ENV.', '', $domain); return $domain; } @@ -64,6 +66,8 @@ function purge_interpolate_domain(string $domain, string $target_env): ?string { // Interpolate variables in domain name. $domain = str_replace('$target_env_remap', $target_env_remap, $domain); $domain = str_replace('$target_env', $target_env, $domain); + $domain = str_replace('$TARGET_ENV_REMAP', $target_env_remap, $domain); + $domain = str_replace('$TARGET_ENV', $target_env, $domain); $domain = str_replace('${target_env_remap}', $target_env_remap, $domain); $domain = str_replace('${target_env}', $target_env, $domain); $domain = str_replace('${TARGET_ENV_REMAP}', $target_env_remap, $domain); diff --git a/.vortex/tooling/tests/Unit/TaskPurgeCacheAcquiaTest.php b/.vortex/tooling/tests/Unit/TaskPurgeCacheAcquiaTest.php index e1319d6fea..87d744a523 100644 --- a/.vortex/tooling/tests/Unit/TaskPurgeCacheAcquiaTest.php +++ b/.vortex/tooling/tests/Unit/TaskPurgeCacheAcquiaTest.php @@ -4,6 +4,7 @@ namespace DrevOps\VortexTooling\Tests\Unit; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; @@ -186,6 +187,56 @@ public function testTestEnvRemapsToStage(): void { $this->assertStringContainsString('Finished cache purging in Acquia.', $output); } + #[DataProvider('dataProviderTemplatePlaceholder')] + public function testTemplatePlaceholder(string $env, string $domain_line, string $expected_domain): void { + $this->mockSleep(); + $this->envSet('VORTEX_TASK_PURGE_CACHE_ACQUIA_ENV', $env); + + file_put_contents(self::$tmp . '/domains.txt', $domain_line . "\n"); + + $this->mockRequestMultiple([ + [ + 'url' => 'https://accounts.acquia.com/api/auth/oauth/token', + 'response' => ['body' => json_encode(['access_token' => 'test-token'])], + ], + [ + 'url' => 'https://cloud.acquia.com/api/applications?filter=name%3Dmyapp', + 'response' => ['body' => json_encode(['_embedded' => ['items' => [['uuid' => 'app-uuid-123']]]])], + ], + [ + 'url' => 'https://cloud.acquia.com/api/applications/app-uuid-123/environments?filter=name%3D' . $env, + 'response' => ['body' => json_encode(['_embedded' => ['items' => [['id' => 'env-id-' . $env]]]])], + ], + [ + 'url' => 'https://cloud.acquia.com/api/environments/env-id-' . $env . '/domains/actions/clear-varnish', + 'response' => ['body' => json_encode(['_links' => ['notification' => ['href' => 'https://cloud.acquia.com/api/notifications/purge-1']]])], + ], + [ + 'url' => 'https://cloud.acquia.com/api/notifications/purge-1', + 'response' => ['body' => json_encode(['status' => 'completed'])], + ], + ]); + + $output = $this->runScript('src/vortex-task-purge-cache-acquia'); + + $this->assertSame(json_encode(['domains' => [$expected_domain]]), $this->getMockRequestBody(3)); + $this->assertStringContainsString(sprintf('Purged cache for %s environment domain %s.', $env, $expected_domain), $output); + $this->assertStringNotContainsString('$', $output); + $this->assertStringContainsString('Finished cache purging in Acquia.', $output); + } + + public static function dataProviderTemplatePlaceholder(): array { + return [ + 'prod, remap placeholder' => ['prod', '$TARGET_ENV_REMAP.your-site-domain.example', 'your-site-domain.example'], + 'prod, env placeholder' => ['prod', '$TARGET_ENV.your-site-domain.example', 'your-site-domain.example'], + 'dev, remap placeholder' => ['dev', '$TARGET_ENV_REMAP.your-site-domain.example', 'dev.your-site-domain.example'], + 'dev, env placeholder' => ['dev', '$TARGET_ENV.your-site-domain.example', 'dev.your-site-domain.example'], + 'test, remap placeholder' => ['test', '$TARGET_ENV_REMAP.your-site-domain.example', 'stage.your-site-domain.example'], + 'test, env placeholder' => ['test', '$TARGET_ENV.your-site-domain.example', 'test.your-site-domain.example'], + 'test2, remap placeholder' => ['test2', '$TARGET_ENV_REMAP.your-site-domain.example', 'test2.your-site-domain.example'], + ]; + } + public function testDomainPurgeWarning(): void { $this->mockSleep(); From 563c273cc8d9d22d7dc0c0ef1461e9d897d20abc Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:09:04 +1100 Subject: [PATCH 56/71] [#3135] Added an opt-in check that fails provisioning when post-provision operations change configuration. Forward-ported from main fce3081dd4f39a18abdb8ccdd71fad5d0a73dc20. Re-implemented the check in the PHP 'vortex-provision' after maintenance mode is disabled, using the 'drush()' helper inside a 'TASK()', ported the BATS cases as a 'ProvisionTest' data provider and described deploy steps instead of custom provision scripts. --- .env | 6 + .../docs/content/development/provision.mdx | 6 +- .../docs/content/development/variables.mdx | 1 + .../Traits/Subtests/SubtestAhoyTrait.php | 12 ++ .vortex/tooling/src/vortex-provision | 24 +++ .vortex/tooling/tests/Unit/ProvisionTest.php | 166 ++++++++++++++++++ 6 files changed, 214 insertions(+), 1 deletion(-) diff --git a/.env b/.env index 3bb086a835..9c19836bd8 100644 --- a/.env +++ b/.env @@ -141,6 +141,12 @@ VORTEX_PROVISION_FALLBACK_TO_PROFILE=0 # drush config:import from silently overwriting those changes. VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_UPDATE=0 +# Verify that configuration was not changed by post-provision operations. +# If enabled and config files are present, the provision will fail if any +# active configuration item differs from the exported configuration once +# configuration imports, deployment hooks and deploy steps have run. +VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION=0 + #;< !PROVISION_TYPE_PROFILE # Skip database sanitization. # diff --git a/.vortex/docs/content/development/provision.mdx b/.vortex/docs/content/development/provision.mdx index 9b231fbef7..441005baa9 100644 --- a/.vortex/docs/content/development/provision.mdx +++ b/.vortex/docs/content/development/provision.mdx @@ -90,6 +90,9 @@ section. ▼ ⑥ 🚧 Disable maintenance mode ▼ +⑪ 💡 Verify config unchanged? ──Config changed──► 🏁 EXIT 1 (fail) ✗ + │ Config unchanged (or check disabled) + ▼ 🏁 End ``` @@ -106,7 +109,8 @@ You can control the provisioning flow using the following environment variables: 7. `VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_UPDATE=1`
Verify that active configuration was not changed by database updates. When enabled and config files are present, the provision will fail if `drush updatedb` modifies active configuration, preventing `drush config:import` from silently overwriting those changes.

8. `VORTEX_PROVISION_CACHE_REBUILD_AFTER_DB_UPDATE_SKIP=1`
Skip the cache rebuild that runs between database updates and configuration import. By default, caches are rebuilt after `drush updatedb` to ensure a clean state before importing configuration.

9. `VORTEX_PROVISION_CONFIG_IMPORT_REPEAT=1`
Repeat the configuration import after the initial import. Useful when database update hooks introduce new configuration that affects subsequent configuration imports (e.g., new config_split settings). Disabled by default.

-10. `VORTEX_PROVISION_SANITIZE_DB_SKIP=1`
Disable database sanitization. +10. `VORTEX_PROVISION_SANITIZE_DB_SKIP=1`
Disable database sanitization.

+11. `VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION=1`
Verify that the post-provision operations left active configuration unchanged. When config files are present, the check runs `drush config:status` after the configuration imports, deployment hooks and deploy steps. Provisioning fails if any configuration item is in the `Different` state. Items that exist only in the database or only in the sync directory pass the check. :::tip diff --git a/.vortex/docs/content/development/variables.mdx b/.vortex/docs/content/development/variables.mdx index ee7e937ae4..3d4017b6d5 100644 --- a/.vortex/docs/content/development/variables.mdx +++ b/.vortex/docs/content/development/variables.mdx @@ -244,6 +244,7 @@ The list below is automatically generated with [Shellvar](https://github.com/ale | `VORTEX_PROVISION_SANITIZE_DB_SKIP` | Skip database sanitization.

Database sanitization is enabled by default in all non-production environments and is always skipped in the production environment. @see https://www.vortextemplate.com/docs/development/provision#database-sanitization | `UNDEFINED` | `.env` | | `VORTEX_PROVISION_TYPE` | Set to 'profile' to install a site from profile instead of the database dump. | `database` | `.env` | | `VORTEX_PROVISION_USE_MAINTENANCE_MODE` | Put the site into a maintenance mode during site provisioning. | `1` | `.env` | +| `VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION` | Verify that configuration was not changed by post-provision operations. If enabled and config files are present, the provision will fail if any active configuration item differs from the exported configuration once configuration imports, deployment hooks and deploy steps have run. | `UNDEFINED` | `.env` | | `VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_UPDATE` | Verify that configuration was not changed by database updates. If enabled and config files are present, the provision will fail if database update hooks modify active configuration, preventing drush config:import from silently overwriting those changes. | `UNDEFINED` | `.env` | | `VORTEX_PURGE_CACHE_ACQUIA_SKIP` | Skip purging of edge cache in Acquia environment. | `UNDEFINED` | `ACQUIA ENVIRONMENT` | | `VORTEX_RELEASE_VERSION_SCHEME` | Versioning scheme used for releases.

Can be one of: calver, semver, other @see https://www.vortextemplate.com/docs/releasing | `calver` | `.env` | diff --git a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php index 420bec9cde..3cee8c474e 100644 --- a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php +++ b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php @@ -311,6 +311,18 @@ protected function subtestAhoyProvision(): void { $this->cmd('ahoy drush config:status', '! Different', 'Config files should match the DB'); + $this->logSubstep('Run provision with the post-provision configuration check enabled'); + + $this->cmd( + 'ahoy provision', + [ + '* Verify config after provision : Yes', + '* Verified that post-provision operations did not change configuration.', + ], + 'Provision should report that post-provision operations left configuration unchanged', + env: ['VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION' => '1'] + ); + $this->logSubstep('Run provision with exported config files different to DB'); $this->logNote('Make a change to the configuration.'); diff --git a/.vortex/tooling/src/vortex-provision b/.vortex/tooling/src/vortex-provision index c7851f2acf..d4103c023d 100755 --- a/.vortex/tooling/src/vortex-provision +++ b/.vortex/tooling/src/vortex-provision @@ -69,6 +69,13 @@ $provision_post_operations_skip = getenv_default('VORTEX_PROVISION_POST_OPERATIO // drush config:import from silently overwriting those changes. $provision_verify_config = getenv_default('VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_UPDATE', '0'); +// Verify that configuration was not changed by post-provision operations. +// +// If enabled and config files are present, the provision will fail if any +// active configuration item differs from the exported configuration once +// configuration imports, deployment hooks and deploy steps have run. +$provision_verify_config_after_provision = getenv_default('VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION', '0'); + // Skip cache rebuild after database updates. $provision_cache_rebuild_after_db_update_skip = getenv_default('VORTEX_PROVISION_CACHE_REBUILD_AFTER_DB_UPDATE_SKIP', '0'); @@ -454,6 +461,7 @@ NOTE('Overwrite existing DB : %s', yesno($provision_override_db)); NOTE('Skip DB sanitization : %s', yesno($provision_sanitize_db_skip)); NOTE('Skip post-provision operations : %s', yesno($provision_post_operations_skip)); NOTE('Verify config after update : %s', yesno($provision_verify_config)); +NOTE('Verify config after provision : %s', yesno($provision_verify_config_after_provision)); NOTE('Use maintenance mode : %s', yesno($provision_use_maintenance_mode)); echo PHP_EOL; @@ -731,6 +739,22 @@ if ($provision_use_maintenance_mode === '1') { echo PHP_EOL; } +// Only the 'Different' state is checked: a site may legitimately carry +// configuration that exists only in the database or only in the sync directory. +if ($provision_verify_config_after_provision === '1' && $site_has_config_files) { + TASK('Verifying that configuration was not changed by post-provision operations.', 'Verified that post-provision operations did not change configuration.', function (): void { + $config_status = trim(drush('config:status --state=Different --format=list')); + + if ($config_status !== '') { + NOTE('The following configuration items differ from the exported configuration:'); + echo $config_status . PHP_EOL; + NOTE('Review the changes and export the updated configuration.'); + throw new \RuntimeException('Configuration was changed by post-provision operations.'); + } + }); + echo PHP_EOL; +} + $duration = time() - $start_time; INFO('Finished site provisioning (%dm %ds).', (int) floor($duration / 60), $duration % 60); diff --git a/.vortex/tooling/tests/Unit/ProvisionTest.php b/.vortex/tooling/tests/Unit/ProvisionTest.php index e17be0b43d..96bc397554 100644 --- a/.vortex/tooling/tests/Unit/ProvisionTest.php +++ b/.vortex/tooling/tests/Unit/ProvisionTest.php @@ -4,7 +4,9 @@ namespace DrevOps\VortexTooling\Tests\Unit; +use DrevOps\VortexTooling\Tests\Exceptions\QuitErrorException; use DrevOps\VortexTooling\Tests\Exceptions\QuitSuccessException; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; @@ -29,6 +31,7 @@ protected function setUp(): void { 'VORTEX_PROVISION_USE_MAINTENANCE_MODE' => '0', 'VORTEX_PROVISION_POST_OPERATIONS_SKIP' => '1', 'VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_UPDATE' => '0', + 'VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION' => '0', 'VORTEX_PROVISION_DB' => '', 'VORTEX_PROVISION_SCRIPTS_DIR' => '/tmp/nonexistent-custom-scripts', 'WEBROOT' => 'web', @@ -616,6 +619,169 @@ public function testSummaryOutputIncludesNewVariables(): void { $this->assertStringContainsString('Verify config after update : Yes', $output); } + #[DataProvider('dataProviderVerifyConfigAfterProvision')] + public function testVerifyConfigAfterProvision(string $verify, bool $has_config, ?string $config_status_output, array $expected, array $not_expected, bool $expect_error = FALSE): void { + $this->createDbDumpFile(); + + $this->envSetMultiple([ + 'VORTEX_PROVISION_POST_OPERATIONS_SKIP' => '0', + 'VORTEX_PROVISION_USE_MAINTENANCE_MODE' => '1', + 'VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION' => $verify, + ]); + + if ($has_config) { + $this->mockDrushStartupSequenceWithConfig(TRUE); + } + else { + $this->mockDrushStartupSequence(TRUE); + } + + // Drush php:eval (environment). + $this->mockPassthru([ + 'cmd' => $this->drushCmd("php:eval \"print \\Drupal\\Core\\Site\\Settings::get('environment');\""), + 'output' => 'production', + 'result_code' => 0, + ]); + + // Drush maint:set 1. + $this->mockPassthru([ + 'cmd' => $this->drushCmd('maint:set 1'), + 'result_code' => 0, + ]); + + if ($has_config) { + // Drush config-set system.site uuid. + $this->mockPassthru([ + 'cmd' => $this->drushCmd("config-set system.site uuid 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'"), + 'result_code' => 0, + ]); + } + + // Drush updatedb. + $this->mockPassthru([ + 'cmd' => $this->drushCmd('updatedb --no-cache-clear'), + 'result_code' => 0, + ]); + + // Drush cache:rebuild (after database updates). + $this->mockPassthru([ + 'cmd' => $this->drushCmd('cache:rebuild'), + 'result_code' => 0, + ]); + + if ($has_config) { + // Drush config:import. + $this->mockPassthru([ + 'cmd' => $this->drushCmd('config:import'), + 'result_code' => 0, + ]); + + // Drush pm:list (config_split check) - module not enabled. + $this->mockPassthru([ + 'cmd' => $this->drushCmd('pm:list --status=enabled'), + 'output' => '', + 'result_code' => 0, + ]); + } + + // Drush cache:rebuild (post-provision). + $this->mockPassthru([ + 'cmd' => $this->drushCmd('cache:rebuild'), + 'result_code' => 0, + ]); + + // Drush pm:install deploy_steps. + $this->mockPassthru([ + 'cmd' => $this->drushCmd('pm:install deploy_steps'), + 'result_code' => 0, + ]); + + // Drush deploy:hook. + $this->mockPassthru([ + 'cmd' => $this->drushCmd('deploy:hook'), + 'result_code' => 0, + ]); + + // Drush maint:set 0. + $this->mockPassthru([ + 'cmd' => $this->drushCmd('maint:set 0'), + 'result_code' => 0, + ]); + + if ($config_status_output !== NULL) { + // Drush config:status (post-provision verification). + $this->mockPassthru([ + 'cmd' => $this->drushCmd('config:status --state=Different --format=list'), + 'output' => $config_status_output, + 'result_code' => 0, + ]); + } + + $this->mockQuit($expect_error ? 1 : 0); + + $output = ''; + try { + $this->runScript('src/vortex-provision'); + $this->fail('Expected the script to quit.'); + } + catch (QuitSuccessException | QuitErrorException $e) { + $output = $e->getOutput(); + } + + foreach ($expected as $string) { + $this->assertStringContainsString($string, $output); + } + foreach ($not_expected as $string) { + $this->assertStringNotContainsString($string, $output); + } + } + + public static function dataProviderVerifyConfigAfterProvision(): array { + return [ + 'disabled' => [ + '0', + TRUE, + NULL, + ['Verify config after provision : No', 'Disabled maintenance mode.', 'Finished site provisioning'], + ['Verifying that configuration was not changed by post-provision operations.'], + ], + 'enabled, configuration unchanged' => [ + '1', + TRUE, + '', + [ + 'Verify config after provision : Yes', + 'Verifying that configuration was not changed by post-provision operations.', + 'Verified that post-provision operations did not change configuration.', + 'Finished site provisioning', + ], + ['Configuration was changed by post-provision operations.'], + ], + 'enabled, configuration different' => [ + '1', + TRUE, + "core.extension\nviews.view.content\n", + [ + 'Verify config after provision : Yes', + 'Verifying that configuration was not changed by post-provision operations.', + 'The following configuration items differ from the exported configuration:', + "core.extension\nviews.view.content", + 'Review the changes and export the updated configuration.', + 'Configuration was changed by post-provision operations.', + ], + ['Verified that post-provision operations did not change configuration.', 'Finished site provisioning'], + TRUE, + ], + 'enabled, no configuration files' => [ + '1', + FALSE, + NULL, + ['Verify config after provision : Yes', 'Disabled maintenance mode.', 'Finished site provisioning'], + ['Verifying that configuration was not changed by post-provision operations.'], + ], + ]; + } + public function testProvisionDbDirFallback(): void { $this->envSetMultiple([ 'VORTEX_PROVISION_DB_DIR' => '', From 183fcc975a929809362b477d47172ea300563e51 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:10:44 +1100 Subject: [PATCH 57/71] [#3169] Made 'webserver' start after 'appserver' and corrected the SSH agent recovery advice in 'vortex-doctor'. Forward-ported from main ec0f814593675ec8f5367cc35aa2d0feb2a5c2b5. Applied the change to the renamed 'webserver' and 'appserver' services and their harness fixtures, updated the PHP 'vortex-doctor' messages with negative assertions in 'DoctorTest' that already covers main's new SSH cases, and ported the Pygmy SSH key docs section. --- .../content/development/environment/pygmy.mdx | 22 +++++++++++++++++++ .../phpunit/Fixtures/docker-compose.env.json | 4 ++++ .../Fixtures/docker-compose.env_local.json | 4 ++++ .../Fixtures/docker-compose.env_mod.json | 4 ++++ .../Fixtures/docker-compose.noenv.json | 4 ++++ .vortex/tooling/src/vortex-doctor | 4 ++-- .vortex/tooling/tests/Unit/DoctorTest.php | 6 +++-- docker-compose.yml | 1 + 8 files changed, 45 insertions(+), 4 deletions(-) diff --git a/.vortex/docs/content/development/environment/pygmy.mdx b/.vortex/docs/content/development/environment/pygmy.mdx index 05a3eab2c8..1accd912a7 100644 --- a/.vortex/docs/content/development/environment/pygmy.mdx +++ b/.vortex/docs/content/development/environment/pygmy.mdx @@ -36,3 +36,25 @@ pygmy restart # Restart the services. pygmy status # Show the status of the services. pygmy clean # Stop and remove all services. Useful if you have issues with pygmy. ``` + +## SSH key in the CLI container + +The CLI container uses the SSH agent from Pygmy's `amazeeio-ssh-agent` +container. It mounts the agent's volume through `volumes_from` and links to the +agent's socket only when the CLI container starts. + +`pygmy restart` removes the agent container and creates a new one. A CLI +container that is running at the time stays attached to the previous agent, so +the SSH key is no longer available inside it. The same happens when the stack +starts before Pygmy. + +Recreate the CLI container to attach it to the current agent: + +```shell +ahoy up --no-deps --force-recreate cli +``` + +Running `ahoy up` on its own leaves a running container in place when its +configuration is unchanged. [`ahoy doctor`](doctor.mdx) checks that the SSH key +is available in the CLI container and prints the recreate command when it +isn't. diff --git a/.vortex/tests/phpunit/Fixtures/docker-compose.env.json b/.vortex/tests/phpunit/Fixtures/docker-compose.env.json index c4beb89047..f6f6591799 100644 --- a/.vortex/tests/phpunit/Fixtures/docker-compose.env.json +++ b/.vortex/tests/phpunit/Fixtures/docker-compose.env.json @@ -522,6 +522,10 @@ }, "command": null, "depends_on": { + "appserver": { + "condition": "service_started", + "required": true + }, "cli": { "condition": "service_started", "required": true diff --git a/.vortex/tests/phpunit/Fixtures/docker-compose.env_local.json b/.vortex/tests/phpunit/Fixtures/docker-compose.env_local.json index c4beb89047..f6f6591799 100644 --- a/.vortex/tests/phpunit/Fixtures/docker-compose.env_local.json +++ b/.vortex/tests/phpunit/Fixtures/docker-compose.env_local.json @@ -522,6 +522,10 @@ }, "command": null, "depends_on": { + "appserver": { + "condition": "service_started", + "required": true + }, "cli": { "condition": "service_started", "required": true diff --git a/.vortex/tests/phpunit/Fixtures/docker-compose.env_mod.json b/.vortex/tests/phpunit/Fixtures/docker-compose.env_mod.json index ecf8d36313..471b8c9911 100644 --- a/.vortex/tests/phpunit/Fixtures/docker-compose.env_mod.json +++ b/.vortex/tests/phpunit/Fixtures/docker-compose.env_mod.json @@ -522,6 +522,10 @@ }, "command": null, "depends_on": { + "appserver": { + "condition": "service_started", + "required": true + }, "cli": { "condition": "service_started", "required": true diff --git a/.vortex/tests/phpunit/Fixtures/docker-compose.noenv.json b/.vortex/tests/phpunit/Fixtures/docker-compose.noenv.json index acf41cf948..192cde0500 100644 --- a/.vortex/tests/phpunit/Fixtures/docker-compose.noenv.json +++ b/.vortex/tests/phpunit/Fixtures/docker-compose.noenv.json @@ -522,6 +522,10 @@ }, "command": null, "depends_on": { + "appserver": { + "condition": "service_started", + "required": true + }, "cli": { "condition": "service_started", "required": true diff --git a/.vortex/tooling/src/vortex-doctor b/.vortex/tooling/src/vortex-doctor index 618bfd5f3f..dfa0516780 100755 --- a/.vortex/tooling/src/vortex-doctor +++ b/.vortex/tooling/src/vortex-doctor @@ -166,7 +166,7 @@ if ($check_ssh === '1') { $ssh_key_added_to_pygmy = (bool) TASK('Checking that the SSH key is added to pygmy.', 'SSH key is added to pygmy.', function () use ($ssh_file): bool { $status = str_replace("\0", '', (string) shell_exec('pygmy status 2>&1')); if (!str_contains($status, $ssh_file)) { - NOTE("The SSH key will not be available in the CLI container. Run 'pygmy restart' and then 'ahoy up'."); + NOTE("The SSH key will not be available in the CLI container. Run 'pygmy restart' and then 'ahoy up --no-deps --force-recreate cli'."); throw new \RuntimeException('SSH key is not added to pygmy.'); } @@ -192,7 +192,7 @@ if ($check_ssh === '1') { TASK('Checking that the SSH key is available within the CLI container.', 'SSH key is available within the CLI container.', function (): void { passthru("docker compose exec -T cli bash -c \"ssh-add -L | grep -q 'ssh-rsa'\"", $exit_code); if ($exit_code !== 0) { - throw new \RuntimeException("SSH key was not added to the container. Run 'pygmy restart'."); + throw new \RuntimeException("SSH key was not added to the container. Run 'ahoy up --no-deps --force-recreate cli'."); } }, fatal: FALSE); } diff --git a/.vortex/tooling/tests/Unit/DoctorTest.php b/.vortex/tooling/tests/Unit/DoctorTest.php index 607987b741..21d5d38f27 100644 --- a/.vortex/tooling/tests/Unit/DoctorTest.php +++ b/.vortex/tooling/tests/Unit/DoctorTest.php @@ -294,7 +294,8 @@ public static function dataProviderDoctor(): array { [ '* [INFO] Checking project requirements.', '* [FAIL] SSH key is not added to pygmy.', - "* The SSH key will not be available in the CLI container. Run 'pygmy restart' and then 'ahoy up'.", + "* The SSH key will not be available in the CLI container. Run 'pygmy restart' and then 'ahoy up --no-deps --force-recreate cli'.", + "! and then 'ahoy up'.", '! [ OK ] SSH key is available within the CLI container.', '* [ OK ] All required checks have passed.', ], @@ -326,7 +327,8 @@ public static function dataProviderDoctor(): array { [$ssh_pygmy_status(TRUE), $ssh_volume_cmd(0), $ssh_key_cmd(1)], [ '* [INFO] Checking project requirements.', - "* [FAIL] SSH key was not added to the container. Run 'pygmy restart'.", + "* [FAIL] SSH key was not added to the container. Run 'ahoy up --no-deps --force-recreate cli'.", + "! Run 'pygmy restart'.", '! [ OK ] SSH key is available within the CLI container.', '* [ OK ] All required checks have passed.', ], diff --git a/docker-compose.yml b/docker-compose.yml index 1ad79961ea..9e6dc2233d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -153,6 +153,7 @@ services: <<: [ *default-volumes, *default-user ] depends_on: - cli + - appserver networks: - default # This is a standard network and is used for all other environments, where requests routing is not required and/or not supported. - amazeeio-network ### This network is supported by Pygmy and used to route all requests to host machine locally. Removed in CI. From 9696f67f27da8f9260f339f3c2502317850aadd2 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:11:46 +1100 Subject: [PATCH 58/71] Switched artifact deployments to the development version of 'git-artifact' and its '--source' option. Forward-ported from main ab399361622cd0ba8962ea13a6678fe4606d88bb. Applied the 1.8.0 version, checksum and '--source' option to the PHP 'vortex-deploy-artifact' and 'DeployArtifactTest'; the 2.x variables table does not list tooling script variables, so 'update-docs' produced no change. --- .vortex/docs/content/deployment/artifact.mdx | 2 +- .vortex/tooling/src/vortex-deploy-artifact | 6 +++--- .../tooling/tests/Unit/DeployArtifactTest.php | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.vortex/docs/content/deployment/artifact.mdx b/.vortex/docs/content/deployment/artifact.mdx index 352e20688e..26194a14fe 100644 --- a/.vortex/docs/content/deployment/artifact.mdx +++ b/.vortex/docs/content/deployment/artifact.mdx @@ -85,7 +85,7 @@ with a SHA256 checksum before execution. The version and checksum are controlled by: -- `VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_VERSION`: Version to download (default: `1.7.0`). +- `VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_VERSION`: Version to download (default: `1.8.0`). - `VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_SHA256`: Expected SHA256 checksum of the binary. ### Stale branch cleanup diff --git a/.vortex/tooling/src/vortex-deploy-artifact b/.vortex/tooling/src/vortex-deploy-artifact index 6b8176580d..a62f2e372d 100755 --- a/.vortex/tooling/src/vortex-deploy-artifact +++ b/.vortex/tooling/src/vortex-deploy-artifact @@ -62,10 +62,10 @@ $deploy_ssh_fingerprint = getenv_default('VORTEX_DEPLOY_ARTIFACT_SSH_FINGERPRINT $deploy_ssh_file = getenv_default('VORTEX_DEPLOY_ARTIFACT_SSH_FILE', 'VORTEX_DEPLOY_SSH_FILE', 'VORTEX_SSH_FILE', getenv('HOME') . '/.ssh/id_rsa'); // Version of git-artifact to download. -$git_artifact_version = getenv_default('VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_VERSION', '1.7.0'); +$git_artifact_version = getenv_default('VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_VERSION', '1.8.0'); // SHA256 checksum of the git-artifact binary. -$git_artifact_sha256 = getenv_default('VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_SHA256', 'bff9d061fb757051366d650c35e367d9b024b7146e22fbd831c734ff88f4af4d'); +$git_artifact_sha256 = getenv_default('VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_SHA256', '31133d0d7887388501ecc407179325e2ad4b21cfb7ac9c7f4e6aecb991977d9d'); // Remote branches eligible for stale branch cleanup after a successful push: // comma-separated globs (e.g. "feature/*,bugfix/*") or a single regex literal. @@ -162,7 +162,7 @@ TASK('Running artifact builder.', 'Finished artifact deployment.', function () u escapeshellarg($git_artifact_bin), escapeshellarg($deploy_git_remote), '--root=' . escapeshellarg($deploy_artifact_root), - '--src=' . escapeshellarg($deploy_artifact_src), + '--source=' . escapeshellarg($deploy_artifact_src), '--branch=' . escapeshellarg($deploy_artifact_dst_branch), '--gitignore=' . escapeshellarg($deploy_artifact_src . '/.gitignore.artifact'), '--log=' . escapeshellarg($deploy_artifact_log), diff --git a/.vortex/tooling/tests/Unit/DeployArtifactTest.php b/.vortex/tooling/tests/Unit/DeployArtifactTest.php index 781ea2dc81..f7ce1102f8 100644 --- a/.vortex/tooling/tests/Unit/DeployArtifactTest.php +++ b/.vortex/tooling/tests/Unit/DeployArtifactTest.php @@ -73,7 +73,7 @@ public function testDefaultValues(): void { // Mock git-artifact command. $git_artifact_cmd = sprintf( - '%s %s --root=%s --src=%s --branch=%s --gitignore=%s --log=%s -vvv', + '%s %s --root=%s --source=%s --branch=%s --gitignore=%s --log=%s -vvv', escapeshellarg($this->getGitArtifactBinPath()), escapeshellarg('git@github.com:org/repo.git'), escapeshellarg(self::$tmp . '/root'), @@ -130,7 +130,7 @@ public function testConfigureGitUser(): void { // Mock git-artifact command. $git_artifact_cmd = sprintf( - '%s %s --root=%s --src=%s --branch=%s --gitignore=%s --log=%s -vvv', + '%s %s --root=%s --source=%s --branch=%s --gitignore=%s --log=%s -vvv', escapeshellarg($this->getGitArtifactBinPath()), escapeshellarg('git@github.com:org/repo.git'), escapeshellarg(self::$tmp . '/root'), @@ -239,7 +239,7 @@ public function testGitArtifactDownloadFailure(): void { // Mock git-artifact download failure. $this->mockRequest( - 'https://github.com/drevops/git-artifact/releases/download/1.7.0/git-artifact', + 'https://github.com/drevops/git-artifact/releases/download/1.8.0/git-artifact', ['method' => 'GET'], ['ok' => FALSE, 'status' => 404, 'body' => 'Not Found'], ); @@ -288,7 +288,7 @@ public function testGitArtifactFailure(): void { // Mock git-artifact command failure. $git_artifact_cmd = sprintf( - '%s %s --root=%s --src=%s --branch=%s --gitignore=%s --log=%s -vvv', + '%s %s --root=%s --source=%s --branch=%s --gitignore=%s --log=%s -vvv', escapeshellarg($this->getGitArtifactBinPath()), escapeshellarg('git@github.com:org/repo.git'), escapeshellarg(self::$tmp . '/root'), @@ -357,7 +357,7 @@ public function testCustomBranch(): void { // Mock git-artifact command with custom branch. $git_artifact_cmd = sprintf( - '%s %s --root=%s --src=%s --branch=%s --gitignore=%s --log=%s -vvv', + '%s %s --root=%s --source=%s --branch=%s --gitignore=%s --log=%s -vvv', escapeshellarg($this->getGitArtifactBinPath()), escapeshellarg('git@github.com:org/repo.git'), escapeshellarg(self::$tmp . '/root'), @@ -399,7 +399,7 @@ public function testCleanupPatternEnablesCleanup(): void { // Mock git-artifact command with the cleanup flags and the default age. $git_artifact_cmd = sprintf( - '%s %s --root=%s --src=%s --branch=%s --gitignore=%s --log=%s --cleanup-stale --cleanup-pattern=%s --cleanup-age=%s -vvv', + '%s %s --root=%s --source=%s --branch=%s --gitignore=%s --log=%s --cleanup-stale --cleanup-pattern=%s --cleanup-age=%s -vvv', escapeshellarg($this->getGitArtifactBinPath()), escapeshellarg('git@github.com:org/repo.git'), escapeshellarg(self::$tmp . '/root'), @@ -446,7 +446,7 @@ public function testCleanupAgeOverride(): void { // Mock git-artifact command with the overridden age. $git_artifact_cmd = sprintf( - '%s %s --root=%s --src=%s --branch=%s --gitignore=%s --log=%s --cleanup-stale --cleanup-pattern=%s --cleanup-age=%s -vvv', + '%s %s --root=%s --source=%s --branch=%s --gitignore=%s --log=%s --cleanup-stale --cleanup-pattern=%s --cleanup-age=%s -vvv', escapeshellarg($this->getGitArtifactBinPath()), escapeshellarg('git@github.com:org/repo.git'), escapeshellarg(self::$tmp . '/root'), @@ -494,7 +494,7 @@ protected function createDummyGitArtifactBinary(): void { */ protected function mockGitArtifactDownload(): void { $this->mockRequest( - 'https://github.com/drevops/git-artifact/releases/download/1.7.0/git-artifact', + 'https://github.com/drevops/git-artifact/releases/download/1.8.0/git-artifact', ['method' => 'GET'], ['ok' => TRUE, 'status' => 200, 'body' => ''], ); From b24ff0fc5eeef9786cfa1d520bf88b36dac4033d Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:12:08 +1100 Subject: [PATCH 59/71] Updated 'git-artifact' to 1.9.0. Forward-ported from main 1b86151e96a41266310de152d21beb3289d3c4e7. Applied the 1.9.0 version and checksum to the PHP 'vortex-deploy-artifact', 'DeployArtifactTest' and the artifact deployment docs. --- .vortex/docs/content/deployment/artifact.mdx | 2 +- .vortex/tooling/src/vortex-deploy-artifact | 4 ++-- .vortex/tooling/tests/Unit/DeployArtifactTest.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.vortex/docs/content/deployment/artifact.mdx b/.vortex/docs/content/deployment/artifact.mdx index 26194a14fe..a9da59415f 100644 --- a/.vortex/docs/content/deployment/artifact.mdx +++ b/.vortex/docs/content/deployment/artifact.mdx @@ -85,7 +85,7 @@ with a SHA256 checksum before execution. The version and checksum are controlled by: -- `VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_VERSION`: Version to download (default: `1.8.0`). +- `VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_VERSION`: Version to download (default: `1.9.0`). - `VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_SHA256`: Expected SHA256 checksum of the binary. ### Stale branch cleanup diff --git a/.vortex/tooling/src/vortex-deploy-artifact b/.vortex/tooling/src/vortex-deploy-artifact index a62f2e372d..e2fa64c4ee 100755 --- a/.vortex/tooling/src/vortex-deploy-artifact +++ b/.vortex/tooling/src/vortex-deploy-artifact @@ -62,10 +62,10 @@ $deploy_ssh_fingerprint = getenv_default('VORTEX_DEPLOY_ARTIFACT_SSH_FINGERPRINT $deploy_ssh_file = getenv_default('VORTEX_DEPLOY_ARTIFACT_SSH_FILE', 'VORTEX_DEPLOY_SSH_FILE', 'VORTEX_SSH_FILE', getenv('HOME') . '/.ssh/id_rsa'); // Version of git-artifact to download. -$git_artifact_version = getenv_default('VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_VERSION', '1.8.0'); +$git_artifact_version = getenv_default('VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_VERSION', '1.9.0'); // SHA256 checksum of the git-artifact binary. -$git_artifact_sha256 = getenv_default('VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_SHA256', '31133d0d7887388501ecc407179325e2ad4b21cfb7ac9c7f4e6aecb991977d9d'); +$git_artifact_sha256 = getenv_default('VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_SHA256', 'b8282b9a07f6d9a11d4b0dcfa248848ae57182ec8626eee8bee4ee12cdd36a39'); // Remote branches eligible for stale branch cleanup after a successful push: // comma-separated globs (e.g. "feature/*,bugfix/*") or a single regex literal. diff --git a/.vortex/tooling/tests/Unit/DeployArtifactTest.php b/.vortex/tooling/tests/Unit/DeployArtifactTest.php index f7ce1102f8..3896625dbf 100644 --- a/.vortex/tooling/tests/Unit/DeployArtifactTest.php +++ b/.vortex/tooling/tests/Unit/DeployArtifactTest.php @@ -239,7 +239,7 @@ public function testGitArtifactDownloadFailure(): void { // Mock git-artifact download failure. $this->mockRequest( - 'https://github.com/drevops/git-artifact/releases/download/1.8.0/git-artifact', + 'https://github.com/drevops/git-artifact/releases/download/1.9.0/git-artifact', ['method' => 'GET'], ['ok' => FALSE, 'status' => 404, 'body' => 'Not Found'], ); @@ -494,7 +494,7 @@ protected function createDummyGitArtifactBinary(): void { */ protected function mockGitArtifactDownload(): void { $this->mockRequest( - 'https://github.com/drevops/git-artifact/releases/download/1.8.0/git-artifact', + 'https://github.com/drevops/git-artifact/releases/download/1.9.0/git-artifact', ['method' => 'GET'], ['ok' => TRUE, 'status' => 200, 'body' => ''], ); From 4dbbdbdc5c0f8d6b49cbd43fbd7cb8147aa1c848 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:13:45 +1100 Subject: [PATCH 60/71] [#3208] Made 'vortex-fetch-db' validate 'VORTEX_FETCH_DB_SOURCE' before reusing a cached dump and accept the 'none' source. Forward-ported from main 7773f08778eb39f428bd00be4ae6884610bd037f. The PHP router already failed on an unknown source, so the port moves validation ahead of the cached dump check, adds the 'none' source written by the CLI, names the indexed variable in the error, adds 'FetchDbTest' cases and adds the source list to the provision docs, which 2.x did not have. --- .../docs/content/development/provision.mdx | 14 +++++ .vortex/tooling/src/vortex-fetch-db | 38 ++++++----- .vortex/tooling/tests/Unit/FetchDbTest.php | 63 ++++++++++++++++++- 3 files changed, 98 insertions(+), 17 deletions(-) diff --git a/.vortex/docs/content/development/provision.mdx b/.vortex/docs/content/development/provision.mdx index 441005baa9..cbeac035ac 100644 --- a/.vortex/docs/content/development/provision.mdx +++ b/.vortex/docs/content/development/provision.mdx @@ -181,6 +181,20 @@ database) - the tabs below reflect that difference. To fetch the database with the latest data from the production environment, fetch the latest database dump into the `.data` directory. +`VORTEX_FETCH_DB_SOURCE` sets where the dump comes from, and accepts the +following values: + +- `url`, the default: the file at `VORTEX_FETCH_DB_URL` +- `ftp`: a file on an FTP server +- `acquia`: a backup of an Acquia environment +- `lagoon`: a dump of a Lagoon environment +- `container_registry`: a database container image, pulled instead of a + file +- `s3`: a file in an S3 bucket +- `none`: no source; you put the dump into `.data` yourself + +Any other value stops the command with an error that lists these values. + ```shell diff --git a/.vortex/tooling/src/vortex-fetch-db b/.vortex/tooling/src/vortex-fetch-db index 100a6b5114..8391dba6ae 100755 --- a/.vortex/tooling/src/vortex-fetch-db +++ b/.vortex/tooling/src/vortex-fetch-db @@ -50,6 +50,22 @@ if ($proceed !== '1') { quit(0); } +// The fetch script is resolved before the existing dump check, so an +// unsupported source fails even when a cached dump would be reused. +$sources = [ + 'url' => __DIR__ . '/vortex-fetch-db-url', + 'ftp' => __DIR__ . '/vortex-fetch-db-ftp', + 'acquia' => __DIR__ . '/vortex-fetch-db-acquia', + 'lagoon' => __DIR__ . '/vortex-fetch-db-lagoon', + 'container_registry' => __DIR__ . '/vortex-fetch-db-container-registry', + 's3' => __DIR__ . '/vortex-fetch-db-s3', + 'none' => '', +]; + +if (!array_key_exists($source, $sources)) { + FAIL('Unsupported database source "%s" in VORTEX_FETCH_DB%s_SOURCE. Use one of: %s.', $source, $db_index, implode(', ', array_keys($sources))); +} + // Skip file existence check for container_registry source as the database is // stored as a Docker image, not a file. if ($source !== 'container_registry') { @@ -78,22 +94,14 @@ if ($source !== 'container_registry') { } } -$sources = [ - 'ftp' => __DIR__ . '/vortex-fetch-db-ftp', - 'url' => __DIR__ . '/vortex-fetch-db-url', - 'acquia' => __DIR__ . '/vortex-fetch-db-acquia', - 'lagoon' => __DIR__ . '/vortex-fetch-db-lagoon', - 'container_registry' => __DIR__ . '/vortex-fetch-db-container-registry', - 's3' => __DIR__ . '/vortex-fetch-db-s3', -]; - -if (!isset($sources[$source])) { - FAIL('Invalid database download source "%s". Available sources: %s.', $source, implode(', ', array_keys($sources))); +if ($sources[$source] === '') { + NOTE('Skipped fetching as VORTEX_FETCH_DB%s_SOURCE is set to "none".', $db_index); +} +else { + TASK(sprintf('Fetching database from the "%s" source.', $source), sprintf('Fetched database from the "%s" source.', $source), function () use ($sources, $source): void { + passthru_or_fail($sources[$source], 'Failed to download database from source "%s".', $source); + }); } - -TASK(sprintf('Fetching database from the "%s" source.', $source), sprintf('Fetched database from the "%s" source.', $source), function () use ($sources, $source): void { - passthru_or_fail($sources[$source], 'Failed to download database from source "%s".', $source); -}); passthru('ls -Alh ' . escapeshellarg($db_dir) . ' || true'); diff --git a/.vortex/tooling/tests/Unit/FetchDbTest.php b/.vortex/tooling/tests/Unit/FetchDbTest.php index 6820cdeedf..cf46531485 100644 --- a/.vortex/tooling/tests/Unit/FetchDbTest.php +++ b/.vortex/tooling/tests/Unit/FetchDbTest.php @@ -44,6 +44,13 @@ public static function dataProviderEarlyPass(): array { }, 'expected' => 'Skipped database download', ], + 'proceed not set skips source validation' => [ + 'before' => function (self $test): void { + $test->envSet('VORTEX_FETCH_DB_PROCEED', '0'); + $test->envSet('VORTEX_FETCH_DB_SOURCE', 'VORTEX_CONTAINER_REGISTRY'); + }, + 'expected' => 'Skipped database download', + ], 'existing dump skips download' => [ 'before' => function (self $test): void { $db_dir = self::$tmp . '/data'; @@ -112,6 +119,24 @@ public static function dataProviderSuccess(): array { 'expected' => ['Finished database download.'], 'after' => NULL, ], + 'acquia source' => self::sourceRoute('acquia', 'vortex-fetch-db-acquia'), + 'lagoon source' => self::sourceRoute('lagoon', 'vortex-fetch-db-lagoon'), + 'container_registry source' => self::sourceRoute('container_registry', 'vortex-fetch-db-container-registry'), + 's3 source' => self::sourceRoute('s3', 'vortex-fetch-db-s3'), + 'none source' => [ + 'before' => function (self $test): void { + $db_dir = self::$tmp . '/data'; + $test->envSet('VORTEX_FETCH_DB_SOURCE', 'none'); + $test->envSet('VORTEX_FETCH_DB_SEMAPHORE', self::$tmp . '/sem'); + $test->mockPassthruMultiple([ + ['cmd' => 'ls -Alh ' . escapeshellarg($db_dir) . ' || true', 'result_code' => 0], + ]); + }, + 'expected' => ['Started database download.', 'Skipped fetching as VORTEX_FETCH_DB_SOURCE is set to "none".', 'Finished database download.'], + 'after' => function (self $test): void { + $test->assertFileExists(self::$tmp . '/sem'); + }, + ], 'existing dump force override' => [ 'before' => function (self $test): void { $db_dir = self::$tmp . '/data'; @@ -155,9 +180,25 @@ public static function dataProviderError(): array { return [ 'invalid source' => [ 'before' => function (self $test): void { - $test->envSet('VORTEX_FETCH_DB_SOURCE', 'invalid'); + $test->envSet('VORTEX_FETCH_DB_SOURCE', 'VORTEX_CONTAINER_REGISTRY'); }, - 'expected' => 'Invalid database download source', + 'expected' => 'Unsupported database source "VORTEX_CONTAINER_REGISTRY" in VORTEX_FETCH_DB_SOURCE. Use one of: url, ftp, acquia, lagoon, container_registry, s3, none.', + ], + 'invalid source with an existing dump' => [ + 'before' => function (self $test): void { + $test->envSet('VORTEX_FETCH_DB_SOURCE', 'VORTEX_CONTAINER_REGISTRY'); + $db_dir = self::$tmp . '/data'; + File::mkdir($db_dir); + File::dump($db_dir . '/db.sql', 'fake-dump'); + }, + 'expected' => 'Unsupported database source "VORTEX_CONTAINER_REGISTRY" in VORTEX_FETCH_DB_SOURCE.', + ], + 'invalid indexed source' => [ + 'before' => function (self $test): void { + $test->envSet('VORTEX_DB_INDEX', '2'); + $test->envSet('VORTEX_FETCH_DB2_SOURCE', 'sftp'); + }, + 'expected' => 'Unsupported database source "sftp" in VORTEX_FETCH_DB2_SOURCE. Use one of: url, ftp, acquia, lagoon, container_registry, s3, none.', ], 'source script fails' => [ 'before' => function (self $test): void { @@ -171,4 +212,22 @@ public static function dataProviderError(): array { ]; } + /** + * Build a success case that routes a source to its fetch script. + */ + protected static function sourceRoute(string $source, string $script): array { + return [ + 'before' => function (self $test) use ($source, $script): void { + $db_dir = self::$tmp . '/data'; + $test->envSet('VORTEX_FETCH_DB_SOURCE', $source); + $test->mockPassthruMultiple([ + ['cmd' => self::$srcDir . '/' . $script, 'result_code' => 0], + ['cmd' => 'ls -Alh ' . escapeshellarg($db_dir) . ' || true', 'result_code' => 0], + ]); + }, + 'expected' => [sprintf('Fetched database from the "%s" source.', $source), 'Finished database download.'], + 'after' => NULL, + ]; + } + } From d5329b2639d3e1ee8e82cf4da5c142e106012398 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:15:47 +1100 Subject: [PATCH 61/71] [#3135] Enabled the post-provision configuration check through '.env' in the provision subtest. Follow-up to the forward-port of main fce3081dd4f39a18abdb8ccdd71fad5d0a73dc20. The 2.x PHP tooling loads '.env' over the process environment, so the flag passed as a command environment variable was overridden by the shipped '0' value. --- .../phpunit/Traits/Subtests/SubtestAhoyTrait.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php index 3cee8c474e..10053e2c38 100644 --- a/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php +++ b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php @@ -313,16 +313,23 @@ protected function subtestAhoyProvision(): void { $this->logSubstep('Run provision with the post-provision configuration check enabled'); + // The tooling loads '.env' over the process environment, so the flag is + // enabled in '.env' rather than passed to the command. + $this->fileAddVar('.env', 'VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION', '1'); + $this->syncToContainer('.env'); + $this->cmd( 'ahoy provision', [ '* Verify config after provision : Yes', '* Verified that post-provision operations did not change configuration.', ], - 'Provision should report that post-provision operations left configuration unchanged', - env: ['VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION' => '1'] + 'Provision should report that post-provision operations left configuration unchanged' ); + $this->fileRestore('.env'); + $this->syncToContainer('.env'); + $this->logSubstep('Run provision with exported config files different to DB'); $this->logNote('Make a change to the configuration.'); From 116b1092e838293f10196ce56e78614cf6d23a3e Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:20:59 +1100 Subject: [PATCH 62/71] [#3136] Added a CI gate that fails when the build leaves a dirty working tree. Forward-ported from main b343aea7cc240eb3b4761026258f8d9dbc4e84b8. Re-implemented 'vortex-check-worktree-changes' as a PHP tooling script with a PHPUnit test against a real Git repository, and added the step at the end of the 2.x GHA and CircleCI 'test' jobs, which write the same 'docker-compose.yml', 'db_cache_*' and 'codecov' files as main's ignore list covers. --- .circleci/config.yml | 5 + .circleci/vortex-test-common.yml | 5 + .github/workflows/build-test-deploy.yml | 5 + .../.utils/variables/extra/ci.variables.sh | 3 + .../content/continuous-integration/README.mdx | 56 ++++ .../docs/content/development/variables.mdx | 1 + .vortex/docs/cspell.json | 2 + .vortex/tooling/composer.json | 1 + .vortex/tooling/phpcs.xml | 1 + .../tooling/src/vortex-check-worktree-changes | 61 +++++ .../tests/Unit/CheckWorktreeChangesTest.php | 259 ++++++++++++++++++ 11 files changed, 399 insertions(+) create mode 100755 .vortex/tooling/src/vortex-check-worktree-changes create mode 100644 .vortex/tooling/tests/Unit/CheckWorktreeChangesTest.php diff --git a/.circleci/config.yml b/.circleci/config.yml index 0a5ac6706c..4e1d8252d5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -561,6 +561,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + #;< DEPLOYMENT # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for diff --git a/.circleci/vortex-test-common.yml b/.circleci/vortex-test-common.yml index f9fa1cc46b..e399c700be 100644 --- a/.circleci/vortex-test-common.yml +++ b/.circleci/vortex-test-common.yml @@ -418,6 +418,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # DIDI-FI variant jobs vortex-dev-didi-database-fi: <<: *runner_config diff --git a/.github/workflows/build-test-deploy.yml b/.github/workflows/build-test-deploy.yml index d2621e4ede..5b7df80a71 100644 --- a/.github/workflows/build-test-deploy.yml +++ b/.github/workflows/build-test-deploy.yml @@ -572,6 +572,11 @@ jobs: .logs/test_results/**/*.xml #;> TOOL_PHPUNIT_BEHAT + # Placed after the test steps so a dirty tree never suppresses them. + - name: Check that the build left a clean working tree + run: ./vendor/bin/vortex-check-worktree-changes + continue-on-error: ${{ vars.VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE == '1' }} + - name: Setup tmate session if: ${{ !cancelled() && github.event.inputs.enable_terminal }} uses: mxschmitt/action-tmate@35b54afac29c97fb54faba5b513f8fbd1882f113 # v3 diff --git a/.vortex/docs/.utils/variables/extra/ci.variables.sh b/.vortex/docs/.utils/variables/extra/ci.variables.sh index 7e81da0e51..8000edaf41 100755 --- a/.vortex/docs/.utils/variables/extra/ci.variables.sh +++ b/.vortex/docs/.utils/variables/extra/ci.variables.sh @@ -75,6 +75,9 @@ VORTEX_CI_BEHAT_PROFILE= # Ignore Jest test failures. VORTEX_CI_JEST_IGNORE_FAILURE=0 +# Ignore working tree check failures. +VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE=0 + # Directory to store test results in CI. VORTEX_CI_TEST_RESULTS=/tmp/tests diff --git a/.vortex/docs/content/continuous-integration/README.mdx b/.vortex/docs/content/continuous-integration/README.mdx index dc813d39ea..fc72d493a0 100644 --- a/.vortex/docs/content/continuous-integration/README.mdx +++ b/.vortex/docs/content/continuous-integration/README.mdx @@ -47,6 +47,7 @@ import CodeLifecycle from '../_code-lifecycle.mdx'; - Checks code coverage and posts a PR comment (first container only) - Runs BDD tests (distributed across all containers - see [Test parallelism](#test-parallelism)) - Collects and stores test results and artifacts +- Checks that the build left a clean working tree - see [Working tree check](#working-tree-check) ### 3. Build @@ -98,6 +99,60 @@ protection rules as a required status check. ::: +## Working tree check + +A build can produce files that belong in the repository, such as exported +configuration, compiled front-end assets or scaffolded files. If nobody commits +them, the repository and the build output drift apart. The next developer to +run a build then gets a dirty working tree they didn't cause. + +The `test` job runs `vendor/bin/vortex-check-worktree-changes` as its last +step, after the tests, so a dirty tree never hides the test results that +explain it. The step fails when the working tree holds modified or untracked +files, and prints each file with its Git status: + +```shell +[INFO] Started working tree check. + Ignoring "docker-compose.yml". + Ignoring "*/docker-compose.yml". + Ignoring "db_cache_*". + Ignoring "codecov". + Ignoring "codecov.SHA256SUM". + Ignoring "codecov.SHA256SUM.sig". + The build modified or created these files: + M config/default/core.extension.yml +?? config/default/views.view.recent_content.yml + Run "ahoy build" locally and commit the resulting changes. + Add paths that are generated during the build and are not committed to VORTEX_CHECK_WORKTREE_CHANGES_IGNORE. +[FAIL] The build left changes in the working tree. +``` + +The check never reports files that Git ignores, so `.gitignore` already covers +most generated output. To exclude other paths, set +`VORTEX_CHECK_WORKTREE_CHANGES_IGNORE` in `.env` to a comma-separated list of +[Git pathspec](https://git-scm.com/docs/gitglossary#def_pathspec) patterns: + +```shell +VORTEX_CHECK_WORKTREE_CHANGES_IGNORE=docker-compose.yml,*/docker-compose.yml,db_cache_*,codecov,codecov.SHA256SUM,codecov.SHA256SUM.sig,web/sites/default/settings.generated.php +``` + +The default value covers the files the pipeline itself writes into the working +tree: + +- every `docker-compose.yml`, which the `Process the codebase to run in CI` step rewrites in place +- the `db_cache_*` database cache keys +- the `codecov` uploader and its 2 signature files + +These files exist only during a continuous integration run, so they belong in +this list rather than in `.gitignore`. Your value replaces the default list, so +keep those entries when you add your own. + +The check reads the working tree on the runner, not the codebase inside the +`cli` container. + +Set `VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE` to `1` to report the findings +without failing the build. See [Ignore tool failures](#ignore-tool-failures). + ## Caching strategy The database is fetched on the first continuous integration run of the day and cached so that @@ -441,6 +496,7 @@ failures (but still run the tool and see the results in the logs): | [Rector](../development/code-quality/rector.mdx) | Check for automated refactoring rules | `VORTEX_CI_RECTOR_IGNORE_FAILURE` | | [SDC Devel](../development/code-quality/sdc-devel.mdx) | Validate Single Directory Components | `VORTEX_CI_SDC_DEVEL_IGNORE_FAILURE` | | [Twig CS Fixer](../development/code-quality/twig-cs-fixer.mdx) | Lint Twig templates | `VORTEX_CI_TWIG_CS_FIXER_IGNORE_FAILURE` | +| [Working tree check](#working-tree-check) | Check for files left behind by the build | `VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE` | ### Configure deployment skip conditions diff --git a/.vortex/docs/content/development/variables.mdx b/.vortex/docs/content/development/variables.mdx index 3d4017b6d5..004834c88e 100644 --- a/.vortex/docs/content/development/variables.mdx +++ b/.vortex/docs/content/development/variables.mdx @@ -185,6 +185,7 @@ The list below is automatically generated with [Shellvar](https://github.com/ale | `VORTEX_CI_RECTOR_IGNORE_FAILURE` | Ignore Rector failures. | `UNDEFINED` | `CI config` | | `VORTEX_CI_TEST_RESULTS` | Directory to store test results in CI. | `/tmp/tests` | `CI config` | | `VORTEX_CI_TWIG_CS_FIXER_IGNORE_FAILURE` | Ignore Twig CS Fixer failures. | `UNDEFINED` | `CI config` | +| `VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE` | Ignore working tree check failures. | `UNDEFINED` | `CI config` | | `VORTEX_CONTAINER_REGISTRY` | Container registry name.

Provide port, if required as `:`. | `docker.io` | `.env` | | `VORTEX_CONTAINER_REGISTRY_PASS` | The password (token) to log into the container registry. | `UNDEFINED` | `.env.local.example` | | `VORTEX_CONTAINER_REGISTRY_USER` | The username to log into the container registry. | `UNDEFINED` | `.env.local.example` | diff --git a/.vortex/docs/cspell.json b/.vortex/docs/cspell.json index edb7966d92..c3aca903d6 100644 --- a/.vortex/docs/cspell.json +++ b/.vortex/docs/cspell.json @@ -73,6 +73,7 @@ "oomphinc", "palantirnet", "pathauto", + "pathspec", "phpcbf", "phpcodesniffer", "phpcompatibility", @@ -106,6 +107,7 @@ "vortextemplate", "webflo", "webroot", + "worktree", "xmlsitemap", "yourorg", "yoursite" diff --git a/.vortex/tooling/composer.json b/.vortex/tooling/composer.json index d931dc43fb..a2d3d36533 100644 --- a/.vortex/tooling/composer.json +++ b/.vortex/tooling/composer.json @@ -45,6 +45,7 @@ } }, "bin": [ + "src/vortex-check-worktree-changes", "src/vortex-deploy", "src/vortex-doctor", "src/vortex-export-db", diff --git a/.vortex/tooling/phpcs.xml b/.vortex/tooling/phpcs.xml index f0c2554d22..ed33f5c647 100644 --- a/.vortex/tooling/phpcs.xml +++ b/.vortex/tooling/phpcs.xml @@ -15,6 +15,7 @@ check-no-exit.php playground + src/vortex-check-worktree-changes src/vortex-deploy-artifact src/vortex-deploy-lagoon src/vortex-deploy-webhook diff --git a/.vortex/tooling/src/vortex-check-worktree-changes b/.vortex/tooling/src/vortex-check-worktree-changes new file mode 100755 index 0000000000..0906eec876 --- /dev/null +++ b/.vortex/tooling/src/vortex-check-worktree-changes @@ -0,0 +1,61 @@ +#!/usr/bin/env php +/dev/null', $rev_parse_output, $rev_parse_exit_code); +if ($rev_parse_exit_code !== 0) { + FAIL('The current directory is not a Git repository.'); +} + +$git_args = ['status', '--porcelain', '--', '.']; + +foreach ($ignore as $pattern) { + $git_args[] = ':(exclude)' . $pattern; + NOTE('Ignoring "%s".', $pattern); +} + +exec('git ' . implode(' ', array_map(escapeshellarg(...), $git_args)), $changes, $status_exit_code); +if ($status_exit_code !== 0) { + FAIL('Unable to read the working tree status.'); +} + +if ($changes !== []) { + NOTE('The build modified or created these files:'); + echo implode(PHP_EOL, $changes) . PHP_EOL; + NOTE('Run "ahoy build" locally and commit the resulting changes.'); + NOTE('Add paths that are generated during the build and are not committed to VORTEX_CHECK_WORKTREE_CHANGES_IGNORE.'); + FAIL('The build left changes in the working tree.'); +} + +PASS('Finished working tree check.'); diff --git a/.vortex/tooling/tests/Unit/CheckWorktreeChangesTest.php b/.vortex/tooling/tests/Unit/CheckWorktreeChangesTest.php new file mode 100644 index 0000000000..d5d7ecfa8a --- /dev/null +++ b/.vortex/tooling/tests/Unit/CheckWorktreeChangesTest.php @@ -0,0 +1,259 @@ +envUnset('VORTEX_CHECK_WORKTREE_CHANGES_IGNORE'); + + // Stop Git from discovering a repository above the sandbox, so a sandbox + // without a repository is reported as such. + $this->envSet('GIT_CEILING_DIRECTORIES', self::$tmp); + } + + #[DataProvider('dataProviderCheckWorktreeChanges')] + public function testCheckWorktreeChanges(array $env_vars, array $files, array $expected, bool $expect_error = FALSE, bool $init_repo = TRUE): void { + if (!empty($env_vars)) { + $this->envSetMultiple($env_vars); + } + + $root = self::$tmp . '/project_' . uniqid(); + File::mkdir($root); + + if ($init_repo) { + $this->createRepository($root); + } + + // Each entry is appended to the file, creating the file when missing. + foreach ($files as $path => $content) { + $file = $root . '/' . $path; + File::dump($file, (File::exists($file) ? File::read($file) : '') . $content); + } + + if ($expect_error) { + try { + $this->runScript('src/vortex-check-worktree-changes', 1, $root); + } + catch (QuitErrorException $e) { + $this->assertStringContainsOrNot($e->getOutput(), $expected); + throw $e; + } + + return; + } + + $output = $this->runScript('src/vortex-check-worktree-changes', NULL, $root); + + $this->assertStringContainsOrNot($output, $expected); + } + + public static function dataProviderCheckWorktreeChanges(): array { + return [ + 'clean working tree passes' => [ + [], + [], + [ + '* Started working tree check.', + '* Finished working tree check.', + '! The build left changes in the working tree.', + ], + ], + + 'modified tracked file fails' => [ + [], + ['composer.json' => 'Modified by the build.' . PHP_EOL], + [ + '* The build modified or created these files:', + '* M composer.json', + '* Run "ahoy build" locally and commit the resulting changes.', + '* Add paths that are generated during the build and are not committed to VORTEX_CHECK_WORKTREE_CHANGES_IGNORE.', + '* The build left changes in the working tree.', + '! Finished working tree check.', + ], + TRUE, + ], + + 'untracked file fails' => [ + [], + ['build-manifest.json' => '{}'], + [ + '* ?? build-manifest.json', + '* The build left changes in the working tree.', + ], + TRUE, + ], + + 'file ignored by Git passes' => [ + [], + ['.logs/build.log' => 'log'], + [ + '* Finished working tree check.', + '! .logs', + ], + ], + + 'shipped ignore list covers the paths written by the pipeline' => [ + [], + [ + 'docker-compose.yml' => '# Processed to run in CI.' . PHP_EOL, + 'web/sites/default/docker-compose.yml' => 'services: {}', + 'db_cache_branch' => 'develop', + 'db_cache_fallback_yes' => 'yes', + 'db_cache_timestamp' => '20260101', + 'codecov' => 'binary', + 'codecov.SHA256SUM' => 'sum', + 'codecov.SHA256SUM.sig' => 'sig', + ], + [ + '* Ignoring "docker-compose.yml".', + '* Ignoring "*/docker-compose.yml".', + '* Ignoring "db_cache_*".', + '* Ignoring "codecov".', + '* Ignoring "codecov.SHA256SUM".', + '* Ignoring "codecov.SHA256SUM.sig".', + '* Finished working tree check.', + ], + ], + + 'shipped ignore list does not cover the Codecov config file' => [ + [], + ['codecov.yml' => 'coverage: {}'], + [ + '* ?? codecov.yml', + '* The build left changes in the working tree.', + ], + TRUE, + ], + + 'custom ignore list excludes a path' => [ + ['VORTEX_CHECK_WORKTREE_CHANGES_IGNORE' => 'build-manifest.json'], + ['build-manifest.json' => '{}'], + [ + '* Ignoring "build-manifest.json".', + '* Finished working tree check.', + ], + ], + + 'custom ignore list replaces the shipped one' => [ + ['VORTEX_CHECK_WORKTREE_CHANGES_IGNORE' => 'build-manifest.json'], + ['docker-compose.yml' => '# Processed to run in CI.' . PHP_EOL], + [ + '* M docker-compose.yml', + '! Ignoring "docker-compose.yml".', + '* The build left changes in the working tree.', + ], + TRUE, + ], + + 'blank entries in the ignore list are skipped' => [ + ['VORTEX_CHECK_WORKTREE_CHANGES_IGNORE' => ' , build-manifest.json , '], + ['build-manifest.json' => '{}'], + [ + '* Ignoring "build-manifest.json".', + '! Ignoring "".', + '* Finished working tree check.', + ], + ], + + 'ignore list of separators only checks every path' => [ + ['VORTEX_CHECK_WORKTREE_CHANGES_IGNORE' => ','], + ['docker-compose.yml' => '# Processed to run in CI.' . PHP_EOL], + [ + '! Ignoring ', + '* M docker-compose.yml', + '* The build left changes in the working tree.', + ], + TRUE, + ], + + 'fails outside a Git repository' => [ + [], + [], + [ + '* The current directory is not a Git repository.', + '! Finished working tree check.', + ], + TRUE, + FALSE, + ], + ]; + } + + public function testMissingGit(): void { + $this->mockCommandExists(); + $this->mockCommandMissing('git'); + + $this->runScriptError('src/vortex-check-worktree-changes', "Command 'git' is not available."); + } + + public function testStatusFailure(): void { + $root = self::$tmp . '/project_' . uniqid(); + File::mkdir($root); + $this->createRepository($root); + + // Fail only the status read; every other command runs for real. + $this->registerMock('exec', 'DrevOps\\VortexTooling', function (string $command, mixed &$output = NULL, mixed &$result_code = NULL): string|false { + if (str_starts_with($command, "git 'status'")) { + $output = []; + $result_code = 128; + + return ''; + } + + return \exec($command, $output, $result_code); + }); + + try { + $this->runScript('src/vortex-check-worktree-changes', 1, $root); + } + catch (QuitErrorException $e) { + $this->assertStringContainsOrNot($e->getOutput(), [ + '* Unable to read the working tree status.', + '! Finished working tree check.', + ]); + throw $e; + } + } + + /** + * Create a Git repository with committed files. + */ + protected function createRepository(string $root): void { + File::dump($root . '/.gitignore', '.logs' . PHP_EOL); + File::dump($root . '/composer.json', '{}' . PHP_EOL); + File::dump($root . '/docker-compose.yml', 'services: {}' . PHP_EOL); + + $commands = [ + 'git init --quiet', + 'git add --all', + 'git -c user.name=Test -c user.email=test@example.com -c commit.gpgsign=false commit --quiet --message=Initial', + ]; + + foreach ($commands as $command) { + exec(sprintf('cd %s && %s 2>&1', escapeshellarg($root), $command), $output, $exit_code); + if ($exit_code !== 0) { + throw new \RuntimeException(sprintf('Unable to run "%s": %s', $command, implode(PHP_EOL, $output))); + } + } + } + +} From f3fe2acbc808aeb542bba8cf2121574ca7e5ce89 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:26:18 +1100 Subject: [PATCH 63/71] [#3110] Reconciled comments and docblocks with the code they describe. Forward-ported from main a7e613ce8d94e4ee63c5112003328d5bf969e53b. Applied the corrections to the 2.x CLI classes and the '.vortex/tests' lint scripts; skipped the PromptManager, Bash tooling and BATS hunks that have no 2.x counterpart and the EnvTest and ValidatorTest docblocks that are already accurate on 2.x. --- .../src/Prompts/Handlers/CustomModules.php | 4 +-- .../src/Prompts/Handlers/HandlerInterface.php | 9 +++-- .vortex/cli/src/Schema/SchemaValidator.php | 34 +++---------------- .vortex/cli/src/Utils/FileManager.php | 3 +- .vortex/cli/src/Utils/Git.php | 2 +- .vortex/cli/src/Utils/Normalizer.php | 7 ---- .vortex/cli/src/Utils/OptionsResolver.php | 8 ++--- .vortex/cli/src/Utils/Validator.php | 17 ++-------- .../Functional/Command/BuildCommandTest.php | 2 +- .vortex/tests/lint.ci.sh | 2 ++ .vortex/tests/lint.dockerfiles.sh | 2 ++ .vortex/tests/lint.markdown.sh | 2 ++ .vortex/tests/lint.scripts.sh | 2 ++ 13 files changed, 28 insertions(+), 66 deletions(-) diff --git a/.vortex/cli/src/Prompts/Handlers/CustomModules.php b/.vortex/cli/src/Prompts/Handlers/CustomModules.php index 8884824965..d4451c1214 100644 --- a/.vortex/cli/src/Prompts/Handlers/CustomModules.php +++ b/.vortex/cli/src/Prompts/Handlers/CustomModules.php @@ -214,8 +214,8 @@ protected function discoverModulePrefix(): ?string { /** * Remove Behat feature files tagged with @demo. * - * Scans the Behat features directory for .feature files whose first line - * contains the @demo tag and removes them. + * Removes every file in the Behat features directory that contains + * the @demo tag anywhere in its contents. * * @param string $dir * The base directory to search in. diff --git a/.vortex/cli/src/Prompts/Handlers/HandlerInterface.php b/.vortex/cli/src/Prompts/Handlers/HandlerInterface.php index f10a5b8702..a996a74453 100644 --- a/.vortex/cli/src/Prompts/Handlers/HandlerInterface.php +++ b/.vortex/cli/src/Prompts/Handlers/HandlerInterface.php @@ -122,7 +122,7 @@ public function options(array $responses): ?array; * Array of collected responses. * * @return bool - * The condition callback, or null if not conditional. + * TRUE if the handler should run, FALSE otherwise. */ public function shouldRun(array $responses): bool; @@ -138,10 +138,10 @@ public function shouldRun(array $responses): bool; public function default(array $responses): null|string|bool|array; /** - * Discover the value from the environment. + * Discover the value from the existing codebase. * * @return null|string|bool|array - * The value of the environment variable. + * The discovered value, or NULL if it could not be discovered. */ public function discover(): null|string|bool|array; @@ -180,8 +180,7 @@ public function resolvedValue(array $responses): null|string|bool|array; /** * Get a message to display when showing the resolved value. * - * This is used by handlerManager to show an appropriate message (via - * info(), ok(), etc.) when using a resolved value instead of handlering + * The message is shown when a resolved value is used instead of prompting * for input. * * @param array $responses diff --git a/.vortex/cli/src/Schema/SchemaValidator.php b/.vortex/cli/src/Schema/SchemaValidator.php index 9d4e894a7e..936fd32916 100644 --- a/.vortex/cli/src/Schema/SchemaValidator.php +++ b/.vortex/cli/src/Schema/SchemaValidator.php @@ -39,12 +39,9 @@ public function validate(array $config): array { $warnings = []; $resolved = []; - // Normalize config keys to handler IDs. - $normalized = $this->normalizeConfig($config); - // Report unknown prompt IDs. $known_ids = array_keys($this->handlers); - foreach (array_keys($normalized) as $key) { + foreach (array_keys($config) as $key) { if (!in_array($key, $known_ids, TRUE)) { $errors[] = [ 'prompt' => $key, @@ -58,8 +55,8 @@ public function validate(array $config): array { continue; } - $has_value = array_key_exists($id, $normalized); - $value = $normalized[$id] ?? NULL; + $has_value = array_key_exists($id, $config); + $value = $config[$id] ?? NULL; // Skip prompts not provided in the input. if (!$has_value) { @@ -69,7 +66,7 @@ public function validate(array $config): array { // Check dependency conditions for provided prompts. $depends_on = $handler->dependsOn(); if ($depends_on !== NULL) { - $dep_result = $this->checkDependency($depends_on, $normalized); + $dep_result = $this->checkDependency($depends_on, $config); if ($dep_result === 'skip') { $type_error = $this->validateType($handler, $value); @@ -119,34 +116,13 @@ public function validate(array $config): array { ]; } - /** - * Normalize config keys to handler IDs. - * - * Supports both env var names (VORTEX_CLI_INSTALL_PROMPT_*) and handler IDs. - * - * @param array $config - * The raw config array. - * - * @return array - * Config keyed by handler IDs. - */ - protected function normalizeConfig(array $config): array { - $normalized = []; - - foreach ($config as $key => $value) { - $normalized[$key] = $value; - } - - return $normalized; - } - /** * Check if dependency conditions are met. * * @param array> $depends_on * The dependency conditions. * @param array $config - * The normalized config. + * The config array, keyed by handler ID. * * @return bool|string * TRUE if met, FALSE if not met, 'skip' for system dependencies. diff --git a/.vortex/cli/src/Utils/FileManager.php b/.vortex/cli/src/Utils/FileManager.php index a7919d1150..1d241a9426 100644 --- a/.vortex/cli/src/Utils/FileManager.php +++ b/.vortex/cli/src/Utils/FileManager.php @@ -97,8 +97,7 @@ public function copyFiles(): void { * Remove obsolete paths from previous Vortex versions. * * Removes paths that previous Vortex versions placed in the destination but - * the current version no longer ships. Runs after copyFiles() so legacy - * artifacts do not linger across upgrades. + * the current version no longer ships. */ public function removeObsoletePaths(): void { $dst = $this->config->getDst(); diff --git a/.vortex/cli/src/Utils/Git.php b/.vortex/cli/src/Utils/Git.php index 0d2cfe72f4..a1b60acc1b 100644 --- a/.vortex/cli/src/Utils/Git.php +++ b/.vortex/cli/src/Utils/Git.php @@ -50,7 +50,7 @@ public function listRemotes(): array { continue; // @codeCoverageIgnoreEnd } - // Remove the trailing (fetch) or (push) from the remote name. + // Remove the trailing (fetch) or (push) from the remote URL. $parts[1] = preg_replace('/ \(.*\)$/', '', $parts[1]); $remotes[$parts[0]] = $parts[1]; } diff --git a/.vortex/cli/src/Utils/Normalizer.php b/.vortex/cli/src/Utils/Normalizer.php index a958c54141..28d8a2ae5e 100644 --- a/.vortex/cli/src/Utils/Normalizer.php +++ b/.vortex/cli/src/Utils/Normalizer.php @@ -4,13 +4,6 @@ namespace DrevOps\VortexCli\Utils; -/** - * Install configuration. - * - * Install config is a config of the install command. - * - * @package DrevOps\VortexCli - */ final class Normalizer { /** diff --git a/.vortex/cli/src/Utils/OptionsResolver.php b/.vortex/cli/src/Utils/OptionsResolver.php index 5ac544aac4..a484e919b5 100644 --- a/.vortex/cli/src/Utils/OptionsResolver.php +++ b/.vortex/cli/src/Utils/OptionsResolver.php @@ -41,11 +41,9 @@ public static function checkRequirements(ExecutableFinder $finder): void { * Instantiate configuration from CLI options and environment variables. * * Install configuration is a set of internal variables prefixed with - * "VORTEX_CLI_INSTALL_" and used to control the installation. They are read - * from the environment variables with $this->config->get(). - * - * For simplicity of naming, internal install config variables used in - * $this->config->get() match environment variables names. + * "VORTEX_CLI_INSTALL_" and used to control the installation. Each is + * resolved from the CLI options, the --config JSON and the environment, and + * stored in Config under the name of its environment variable. * * @param array $options * Array of CLI options. diff --git a/.vortex/cli/src/Utils/Validator.php b/.vortex/cli/src/Utils/Validator.php index 1cc49102b7..fed4e10c4b 100644 --- a/.vortex/cli/src/Utils/Validator.php +++ b/.vortex/cli/src/Utils/Validator.php @@ -4,13 +4,6 @@ namespace DrevOps\VortexCli\Utils; -/** - * Converter. - * - * Convert strings to different formats. - * - * @package DrevOps\VortexCli - */ class Validator { public static function containerImage(string $value): bool { @@ -53,10 +46,11 @@ public static function gitCommitShaShort(string $value): bool { * - Branch names: "main", "develop", "feature/my-feature" * * Follows git reference naming rules: - * - Can contain alphanumeric, dot, hyphen, underscore, slash + * - Can contain alphanumeric, dot, hyphen, underscore, slash, plus * - Cannot start with dot or hyphen * - Cannot contain: @, ^, ~, :, ?, *, [, space, \, @{ - * - Cannot end with .lock or contain + * - Cannot contain .. or // + * - Cannot end with .lock or / * * @param string $value * The reference string to validate. @@ -77,11 +71,6 @@ public static function gitRef(string $value): bool { return TRUE; } - // Git ref naming rules (simplified): - // - Can contain alphanumeric, dot, hyphen, underscore, slash, plus. - // - Cannot start with dot or hyphen. - // - Cannot contain .. or end with .lock. - // - Cannot end with / or contain //. $pattern = '/^(?![.\-])(?!.*\.\.)[a-zA-Z0-9._\/+-]+(?, expect_failure: bool, output_assertions: array, requirements_exit_callback?: (\Closure | null), requirements_finder_callback?: (\Closure | null), docker_compose_url?: (string | null), url_service?: string, before?: (\Closure | null)}> */ diff --git a/.vortex/tests/lint.ci.sh b/.vortex/tests/lint.ci.sh index 4e3f743578..1bfb430f17 100755 --- a/.vortex/tests/lint.ci.sh +++ b/.vortex/tests/lint.ci.sh @@ -23,3 +23,5 @@ else echo "Checking that .circleci/vortex-test-common.yml is up to date." php "${ROOT_DIR}/.vortex/tests/generate-vortex-dev-circleci" --check fi + +# LCOV_EXCL_STOP diff --git a/.vortex/tests/lint.dockerfiles.sh b/.vortex/tests/lint.dockerfiles.sh index cd9037c053..cd55b81c40 100755 --- a/.vortex/tests/lint.dockerfiles.sh +++ b/.vortex/tests/lint.dockerfiles.sh @@ -36,3 +36,5 @@ for file in "${targets[@]}"; do docker run --rm -i hadolint/hadolint:v2.15.0 <"${file}" fi done + +# LCOV_EXCL_STOP diff --git a/.vortex/tests/lint.markdown.sh b/.vortex/tests/lint.markdown.sh index 4f02979371..6584a274ef 100755 --- a/.vortex/tests/lint.markdown.sh +++ b/.vortex/tests/lint.markdown.sh @@ -33,3 +33,5 @@ done "${ROOT_DIR}"/README.md \ "${ROOT_DIR}"/README.dist.md \ "${ROOT_DIR}"/SECURITY.md + +# LCOV_EXCL_STOP diff --git a/.vortex/tests/lint.scripts.sh b/.vortex/tests/lint.scripts.sh index 5d88a7e529..1f8cb0069e 100755 --- a/.vortex/tests/lint.scripts.sh +++ b/.vortex/tests/lint.scripts.sh @@ -70,3 +70,5 @@ for file in "${targets[@]}"; do fi fi done + +# LCOV_EXCL_STOP From 69ec062669f8640c64eef0a69c1466aa8c883b67 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:31:52 +1100 Subject: [PATCH 64/71] [#3127] Restored the process environment after every CLI test. Forward-ported from main 748b435d2e1257ed8558103712455c9d8cb2f3e4. Applied to the 2.x CLI test base classes under '.vortex/cli/tests', whose handler test cases live in 'Unit/Handlers' and 'Functional/Handlers' instead of the installer 'Prompts/Handlers' directories. --- .../AbstractHandlerProcessTestCase.php | 6 +- .vortex/cli/tests/Unit/EnvTest.php | 28 -------- .../AbstractHandlerDiscoveryTestCase.php | 2 + .vortex/cli/tests/Unit/SelfTest.php | 47 ++++++++++++++ .vortex/cli/tests/Unit/UnitTestCase.php | 65 +++++++++++++++++++ 5 files changed, 115 insertions(+), 33 deletions(-) diff --git a/.vortex/cli/tests/Functional/Handlers/AbstractHandlerProcessTestCase.php b/.vortex/cli/tests/Functional/Handlers/AbstractHandlerProcessTestCase.php index e1614fa896..c60d5cbc08 100644 --- a/.vortex/cli/tests/Functional/Handlers/AbstractHandlerProcessTestCase.php +++ b/.vortex/cli/tests/Functional/Handlers/AbstractHandlerProcessTestCase.php @@ -36,11 +36,7 @@ abstract class AbstractHandlerProcessTestCase extends FunctionalTestCase { protected function setUp(): void { parent::setUp(); - static::envUnsetPrefix('VORTEX_'); - static::envUnsetPrefix('DRUPAL_'); - static::envUnsetPrefix('LAGOON_'); - static::envUnset('WEBROOT'); - static::envUnset('TZ'); + static::envUnsetProjectVars(); static::applicationInitFromCommand(InstallCommand::class); diff --git a/.vortex/cli/tests/Unit/EnvTest.php b/.vortex/cli/tests/Unit/EnvTest.php index 0b90add72b..7d3d99bedf 100644 --- a/.vortex/cli/tests/Unit/EnvTest.php +++ b/.vortex/cli/tests/Unit/EnvTest.php @@ -17,34 +17,6 @@ #[RunTestsInSeparateProcesses] class EnvTest extends UnitTestCase { - /** - * Backup value of the $GLOBALS['_SERVER'] variable. - * - * @var array - */ - protected $backupServer; - - /** - * Backup value of the $GLOBALS['_ENV'] variable. - * - * @var array - */ - protected $backupEnv; - - protected function setUp(): void { - $this->backupEnv = $GLOBALS['_ENV']; - $this->backupServer = $GLOBALS['_SERVER']; - - parent::setUp(); - } - - protected function tearDown(): void { - $GLOBALS['_ENV'] = $this->backupEnv; - $GLOBALS['_SERVER'] = $this->backupServer; - - parent::tearDown(); - } - #[DataProvider('dataProviderGet')] public function testGet(string $name, string $value, ?string $default, ?string $expected): void { static::envSet($name, $expected); diff --git a/.vortex/cli/tests/Unit/Handlers/AbstractHandlerDiscoveryTestCase.php b/.vortex/cli/tests/Unit/Handlers/AbstractHandlerDiscoveryTestCase.php index 8cda01fbf0..addb0972b0 100644 --- a/.vortex/cli/tests/Unit/Handlers/AbstractHandlerDiscoveryTestCase.php +++ b/.vortex/cli/tests/Unit/Handlers/AbstractHandlerDiscoveryTestCase.php @@ -70,6 +70,8 @@ abstract class AbstractHandlerDiscoveryTestCase extends UnitTestCase { protected function setUp(): void { parent::setUp(); + static::envUnsetProjectVars(); + static::tuiSetUp(); static::$sut = File::mkdir(static::$sut . DIRECTORY_SEPARATOR . 'myproject'); diff --git a/.vortex/cli/tests/Unit/SelfTest.php b/.vortex/cli/tests/Unit/SelfTest.php index eccb67af51..b545bc0db2 100644 --- a/.vortex/cli/tests/Unit/SelfTest.php +++ b/.vortex/cli/tests/Unit/SelfTest.php @@ -10,6 +10,33 @@ #[CoversClass(UnitTestCase::class)] class SelfTest extends UnitTestCase { + const AMBIENT_VAR = 'VORTEX_TEST_AMBIENT_VAR'; + + const LEAKED_VAR = 'VORTEX_TEST_LEAKED_VAR'; + + /** + * @var string|false + */ + protected static $ambientOriginal; + + public static function setUpBeforeClass(): void { + parent::setUpBeforeClass(); + + static::$ambientOriginal = getenv(self::AMBIENT_VAR); + putenv(self::AMBIENT_VAR . '=ambient'); + } + + public static function tearDownAfterClass(): void { + if (static::$ambientOriginal === FALSE) { + putenv(self::AMBIENT_VAR); + } + else { + putenv(self::AMBIENT_VAR . '=' . static::$ambientOriginal); + } + + parent::tearDownAfterClass(); + } + public function testEnvCleanup1SetVariables(): void { // Set environment variables using envSet. static::envSet('VORTEX_TEST_VAR_1', 'value1'); @@ -41,4 +68,24 @@ public function testEnvCleanup2VerifyCleanup(): void { $this->assertFalse(getenv('VORTEX_TEST_VAR_4'), 'VORTEX_TEST_VAR_4 should be cleaned up after previous test'); } + public function testEnvRestore1WriteRawValues(): void { + // envSet() is bypassed here to reproduce what production code does when it + // writes the environment directly. + putenv(self::LEAKED_VAR . '=leaked'); + putenv(self::AMBIENT_VAR . '=changed'); + $_ENV[self::LEAKED_VAR] = 'leaked'; + $_SERVER[self::LEAKED_VAR] = 'leaked'; + + $this->assertSame('leaked', getenv(self::LEAKED_VAR)); + $this->assertSame('changed', getenv(self::AMBIENT_VAR)); + } + + #[Depends('testEnvRestore1WriteRawValues')] + public function testEnvRestore2VerifyRestored(): void { + $this->assertFalse(getenv(self::LEAKED_VAR), 'A variable added by the previous test should not outlive it'); + $this->assertSame('ambient', getenv(self::AMBIENT_VAR), 'A variable changed by the previous test should be back to its original value'); + $this->assertArrayNotHasKey(self::LEAKED_VAR, $_ENV); + $this->assertArrayNotHasKey(self::LEAKED_VAR, $_SERVER); + } + } diff --git a/.vortex/cli/tests/Unit/UnitTestCase.php b/.vortex/cli/tests/Unit/UnitTestCase.php index 4bff0bcebc..25117d02ec 100644 --- a/.vortex/cli/tests/Unit/UnitTestCase.php +++ b/.vortex/cli/tests/Unit/UnitTestCase.php @@ -37,10 +37,35 @@ abstract class UnitTestCase extends UpstreamUnitTestCase { */ protected static ?string $originalCwd = NULL; + /** + * The process environment before the test ran. + * + * @var array + */ + protected array $processEnvBackup; + + /** + * The $_ENV superglobal before the test ran. + * + * @var array + */ + protected array $globalEnvBackup; + + /** + * The $_SERVER superglobal before the test ran. + * + * @var array + */ + protected array $globalServerBackup; + /** * {@inheritdoc} */ protected function setUp(): void { + $this->processEnvBackup = getenv(); + $this->globalEnvBackup = $_ENV; + $this->globalServerBackup = $_SERVER; + $cwd = getcwd(); if ($cwd === FALSE) { throw new \RuntimeException('Failed to determine current working directory.'); @@ -61,9 +86,49 @@ protected function tearDown(): void { } static::envReset(); + $this->envRestore(); parent::tearDown(); } + /** + * Restore the process environment captured before the test ran. + * + * EnvTrait::envReset() only reverses names recorded by envSet(). Code under + * test can call putenv() directly, and those values would otherwise be read + * by every later test in the same process. + */ + protected function envRestore(): void { + foreach (array_keys(getenv()) as $name) { + if (!array_key_exists($name, $this->processEnvBackup)) { + putenv($name); + } + } + + foreach ($this->processEnvBackup as $name => $value) { + if (getenv($name) !== $value) { + putenv($name . '=' . $value); + } + } + + $_ENV = $this->globalEnvBackup; + $_SERVER = $this->globalServerBackup; + } + + /** + * Unset the environment variables that a project's .env file defines. + * + * Handlers read the environment before the project's .env file, so a + * variable exported by the shell running the suite would win over the + * fixture. + */ + protected static function envUnsetProjectVars(): void { + static::envUnsetPrefix('VORTEX_'); + static::envUnsetPrefix('DRUPAL_'); + static::envUnsetPrefix('LAGOON_'); + static::envUnset('WEBROOT'); + static::envUnset('TZ'); + } + /** * {@inheritdoc} */ From 37b8b388b98ea65a63663cb63f47defefc63462c Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:32:01 +1100 Subject: [PATCH 65/71] Moved maintenance skills to '.vortex/skills' and registered them as the 'vortex' Claude Code plugin. Forward-ported from main 46d9ee2f7338b95580632285a1c2c3510c6138d3. Moved the 4 skills 2.x ships and applied the plugin settings cleanup to the 2.x CLI 'Internal' handler using the 'JsonManipulator::fromFile()' pattern the other 2.x handlers use, since the 2.x 'JsonManipulator' has no 'updateFile()'. --- .claude/settings.json | 11 +++++++++++ .vortex/.claude-plugin/marketplace.json | 15 +++++++++++++++ .vortex/CLAUDE.md | 1 + .vortex/README.md | 1 + .vortex/cli/src/Prompts/Handlers/Internal.php | 16 ++++++++++++++++ .../AiCodeInstructionsHandlerProcessTest.php | 2 ++ .../create-vortex-tooling-release-notes/SKILL.md | 0 .../skills/prepare-vortex-release/SKILL.md | 0 .../skills/propagate-vortex-main-to-2x/SKILL.md | 2 +- .../skills/update-vortex-dev-deps/SKILL.md | 2 +- AGENTS.md | 4 ++++ 11 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 .vortex/.claude-plugin/marketplace.json rename {.claude => .vortex}/skills/create-vortex-tooling-release-notes/SKILL.md (100%) rename {.claude => .vortex}/skills/prepare-vortex-release/SKILL.md (100%) rename {.claude => .vortex}/skills/propagate-vortex-main-to-2x/SKILL.md (99%) rename {.claude => .vortex}/skills/update-vortex-dev-deps/SKILL.md (99%) diff --git a/.claude/settings.json b/.claude/settings.json index 89ed1ce966..829b3ab7c6 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -4,5 +4,16 @@ "Bash(ahoy:*)" ], "deny": [] + }, + "extraKnownMarketplaces": { + "vortex": { + "source": { + "source": "directory", + "path": "./.vortex" + } + } + }, + "enabledPlugins": { + "vortex@vortex": true } } diff --git a/.vortex/.claude-plugin/marketplace.json b/.vortex/.claude-plugin/marketplace.json new file mode 100644 index 0000000000..3eddcb1591 --- /dev/null +++ b/.vortex/.claude-plugin/marketplace.json @@ -0,0 +1,15 @@ +{ + "name": "vortex", + "description": "Plugins for maintaining the Vortex template.", + "owner": { + "name": "DrevOps", + "url": "https://www.drevops.com" + }, + "plugins": [ + { + "name": "vortex", + "source": "./", + "description": "Skills for maintaining the Vortex template." + } + ] +} diff --git a/.vortex/CLAUDE.md b/.vortex/CLAUDE.md index b975f25e84..340468a325 100644 --- a/.vortex/CLAUDE.md +++ b/.vortex/CLAUDE.md @@ -10,6 +10,7 @@ vortex/ ├── .vortex/ # Test harness (removed on install) │ ├── docs/ # Documentation website │ ├── cli/ # Template CLI +│ ├── skills/ # AI agent skills ('vortex' plugin) │ ├── tests/ # Template tests (PHPUnit) │ └── tooling/ # 'drevops/vortex-tooling' Composer package │ ├── src/ # Shipped PHP scripts diff --git a/.vortex/README.md b/.vortex/README.md index fc4d7986b5..88de26b4fb 100644 --- a/.vortex/README.md +++ b/.vortex/README.md @@ -5,6 +5,7 @@ This directory is removed by the Vortex CLI or can be deleted manually. - [`docs`](docs) - documentation for Vortex published to https://www.vortextemplate.com - [`cli`](cli) - self-contained Symfony console application used to install Vortex +- [`skills`](skills) - AI agent skills for maintaining Vortex, loaded by Claude Code as the `vortex` plugin - [`tests`](tests) - unit and functional tests for Vortex - [`tooling`](tooling) - scripts that ship with Vortex, deployed as the `drevops/vortex-tooling` package to https://github.com/drevops/vortex-tooling diff --git a/.vortex/cli/src/Prompts/Handlers/Internal.php b/.vortex/cli/src/Prompts/Handlers/Internal.php index 15cfe9feaf..99efc1aba1 100644 --- a/.vortex/cli/src/Prompts/Handlers/Internal.php +++ b/.vortex/cli/src/Prompts/Handlers/Internal.php @@ -8,6 +8,7 @@ use DrevOps\VortexCli\Utils\Config; use DrevOps\VortexCli\Utils\Env; use DrevOps\VortexCli\Utils\File; +use DrevOps\VortexCli\Utils\JsonManipulator; use DrevOps\VortexCli\Utils\Strings; use DrevOps\VortexCli\Utils\Yaml; @@ -86,6 +87,9 @@ public function process(): void { // Remove Vortex internal files. File::remove($t . DIRECTORY_SEPARATOR . '.vortex'); + + // The template at the installed reference, such as 'stable', can ship + // maintenance skills in '.claude/skills'. File::remove($t . DIRECTORY_SEPARATOR . '.claude' . DIRECTORY_SEPARATOR . 'skills'); File::remove($t . '/.github/FUNDING.yml'); @@ -131,6 +135,18 @@ public function process(): void { } } + // Remove the Vortex maintenance plugin from the Claude Code settings: the + // plugin is the '.vortex' directory, which consumer sites do not receive. + $claude_settings_path = $t . '/.claude/settings.json'; + $cj = JsonManipulator::fromFile($claude_settings_path); + if ($cj instanceof JsonManipulator) { + $cj->removeSubNode('enabledPlugins', 'vortex@vortex'); + $cj->removeMainKeyIfEmpty('enabledPlugins'); + $cj->removeSubNode('extraKnownMarketplaces', 'vortex'); + $cj->removeMainKeyIfEmpty('extraKnownMarketplaces'); + file_put_contents($claude_settings_path, $cj->getContents()); + } + // Execute all queued batch tasks from all handlers. File::runDirectoryTasks($this->config->get(Config::TMP)); } diff --git a/.vortex/cli/tests/Functional/Handlers/AiCodeInstructionsHandlerProcessTest.php b/.vortex/cli/tests/Functional/Handlers/AiCodeInstructionsHandlerProcessTest.php index b0a84a24a5..44c94f04b1 100644 --- a/.vortex/cli/tests/Functional/Handlers/AiCodeInstructionsHandlerProcessTest.php +++ b/.vortex/cli/tests/Functional/Handlers/AiCodeInstructionsHandlerProcessTest.php @@ -17,6 +17,8 @@ public static function dataProviderHandlerProcess(): \Iterator { $test->assertFileExists(static::$sut . '/AGENTS.md'); $test->assertFileExists(static::$sut . '/CLAUDE.md'); $test->assertFileExists(static::$sut . '/.claude/settings.json'); + $test->assertFileNotContainsString(static::$sut . '/.claude/settings.json', 'extraKnownMarketplaces'); + $test->assertFileNotContainsString(static::$sut . '/.claude/settings.json', 'enabledPlugins'); }), ]; yield 'ai_instructions_disabled' => [ diff --git a/.claude/skills/create-vortex-tooling-release-notes/SKILL.md b/.vortex/skills/create-vortex-tooling-release-notes/SKILL.md similarity index 100% rename from .claude/skills/create-vortex-tooling-release-notes/SKILL.md rename to .vortex/skills/create-vortex-tooling-release-notes/SKILL.md diff --git a/.claude/skills/prepare-vortex-release/SKILL.md b/.vortex/skills/prepare-vortex-release/SKILL.md similarity index 100% rename from .claude/skills/prepare-vortex-release/SKILL.md rename to .vortex/skills/prepare-vortex-release/SKILL.md diff --git a/.claude/skills/propagate-vortex-main-to-2x/SKILL.md b/.vortex/skills/propagate-vortex-main-to-2x/SKILL.md similarity index 99% rename from .claude/skills/propagate-vortex-main-to-2x/SKILL.md rename to .vortex/skills/propagate-vortex-main-to-2x/SKILL.md index 6962a51f4f..a97aab9be4 100644 --- a/.claude/skills/propagate-vortex-main-to-2x/SKILL.md +++ b/.vortex/skills/propagate-vortex-main-to-2x/SKILL.md @@ -1,6 +1,6 @@ --- name: propagate-vortex-main-to-2x -description: Forward-port commits that landed on 'main' into the deviated '2.x' development branch. Lists every 'main' commit absent from '2.x', analyses each diff against the current state of '2.x', recommends apply/adapt/skip with a rationale, lets you select, then cherry-picks or hand-reapplies the chosen commits onto one feature branch and opens a single PR via /open-pr. Keeps a decisions ledger so re-runs across the release cycle never re-ask about settled commits. Triggers on 'propagate main to 2.x', 'port main to 2.x', 'forward-port to 2.x', 'bring main commits into 2.x', '/propagate-vortex-main-to-2x'. +description: Forward-port commits that landed on 'main' into the deviated '2.x' development branch. Lists every 'main' commit absent from '2.x', analyses each diff against the current state of '2.x', recommends apply/adapt/skip with a rationale, lets you select, then cherry-picks or hand-reapplies the chosen commits onto one feature branch and opens a single PR via /open-pr. Keeps a decisions ledger so re-runs across the release cycle never re-ask about settled commits. Triggers on 'propagate main to 2.x', 'port main to 2.x', 'forward-port to 2.x', 'bring main commits into 2.x', '/vortex:propagate-vortex-main-to-2x'. user-invocable: true --- diff --git a/.claude/skills/update-vortex-dev-deps/SKILL.md b/.vortex/skills/update-vortex-dev-deps/SKILL.md similarity index 99% rename from .claude/skills/update-vortex-dev-deps/SKILL.md rename to .vortex/skills/update-vortex-dev-deps/SKILL.md index 6ffd76ef55..2c393fac69 100644 --- a/.claude/skills/update-vortex-dev-deps/SKILL.md +++ b/.vortex/skills/update-vortex-dev-deps/SKILL.md @@ -1,6 +1,6 @@ --- name: update-vortex-dev-deps -description: Use when refreshing Composer and Yarn dev dependencies across the three '.vortex/' subsystems (docs, cli, tests). Runs in-range lock-file refreshes, lints each updated subsystem locally (with auto-fix where the subsystem supports it), produces a 'majors-available' report, makes a single bulk commit covering both lock and lint-fix fallout, and opens a PR. Triggers on phrases like 'update vortex dev deps', 'refresh .vortex dependencies', 'bump .vortex lock files', '/update-vortex-dev-deps'. +description: Use when refreshing Composer and Yarn dev dependencies across the three '.vortex/' subsystems (docs, cli, tests). Runs in-range lock-file refreshes, lints each updated subsystem locally (with auto-fix where the subsystem supports it), produces a 'majors-available' report, makes a single bulk commit covering both lock and lint-fix fallout, and opens a PR. Triggers on phrases like 'update vortex dev deps', 'refresh .vortex dependencies', 'bump .vortex lock files', '/vortex:update-vortex-dev-deps'. user-invocable: true --- diff --git a/AGENTS.md b/AGENTS.md index f43950626e..daecc4488d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,6 +7,10 @@ > > For **maintaining the Vortex template itself**, see the maintenance guide: `.vortex/CLAUDE.md` +> +> Vortex maintenance skills live in `.vortex/skills/`. When a task matches +> a skill's `description` and the skill isn't already loaded, read its +> `SKILL.md` and follow it. [//]: # (#;> VORTEX_DEV) From 0a012cb85d490bf2204b8b2ed23baeacfa7cf06e Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:34:24 +1100 Subject: [PATCH 66/71] [#3108] Closed every 'task' output helper with a matching 'pass' or 'fail'. Forward-ported from main 6a8c624a0d0eb2b0a2963c6f803e3d7c8e2ff6d5. Only the 2 new authoring rules apply on 2.x, where the PHP 'TASK()' helper already pairs 'PASS()' and 'FAIL()', so they were added beside the existing pass/fail rule for the Bash scripts. --- .vortex/docs/content/contributing/maintenance/template.mdx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.vortex/docs/content/contributing/maintenance/template.mdx b/.vortex/docs/content/contributing/maintenance/template.mdx index 02fbff04e4..95f4aa40ec 100644 --- a/.vortex/docs/content/contributing/maintenance/template.mdx +++ b/.vortex/docs/content/contributing/maintenance/template.mdx @@ -73,6 +73,13 @@ Please refer to [RFC2119](https://www.ietf.org/rfc/rfc2119.txt) for meaning of w that is starting, so it always reports its outcome, even when the work itself cannot fail. + A `task` MUST NOT open while another `task` is open. A step inside an open + `task`, including each iteration of a loop, uses a `note`. + + A `pass` or a `fail` MAY stand on its own. A check reports `pass` when it + holds and `fail` when it does not. A skipped or finished operation reports + `pass` without a `task` first. + 7. SHOULD include variable values checks with errors and early exit, i.e.: ```shell From 6041eb9451a255c5f6b8e2dee3584f63b051da27 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:35:44 +1100 Subject: [PATCH 67/71] [#3111] Aborted Acquia hook wrappers on unset and empty required values. Forward-ported from main 0cf8a87cd542d7df3afaf4bbfbb0d59620b6f8ba. Hand-applied to the 2.x hooks, which also needed the 'VORTEX_DEBUG' guard made safe under 'set -u' and gained the documented but unread 'VORTEX_PROVISION_ACQUIA_SKIP' check; BATS tests were not ported as 2.x has no BATS suite. --- .../variables/extra/acquia.variables.sh | 3 +++ .../docs/content/development/variables.mdx | 1 + .vortex/docs/content/hosting/acquia.mdx | 13 ++++++++++ hooks/library/copy-db.sh | 20 +++++++-------- hooks/library/copy-files.sh | 18 ++++++------- hooks/library/notify-deployment.sh | 25 ++++++++++--------- hooks/library/provision.sh | 10 +++++--- hooks/library/purge-cache.sh | 18 ++++++------- 8 files changed, 64 insertions(+), 44 deletions(-) diff --git a/.vortex/docs/.utils/variables/extra/acquia.variables.sh b/.vortex/docs/.utils/variables/extra/acquia.variables.sh index ec9ff8a937..30dcee1748 100755 --- a/.vortex/docs/.utils/variables/extra/acquia.variables.sh +++ b/.vortex/docs/.utils/variables/extra/acquia.variables.sh @@ -15,6 +15,9 @@ VORTEX_PURGE_CACHE_ACQUIA_SKIP= # Skip Drupal site provisioning in Acquia environment. VORTEX_PROVISION_ACQUIA_SKIP= +# Skip sending of deployment notifications in Acquia environment. +VORTEX_NOTIFY_ACQUIA_SKIP= + # NewRelic API key, usually of type 'USER'. # # @see https://www.vortextemplate.com/docs/deployment/notifications/newrelic diff --git a/.vortex/docs/content/development/variables.mdx b/.vortex/docs/content/development/variables.mdx index 004834c88e..170d996ff4 100644 --- a/.vortex/docs/content/development/variables.mdx +++ b/.vortex/docs/content/development/variables.mdx @@ -226,6 +226,7 @@ The list below is automatically generated with [Shellvar](https://github.com/ale | `VORTEX_FETCH_DB_SOURCE` | Database fetch source. | `url` | `.env` | | `VORTEX_FETCH_DB_URL` | Database dump file sourced from a URL.

HTTP Basic Authentication credentials should be embedded into the value. | `UNDEFINED` | `.env` | | `VORTEX_FRONTEND_BUILD_SKIP` | Skip building of the front-end assets inside the container image.

Set to `1` to build theme assets on the host or as part of deployment instead of during the container image build. | `UNDEFINED` | `.env` | +| `VORTEX_NOTIFY_ACQUIA_SKIP` | Skip sending of deployment notifications in Acquia environment. | `UNDEFINED` | `ACQUIA ENVIRONMENT` | | `VORTEX_NOTIFY_CHANNELS` | The channels of the notifications.

A combination of comma-separated values: email,slack,newrelic,github,jira,webhook,diffy | `email` | `.env` | | `VORTEX_NOTIFY_EMAIL_FROM` | An email address to send notifications from.

Applies to email notifications. | `webmaster@your-site-domain.example` | `.env` | | `VORTEX_NOTIFY_EMAIL_RECIPIENTS` | Email address(es) to send notifications to.

Applies to email notifications.

Multiple names can be specified as a comma-separated list of email addresses with optional names in the format "email|name". Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" | `webmaster@your-site-domain.example|Webmaster` | `.env` | diff --git a/.vortex/docs/content/hosting/acquia.mdx b/.vortex/docs/content/hosting/acquia.mdx index f132bcbb5a..68740e8435 100644 --- a/.vortex/docs/content/hosting/acquia.mdx +++ b/.vortex/docs/content/hosting/acquia.mdx @@ -43,6 +43,19 @@ pre-configured scripts in the [`hooks/`](https://github.com/drevops/vortex/tree/ directory that trigger on code deployments, code updates, and database copy operations. +To turn off a hook, set its skip variable to `1` in the Acquia UI: + +| Hook | Variable | +|------------------------|--------------------------------------| +| `provision.sh` | `VORTEX_PROVISION_ACQUIA_SKIP` | +| `purge-cache.sh` | `VORTEX_PURGE_CACHE_ACQUIA_SKIP` | +| `notify-deployment.sh` | `VORTEX_NOTIFY_ACQUIA_SKIP` | +| `copy-db.sh` | `VORTEX_TASK_COPY_DB_ACQUIA_SKIP` | +| `copy-files.sh` | `VORTEX_TASK_COPY_FILES_ACQUIA_SKIP` | + +A hook stops with an error when a value it requires is unset or empty. A blank +field in the Acquia UI aborts the hook before it runs. + ### Environment detection Vortex automatically detects when running on Acquia and applies the diff --git a/hooks/library/copy-db.sh b/hooks/library/copy-db.sh index a06acdbffe..bf52a5e0d0 100755 --- a/hooks/library/copy-db.sh +++ b/hooks/library/copy-db.sh @@ -4,23 +4,23 @@ # # Environment variables must be set in Acquia UI globally or for each environment. -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" -pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 - -[ "${VORTEX_TASK_COPY_DB_ACQUIA_SKIP}" = "1" ] && echo "Skipping copying of database between Acquia environments." && exit 0 +[ "${VORTEX_TASK_COPY_DB_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping copying of database between Acquia environments." && exit 0 export VORTEX_PLATFORM=acquia -export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY?not set}" -export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET?not set}" +export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY:?Missing required value.}" +export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET:?Missing required value.}" export VORTEX_ACQUIA_APP_NAME="${VORTEX_ACQUIA_APP_NAME:-${site}}" export VORTEX_TASK_COPY_DB_ACQUIA_SRC="${VORTEX_TASK_COPY_DB_ACQUIA_SRC:-prod}" export VORTEX_TASK_COPY_DB_ACQUIA_DST="${VORTEX_TASK_COPY_DB_ACQUIA_DST:-${target_env}}" -export VORTEX_TASK_COPY_DB_ACQUIA_NAME="${VORTEX_TASK_COPY_DB_ACQUIA_NAME?not set}" +export VORTEX_TASK_COPY_DB_ACQUIA_NAME="${VORTEX_TASK_COPY_DB_ACQUIA_NAME:?Missing required value.}" + +pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 ./vendor/bin/vortex-task copy-db diff --git a/hooks/library/copy-files.sh b/hooks/library/copy-files.sh index c432622059..b2f1760784 100755 --- a/hooks/library/copy-files.sh +++ b/hooks/library/copy-files.sh @@ -4,23 +4,23 @@ # # Environment variables must be set in Acquia UI globally or for each environment. -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" -pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 - -[ "${VORTEX_TASK_COPY_FILES_ACQUIA_SKIP}" = "1" ] && echo "Skipping copying of files between Acquia environments." && exit 0 +[ "${VORTEX_TASK_COPY_FILES_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping copying of files between Acquia environments." && exit 0 export VORTEX_PLATFORM=acquia -export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY?not set}" -export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET?not set}" +export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY:?Missing required value.}" +export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET:?Missing required value.}" export VORTEX_ACQUIA_APP_NAME="${VORTEX_ACQUIA_APP_NAME:-${site}}" export VORTEX_TASK_COPY_FILES_ACQUIA_SRC="${VORTEX_TASK_COPY_FILES_ACQUIA_SRC:-prod}" export VORTEX_TASK_COPY_FILES_ACQUIA_DST="${VORTEX_TASK_COPY_FILES_ACQUIA_DST:-${target_env}}" +pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 + ./vendor/bin/vortex-task copy-files popd >/dev/null || exit 1 diff --git a/hooks/library/notify-deployment.sh b/hooks/library/notify-deployment.sh index 45cd103240..6f970da90f 100755 --- a/hooks/library/notify-deployment.sh +++ b/hooks/library/notify-deployment.sh @@ -3,26 +3,25 @@ # Acquia Cloud hook: Send deployment notifications. # -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" -branch="${3}" -ref="${4}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" +branch="${3:?Missing required branch name.}" +ref="${4:?Missing required commit reference.}" + +[ "${VORTEX_NOTIFY_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping sending of deployment notifications in Acquia environment." && exit 0 # Custom domain name for the environment, including subdomain. # Examples: "dev.example.com", "test.example.com", "www.example.com" VORTEX_NOTIFY_ENVIRONMENT_DOMAIN="${VORTEX_NOTIFY_ENVIRONMENT_DOMAIN:-}" -pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 - -# Set URL to Acquia domain by default. -url="https://${AH_SITE_NAME}.${AH_REALM:-prod}.acquia-sites.com" - -# Use custom domain in URL, if provided. +# Use custom domain in URL, if provided, or the Acquia domain otherwise. if [ -n "${VORTEX_NOTIFY_ENVIRONMENT_DOMAIN}" ]; then url="https://${VORTEX_NOTIFY_ENVIRONMENT_DOMAIN}" +else + url="https://${AH_SITE_NAME:?Missing required value.}.${AH_REALM:-prod}.acquia-sites.com" fi export VORTEX_NOTIFY_PROJECT="${site}" @@ -32,6 +31,8 @@ export VORTEX_NOTIFY_PR_NUMBER="" export VORTEX_NOTIFY_LABEL="${branch}" export VORTEX_NOTIFY_ENVIRONMENT_URL="${url}" +pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 + ./vendor/bin/vortex-notify popd >/dev/null || exit 1 diff --git a/hooks/library/provision.sh b/hooks/library/provision.sh index 3fdeee319f..82ee8541be 100755 --- a/hooks/library/provision.sh +++ b/hooks/library/provision.sh @@ -3,11 +3,13 @@ # Acquia Cloud hook: Provision site. # -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" + +[ "${VORTEX_PROVISION_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping provisioning of the site in Acquia environment." && exit 0 pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 diff --git a/hooks/library/purge-cache.sh b/hooks/library/purge-cache.sh index 58513bffc6..f2537f599b 100755 --- a/hooks/library/purge-cache.sh +++ b/hooks/library/purge-cache.sh @@ -4,23 +4,23 @@ # # Environment variables must be set in Acquia UI globally or for each environment. -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" -pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 - -[ "${VORTEX_PURGE_CACHE_ACQUIA_SKIP}" = "1" ] && echo "Skipping purging of cache in Acquia environment." && exit 0 +[ "${VORTEX_PURGE_CACHE_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping purging of cache in Acquia environment." && exit 0 export VORTEX_PLATFORM=acquia -export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY?not set}" -export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET?not set}" +export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY:?Missing required value.}" +export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET:?Missing required value.}" export VORTEX_ACQUIA_APP_NAME="${VORTEX_ACQUIA_APP_NAME:-${site}}" export VORTEX_TASK_PURGE_CACHE_ACQUIA_ENV="${VORTEX_TASK_PURGE_CACHE_ACQUIA_ENV:-${target_env}}" export VORTEX_TASK_PURGE_CACHE_ACQUIA_DOMAINS_FILE="${VORTEX_TASK_PURGE_CACHE_ACQUIA_DOMAINS_FILE:-"/var/www/html/${site}.${target_env}/hooks/library/domains.txt"}" +pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 + ./vendor/bin/vortex-task purge-cache popd >/dev/null || exit 1 From f0cd93c55d2ae18acdbac4ef84bef54eff70d1b0 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:36:36 +1100 Subject: [PATCH 68/71] [#3210] Fixed DCLint and Gitleaks scanning an empty directory in CircleCI. Forward-ported from main a8b2031ad2d7db2302244509256fcb30b9c1854f. Only the CircleCI half applies, since 2.x GitHub Actions jobs run on the host where bind mounts work, so the 'lint.ci.sh' guard checks '.circleci/config.yml' only and the 'docker-compose.yml' directive was dropped because the 2.x '.dclintrc' already disables 'no-duplicate-exported-ports'. --- .circleci/config.yml | 14 ++++++++++++-- .vortex/tests/lint.ci.sh | 10 ++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4e1d8252d5..dec987c583 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -157,9 +157,14 @@ jobs: #;> TOOL_HADOLINT #;< TOOL_DCLINT + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:3.1.0 . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:3.1.0 .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] #;> TOOL_DCLINT - run: @@ -249,10 +254,15 @@ jobs: command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] #;< CI_GITLEAKS + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:v8.30.1 dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:v8.30.1 dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] #;> CI_GITLEAKS # Test the provisioned site. Runs in parallel with the lint and build jobs. diff --git a/.vortex/tests/lint.ci.sh b/.vortex/tests/lint.ci.sh index 1bfb430f17..6b95d265cd 100755 --- a/.vortex/tests/lint.ci.sh +++ b/.vortex/tests/lint.ci.sh @@ -24,4 +24,14 @@ else php "${ROOT_DIR}/.vortex/tests/generate-vortex-dev-circleci" --check fi +echo "Checking that CircleCI steps do not bind-mount the working directory into a container." +# CircleCI jobs run against a remote Docker engine, so the engine resolves a +# bind mount of the working directory to an empty directory. +mounts="$(grep -n -E '(-v|--volume)[ =]"?[$]([{]?PWD|[(]pwd[)])' "${ROOT_DIR}/.circleci/config.yml")" || [ "$?" -eq 1 ] +if [ -n "${mounts}" ]; then + echo "${mounts}" + echo "These steps bind-mount the working directory, which the remote Docker engine sees as an empty directory. Copy the files in with 'docker cp' instead." + exit 1 +fi + # LCOV_EXCL_STOP From 4d6c059dd9ae5d781e2234b5be66506c4c4abe00 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:38:03 +1100 Subject: [PATCH 69/71] [#3209] Documented how '.env' reaches PHP-FPM through the Lagoon entrypoint and when a change to it applies. Forward-ported from main 2e5d2844e760d9c4a15bcc588af9399ff157e53f. The 2.x pages have not had main's earlier rewrite of these sections, so the paragraphs were inserted into the existing text with the 2.x 'appserver' and 'webserver' service names, and the 2.x claims they contradicted were corrected. --- .../development/environment/README.mdx | 23 ++++++++++++++++-- .../development/environment/docker.mdx | 24 +++++++++++++++++-- .../docs/content/development/variables.mdx | 3 +++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/.vortex/docs/content/development/environment/README.mdx b/.vortex/docs/content/development/environment/README.mdx index 3bebc5bbaf..fa6ff56622 100644 --- a/.vortex/docs/content/development/environment/README.mdx +++ b/.vortex/docs/content/development/environment/README.mdx @@ -124,8 +124,8 @@ all containers and downloaded dependency packages (`vendor`, `node_modules` etc. To update environment variables in your local development environment: 1. Edit variables in `.env.local` file -2. Apply changes by re-creating the containers (a plain restart does not - re-read the `.env` files): +2. Apply changes to the variables that `docker-compose.yml` lists by + re-creating the containers: @@ -140,4 +140,23 @@ To update environment variables in your local development environment: +Drupal also reads variables that `docker-compose.yml` doesn't pass, such as +`DRUPAL_CLAMAV_ENABLED`. For web requests, PHP-FPM loads them from `.env` +when its container starts, never from `.env.local`. To apply a change to +`.env`, run `ahoy restart` (or `docker compose restart`): `ahoy up` +recreates a container only when its configuration changes, and these +variables aren't part of it. + +To set such a variable on your machine only, for example a credential that +must stay out of the committed `.env`, pass it to the `appserver` service in +`docker-compose.override.yml`. Then set its value in `.env.local` and run +`ahoy up`: + +```yaml title="docker-compose.override.yml" +services: + appserver: + environment: + DRUPAL_EXAMPLE_API_KEY: ${DRUPAL_EXAMPLE_API_KEY:-} +``` + ➡️ See [Variables](../variables.mdx) for the full variable reference. diff --git a/.vortex/docs/content/development/environment/docker.mdx b/.vortex/docs/content/development/environment/docker.mdx index c69b90836f..f839474e90 100644 --- a/.vortex/docs/content/development/environment/docker.mdx +++ b/.vortex/docs/content/development/environment/docker.mdx @@ -154,8 +154,9 @@ By default, Docker Compose reads environment variables from the `.env` file. **Vortex** additionally reads the `.env.local` file, so you can override environment variables locally without modifying the `.env` file. -The variables read from `.env` and `.env.local` files then passed into the -containers. +Docker Compose uses these values to fill in the `${VAR}` references in +`docker-compose.yml`. A container gets only the variables its service lists +under `environment`. This section only defines 2 types of variables: @@ -190,6 +191,25 @@ where of `*default-url`, which is a reference to the `default-url` YAML anchor defined above. +The `cli`, `webserver` and `appserver` services build on Lagoon images, which +load `.env` themselves. When a container starts, the image's entrypoint reads +`.env` from `/app` before it launches the main process. The entrypoint keeps +any variable the container already has. In the `appserver` container, the main +process is PHP-FPM, which passes the loaded variables on to every request it +handles. That's how Drupal gets the `.env` variables that `docker-compose.yml` +doesn't list, such as `DRUPAL_CLAMAV_ENABLED`. + +PHP-FPM keeps the values it started with. A change to such a variable doesn't +alter the container's configuration, so `ahoy up` leaves the container running. +Run `ahoy restart` (or `docker compose restart`) instead, so the entrypoint +reads `.env` again. + +The Lagoon images never read `.env.local`. For a variable that +`docker-compose.yml` doesn't list, web requests get the value from `.env` +only. To use a value from `.env.local`, list the variable in +`docker-compose.override.yml`, as +[Environment variables](README.mdx#environment-variables) shows. + See more information about environment variables in the [official documentation](https://docs.docker.com/compose/environment-variables/set-environment-variables/). diff --git a/.vortex/docs/content/development/variables.mdx b/.vortex/docs/content/development/variables.mdx index 170d996ff4..e6104e6b17 100644 --- a/.vortex/docs/content/development/variables.mdx +++ b/.vortex/docs/content/development/variables.mdx @@ -34,6 +34,9 @@ and should not be committed to the repository. It is a good practice to store local overrides and sensitive information in `.env.local` to keep them separate from the main `.env` file. +To apply a change to either file, see [Environment > Environment +variables](environment/README.mdx#environment-variables). + ## Override order (bottom values win) - default value in container taken from image From 43b6970aebde8231158ed851327741995959d332 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:39:43 +1100 Subject: [PATCH 70/71] Added custom PHP ini support to the 'cli' and 'appserver' containers and disabled session upload progress. Forward-ported from main 6eefbea5f1ff0a2b54b2711c8b7d8ddb6a3d5db0 and 1fa8510732b6f51d1fa07f33b206c364ca7e4427. The 2.x PHP-FPM service is 'appserver', so the subtest asserts 'php-fpm -i' in that container and the docs name it, while the config directory stays '.docker/config/php' to match the 'php.dockerfile' naming used by the other 2.x config directories. --- .docker/cli.dockerfile | 2 ++ .docker/config/cli/custom.ini | 1 + .docker/config/php/custom.ini | 6 +++++ .docker/php.dockerfile | 2 ++ .../development/environment/docker.mdx | 24 +++++++++++++++++++ .../content/development/environment/drush.mdx | 4 +++- .../content/development/security/README.mdx | 12 ++++++++++ .vortex/docs/cspell.json | 1 + .../Functional/DockerComposeWorkflowTest.php | 2 ++ .../Subtests/SubtestDockerComposeTrait.php | 22 +++++++++++++++++ 10 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 .docker/config/cli/custom.ini create mode 100644 .docker/config/php/custom.ini diff --git a/.docker/cli.dockerfile b/.docker/cli.dockerfile index 3bc2c75ffc..4cf78f5d70 100644 --- a/.docker/cli.dockerfile +++ b/.docker/cli.dockerfile @@ -66,6 +66,8 @@ RUN apk add --no-cache ncurses pv tzdata autoconf g++ make && \ docker-php-ext-install pcntl && \ apk del g++ make autoconf +COPY ./.docker/config/cli/custom.ini /usr/local/etc/php/conf.d/custom.ini + # Add patches and scripts. COPY patches /app/patches COPY scripts /app/scripts diff --git a/.docker/config/cli/custom.ini b/.docker/config/cli/custom.ini new file mode 100644 index 0000000000..f6d0b52266 --- /dev/null +++ b/.docker/config/cli/custom.ini @@ -0,0 +1 @@ +; Custom configuration for the CLI service. diff --git a/.docker/config/php/custom.ini b/.docker/config/php/custom.ini new file mode 100644 index 0000000000..c5a72b5710 --- /dev/null +++ b/.docker/config/php/custom.ini @@ -0,0 +1,6 @@ +; Custom configuration for the PHP service. + +[Session] +; Drupal does not use session upload progress, so it is turned off to reduce +; the attack surface of multipart requests. +session.upload_progress.enabled = Off diff --git a/.docker/php.dockerfile b/.docker/php.dockerfile index 590a502ab3..4b9644a2f6 100644 --- a/.docker/php.dockerfile +++ b/.docker/php.dockerfile @@ -14,4 +14,6 @@ FROM uselagoon/php-8.4-fpm:26.10.0 # hadolint ignore=DL3018 # the package set tracks the pinned base image RUN apk add --no-cache tzdata +COPY ./.docker/config/php/custom.ini /usr/local/etc/php/conf.d/custom.ini + COPY --from=cli /app /app diff --git a/.vortex/docs/content/development/environment/docker.mdx b/.vortex/docs/content/development/environment/docker.mdx index f839474e90..49029a1806 100644 --- a/.vortex/docs/content/development/environment/docker.mdx +++ b/.vortex/docs/content/development/environment/docker.mdx @@ -268,6 +268,30 @@ Networks section defines the networks that are used to connect containers to each other. [Pygmy](pygmy.mdx) provides the default `amazeeio-network` network that is used to connect all containers together. +## PHP configuration + +The `cli` and `appserver` images copy a `custom.ini` file from +`.docker/config/` into PHP's `conf.d` directory. Set PHP ini directives for a +service in its file: + +| Service | File | Applies to | +|-------------|---------------------------------|----------------------------------------------------------------| +| `cli` | `.docker/config/cli/custom.ini` | Commands that run in the container, such as Composer and Drush | +| `appserver` | `.docker/config/php/custom.ini` | Web requests that PHP-FPM serves | + +PHP reads `conf.d` in alphabetical order, so `custom.ini` loads after +Lagoon's `00-lagoon-php.ini` and overrides its defaults. Those defaults +include the values of `PHP_*` environment variables, such as +`PHP_MEMORY_LIMIT`. The `appserver` file ships with session upload progress +turned off: see [PHP settings](../security/README.mdx#php-settings). + +In the `cli` container, PHP loads +[`drush/php-ini/drush.ini`](drush.mdx#php-runtime-configuration) last, so a +directive set in both files takes its `drush.ini` value. + +The images include `custom.ini` at build time. After you change it, rebuild +the images and recreate the containers with `ahoy up --build`. + ## Build context and `.dockerignore` When an image is built, Docker sends a **build context** - the set of files it diff --git a/.vortex/docs/content/development/environment/drush.mdx b/.vortex/docs/content/development/environment/drush.mdx index 5e79290fb7..8ef2f54692 100644 --- a/.vortex/docs/content/development/environment/drush.mdx +++ b/.vortex/docs/content/development/environment/drush.mdx @@ -68,7 +68,9 @@ including Drush commands, by editing the `drush/php-ini/drush.ini` file. This file is auto-discovered via the `PHP_INI_SCAN_DIR` environment variable, which is pre-configured in both the Docker CLI container and Acquia deployment hooks. Every PHP CLI process that loads this scan path picks the file up, not -only Drush. +only Drush. For web requests, set PHP directives in +`.docker/config/php/custom.ini`. See +[PHP configuration](docker.mdx#php-configuration). Any valid PHP ini directive can be added to this file to adjust the runtime behavior of those processes. diff --git a/.vortex/docs/content/development/security/README.mdx b/.vortex/docs/content/development/security/README.mdx index cd519ff95f..1f218101d7 100644 --- a/.vortex/docs/content/development/security/README.mdx +++ b/.vortex/docs/content/development/security/README.mdx @@ -23,6 +23,18 @@ under UI control there. The credentials come from the `DRUPAL_SHIELD_USER` and full entry, including the overrides that disable Shield for one environment or open the Let's Encrypt challenge path. +## PHP settings + +The `appserver` container turns off PHP's session upload progress tracking +with `session.upload_progress.enabled = Off` in +`.docker/config/php/custom.ini`. The tracking writes upload request data into +PHP's own session storage before Drupal starts, and Drupal never reads it. +File uploads, including anonymous ones, work with the setting off. Drupal's +optional upload progress bar requires the PECL `uploadprogress` extension. + +The setting applies wherever the **Vortex** images run: locally, in CI and on +Lagoon. On Acquia, the platform's own PHP settings apply. + ## Continuous integration Both scans run in the diff --git a/.vortex/docs/cspell.json b/.vortex/docs/cspell.json index c3aca903d6..352acfba6b 100644 --- a/.vortex/docs/cspell.json +++ b/.vortex/docs/cspell.json @@ -99,6 +99,7 @@ "testmode", "toml", "updatedb", + "uploadprogress", "uselagoon", "Valkey", "vfsstream", diff --git a/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php b/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php index eab49ab286..d1f8567995 100644 --- a/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php +++ b/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php @@ -42,6 +42,8 @@ public function testDockerComposeWorkflowFull(): void { $this->subtestDockerComposeDatabaseConfig(); + $this->subtestDockerComposePhpConfig(); + $this->subtestSolr(); $this->logSubstep('Installing development dependencies'); diff --git a/.vortex/tests/phpunit/Traits/Subtests/SubtestDockerComposeTrait.php b/.vortex/tests/phpunit/Traits/Subtests/SubtestDockerComposeTrait.php index 27bc0962cc..59a1917c19 100644 --- a/.vortex/tests/phpunit/Traits/Subtests/SubtestDockerComposeTrait.php +++ b/.vortex/tests/phpunit/Traits/Subtests/SubtestDockerComposeTrait.php @@ -337,6 +337,28 @@ protected function subtestDockerComposeDatabaseConfig(): void { $this->logStepFinish(); } + protected function subtestDockerComposePhpConfig(): void { + $this->logStepStart(); + + $this->cmd( + 'docker compose exec -T cli php --ini', + '/usr/local/etc/php/conf.d/custom.ini', + 'CLI parses the shipped custom.ini' + ); + + $this->cmd( + 'docker compose exec -T appserver php-fpm -i', + [ + '* Server API => FPM/FastCGI', + '* /usr/local/etc/php/conf.d/custom.ini', + '* session.upload_progress.enabled => Off => Off', + ], + 'PHP-FPM parses the shipped custom.ini and turns off session upload progress' + ); + + $this->logStepFinish(); + } + protected function subtestSolr(): void { $this->logStepStart(); From eedbde1f6fd4702873c37dbfe0b83cd783b85eca Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Mon, 26 Oct 2026 00:40:25 +1100 Subject: [PATCH 71/71] Updated snapshots. --- .../_baseline/.docker/cli.dockerfile | 7 +- .../_baseline/.docker/config/cli/custom.ini | 1 + .../_baseline/.docker/config/php/custom.ini | 6 + .../_baseline/.docker/php.dockerfile | 2 + .../handler_process/_baseline/.dockerignore | 3 + .../Fixtures/handler_process/_baseline/.env | 8 +- .../.github/workflows/build-test-deploy.yml | 5 + .../handler_process/_baseline/behat.yml | 8 +- .../handler_process/_baseline/composer.json | 9 +- .../_baseline/docker-compose.yml | 1 + .../handler_process/_baseline/rector.php | 38 +- .../Drupal/EnvironmentSettingsTest.php | 70 ++++ .../tests/phpunit/Drupal/SettingsTestCase.php | 42 ++ .../phpunit/Drupal/SwitchableSettingsTest.php | 383 ++++++++++++++---- .../EnableDevelopmentModulesDeployStep.php | 3 +- .../includes/modules/settings.clamav.php | 2 +- .../includes/modules/settings.fast404.php | 28 -- .../includes/modules/settings.fast_404.php | 61 +++ .../includes/modules/settings.redis.php | 2 +- .../modules/settings.reroute_email.php | 18 +- .../includes/modules/settings.sdc_devel.php | 10 + .../includes/modules/settings.shield.php | 17 +- .../ciprovider_circleci/.circleci/config.yml | 19 +- .../ciprovider_circleci/.dockerignore | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../.circleci/config.yml | 19 +- .../.dockerignore | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../code_provider_other/renovate.json | 2 +- .../EnableDevelopmentModulesDeployStep.php | 2 +- .../EnableDevelopmentModulesDeployStep.php | 4 +- .../composer.json | 2 +- .../docker-compose.yml | 6 +- .../Drupal/EnvironmentSettingsTest.php | 8 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 2 +- .../EnableDevelopmentModulesDeployStep.php | 4 +- .../db_fetch_source_acquia/.env | 4 +- .../db_fetch_source_container_registry/.env | 4 +- .../handler_process/db_fetch_source_ftp/.env | 4 +- .../db_fetch_source_lagoon/.env | 4 +- .../handler_process/db_fetch_source_s3/.env | 4 +- .../.circleci/config.yml | 19 +- .../deploy_types_all_circleci/.dockerignore | 2 +- .../deploy_types_all_circleci/.env | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../handler_process/deploy_types_all_gha/.env | 2 +- .../.github/workflows/build-test-deploy.yml | 6 +- .../deploy_types_artifact/.env | 2 +- .../.github/workflows/build-test-deploy.yml | 6 +- .../handler_process/deploy_types_lagoon/.env | 2 +- .../.github/workflows/build-test-deploy.yml | 2 +- .../.circleci/config.yml | 19 +- .../deploy_types_none_circleci/.dockerignore | 2 +- .../deploy_types_none_circleci/.env | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../deploy_types_none_gha/.env | 2 +- .../.github/workflows/build-test-deploy.yml | 2 +- .../.circleci/config.yml | 19 +- .../.dockerignore | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../hosting_acquia/.dockerignore | 4 +- .../handler_process/hosting_acquia/.env | 8 +- .../.github/workflows/build-test-deploy.yml | 6 +- .../handler_process/hosting_acquia/behat.yml | 2 +- .../hosting_acquia/composer.json | 2 +- .../EnableDevelopmentModulesDeployStep.php | 3 +- .../includes/modules/settings.clamav.php | 2 +- .../includes/modules/settings.fast404.php | 28 -- .../includes/modules/settings.fast_404.php | 61 +++ .../includes/modules/settings.redis.php | 2 +- .../modules/settings.reroute_email.php | 18 +- .../includes/modules/settings.sdc_devel.php | 10 + .../includes/modules/settings.shield.php | 17 +- .../hosting_acquia/hooks/library/copy-db.sh | 20 +- .../hooks/library/copy-files.sh | 18 +- .../hooks/library/notify-deployment.sh | 25 +- .../hosting_acquia/hooks/library/provision.sh | 10 +- .../hooks/library/purge-cache.sh | 18 +- .../handler_process/hosting_acquia/rector.php | 4 +- .../Drupal/EnvironmentSettingsTest.php | 88 +++- .../tests/phpunit/Drupal/SettingsTestCase.php | 11 +- ...ngs.fast404.php => -settings.fast_404.php} | 0 .../includes/modules/-settings.sdc_devel.php} | 0 .../handler_process/hosting_lagoon/.env | 8 +- .../.github/workflows/build-test-deploy.yml | 2 +- .../hosting_lagoon/composer.json | 4 +- .../hosting_lagoon/docker-compose.yml | 14 +- .../Drupal/EnvironmentSettingsTest.php | 60 ++- .../.dockerignore | 4 +- .../hosting_project_name___acquia/.env | 8 +- .../.github/workflows/build-test-deploy.yml | 6 +- .../hosting_project_name___acquia/behat.yml | 2 +- .../composer.json | 2 +- .../EnableDevelopmentModulesDeployStep.php | 3 +- .../includes/modules/settings.clamav.php | 2 +- .../includes/modules/settings.fast404.php | 28 -- .../includes/modules/settings.fast_404.php | 61 +++ .../includes/modules/settings.redis.php | 2 +- .../modules/settings.reroute_email.php | 18 +- .../includes/modules/settings.sdc_devel.php | 10 + .../includes/modules/settings.shield.php | 17 +- .../hooks/library/copy-db.sh | 20 +- .../hooks/library/copy-files.sh | 18 +- .../hooks/library/notify-deployment.sh | 25 +- .../hooks/library/provision.sh | 10 +- .../hooks/library/purge-cache.sh | 18 +- .../hosting_project_name___acquia/rector.php | 4 +- .../Drupal/EnvironmentSettingsTest.php | 88 +++- .../tests/phpunit/Drupal/SettingsTestCase.php | 11 +- .../includes/modules/-settings.fast_404.php | 0 .../includes/modules/-settings.sdc_devel.php | 0 .../hosting_project_name___lagoon/.env | 8 +- .../.github/workflows/build-test-deploy.yml | 2 +- .../composer.json | 4 +- .../docker-compose.yml | 14 +- .../Drupal/EnvironmentSettingsTest.php | 60 ++- .../.circleci/config.yml | 19 +- .../migration_disabled_circleci/.dockerignore | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../migration_disabled_lagoon/.env | 8 +- .../.github/workflows/build-test-deploy.yml | 2 +- .../migration_disabled_lagoon/composer.json | 4 +- .../docker-compose.yml | 14 +- .../Drupal/EnvironmentSettingsTest.php | 60 ++- .../handler_process/migration_enabled/.env | 4 +- .../migration_enabled/composer.json | 4 +- .../migration_enabled/docker-compose.yml | 4 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../tests/phpunit/Drupal/SettingsTestCase.php | 2 +- .../.circleci/config.yml | 19 +- .../migration_enabled_circleci/.dockerignore | 2 +- .../migration_enabled_circleci/.env | 4 +- .../migration_enabled_circleci/composer.json | 4 +- .../docker-compose.yml | 4 +- .../Drupal/EnvironmentSettingsTest.php | 4 +- .../tests/phpunit/Drupal/SettingsTestCase.php | 2 +- .../migration_enabled_lagoon/.env | 8 +- .../.github/workflows/build-test-deploy.yml | 2 +- .../migration_enabled_lagoon/composer.json | 4 +- .../docker-compose.yml | 14 +- .../Drupal/EnvironmentSettingsTest.php | 62 ++- .../tests/phpunit/Drupal/SettingsTestCase.php | 2 +- .../migration_fetch_source_acquia/.env | 2 +- .../composer.json | 4 +- .../docker-compose.yml | 4 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../tests/phpunit/Drupal/SettingsTestCase.php | 2 +- .../.env | 2 +- .../composer.json | 4 +- .../docker-compose.yml | 4 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../tests/phpunit/Drupal/SettingsTestCase.php | 2 +- .../migration_fetch_source_ftp/.env | 2 +- .../migration_fetch_source_ftp/composer.json | 4 +- .../docker-compose.yml | 4 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../tests/phpunit/Drupal/SettingsTestCase.php | 2 +- .../migration_fetch_source_lagoon/.env | 2 +- .../composer.json | 4 +- .../docker-compose.yml | 4 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../tests/phpunit/Drupal/SettingsTestCase.php | 2 +- .../migration_fetch_source_s3/.env | 2 +- .../migration_fetch_source_s3/composer.json | 4 +- .../docker-compose.yml | 4 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../tests/phpunit/Drupal/SettingsTestCase.php | 2 +- .../migration_fetch_source_url/.env | 4 +- .../migration_fetch_source_url/composer.json | 4 +- .../docker-compose.yml | 4 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../tests/phpunit/Drupal/SettingsTestCase.php | 2 +- .../Drupal/EnvironmentSettingsTest.php | 6 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 2 +- .../modules_no_devel/composer.json | 2 +- .../Drupal/EnvironmentSettingsTest.php | 28 +- .../EnableDevelopmentModulesDeployStep.php | 6 +- .../modules_no_drupal_helpers/composer.json | 2 +- .../composer.json | 2 +- .../Drupal/EnvironmentSettingsTest.php | 8 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 8 +- .../modules_no_fast_404/composer.json | 8 + .../Drupal/EnvironmentSettingsTest.php | 95 +++++ .../phpunit/Drupal/SwitchableSettingsTest.php | 142 +++++++ .../includes/modules/-settings.fast_404.php | 0 .../composer.json | 4 +- .../Drupal/EnvironmentSettingsTest.php | 28 +- .../EnableDevelopmentModulesDeployStep.php | 2 +- .../composer.json | 4 +- .../EnableDevelopmentModulesDeployStep.php | 2 +- .../modules_no_pathauto/composer.json | 4 +- .../EnableDevelopmentModulesDeployStep.php | 2 +- .../modules_no_redirect/composer.json | 2 +- .../EnableDevelopmentModulesDeployStep.php | 2 +- .../modules_no_reroute_email/composer.json | 2 +- .../Drupal/EnvironmentSettingsTest.php | 48 ++- .../phpunit/Drupal/SwitchableSettingsTest.php | 29 +- .../EnableDevelopmentModulesDeployStep.php | 17 +- .../modules_no_robotstxt/composer.json | 2 +- .../Drupal/EnvironmentSettingsTest.php | 8 +- .../EnableDevelopmentModulesDeployStep.php | 4 +- .../modules_no_sdc_devel/composer.json | 2 +- .../Drupal/EnvironmentSettingsTest.php | 40 ++ .../EnableDevelopmentModulesDeployStep.php | 4 +- .../includes/modules/-settings.sdc_devel.php | 0 .../modules_no_seckit/composer.json | 2 +- .../Drupal/EnvironmentSettingsTest.php | 6 +- .../composer.json | 4 +- .../Drupal/EnvironmentSettingsTest.php | 14 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 40 +- .../EnableDevelopmentModulesDeployStep.php | 4 +- .../modules_no_shield/composer.json | 2 +- .../Drupal/EnvironmentSettingsTest.php | 8 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 36 +- .../EnableDevelopmentModulesDeployStep.php | 4 +- .../modules_no_stage_file_proxy/composer.json | 4 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 2 +- .../EnableDevelopmentModulesDeployStep.php | 4 +- .../modules_no_testmode/composer.json | 6 +- .../Drupal/EnvironmentSettingsTest.php | 30 +- .../modules_no_xmlsitemap/composer.json | 6 +- .../Drupal/EnvironmentSettingsTest.php | 8 +- .../EnableDevelopmentModulesDeployStep.php | 2 +- .../modules_none/composer.json | 7 +- .../Drupal/EnvironmentSettingsTest.php | 109 ++++- .../phpunit/Drupal/SwitchableSettingsTest.php | 202 ++++++++- .../EnableDevelopmentModulesDeployStep.php | 7 +- .../includes/modules/-settings.fast_404.php | 0 .../includes/modules/-settings.sdc_devel.php | 0 .../tests/Fixtures/handler_process/names/.env | 6 +- .../Drupal/EnvironmentSettingsTest.php | 8 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 16 +- .../EnableDevelopmentModulesDeployStep.php | 3 +- .../modules/settings.reroute_email.php | 8 +- .../non_interactive_config_file/composer.json | 2 +- .../docker-compose.yml | 4 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 114 +++--- .../EnableDevelopmentModulesDeployStep.php | 2 +- .../docker-compose.yml | 4 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 107 +++-- .../EnableDevelopmentModulesDeployStep.php | 2 +- .../notification_channels_all/.env | 4 +- .../notification_channels_github_only/.env | 2 +- .../notification_channels_jira_only/.env | 2 +- .../notification_channels_newrelic_only/.env | 2 +- .../notification_channels_none/.env | 2 +- .../notification_channels_slack_only/.env | 2 +- .../notification_channels_webhook_only/.env | 2 +- .../provision_database_lagoon/.env | 8 +- .../.github/workflows/build-test-deploy.yml | 2 +- .../provision_database_lagoon/composer.json | 4 +- .../docker-compose.yml | 14 +- .../Drupal/EnvironmentSettingsTest.php | 60 ++- .../handler_process/provision_profile/.env | 10 +- .../.github/workflows/build-test-deploy.yml | 2 +- .../.circleci/config.yml | 19 +- .../provision_profile_circleci/.dockerignore | 2 +- .../provision_profile_circleci/.env | 10 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../services_no_clamav/docker-compose.yml | 4 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 107 +++-- .../EnableDevelopmentModulesDeployStep.php | 2 +- .../services_no_redis/composer.json | 2 +- .../services_no_redis/docker-compose.yml | 4 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 114 +++--- .../EnableDevelopmentModulesDeployStep.php | 2 +- .../services_no_solr/composer.json | 2 +- .../services_no_solr/docker-compose.yml | 6 +- .../Drupal/EnvironmentSettingsTest.php | 8 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 2 +- .../EnableDevelopmentModulesDeployStep.php | 4 +- .../services_none/composer.json | 2 +- .../services_none/docker-compose.yml | 6 +- .../Drupal/EnvironmentSettingsTest.php | 8 +- .../phpunit/Drupal/SwitchableSettingsTest.php | 247 ++++++----- .../EnableDevelopmentModulesDeployStep.php | 4 +- .../starter_drupal_cms_profile/.env | 2 +- .../starter_drupal_cms_profile/composer.json | 12 +- .../starter_drupal_profile/.env | 2 +- .../theme_claro/.docker/cli.dockerfile | 2 +- .../handler_process/theme_claro/rector.php | 2 +- .../theme_custom_non_vortex/.env | 2 +- .../theme_olivero/.docker/cli.dockerfile | 2 +- .../handler_process/theme_olivero/rector.php | 2 +- .../theme_stark/.docker/cli.dockerfile | 2 +- .../handler_process/theme_stark/rector.php | 2 +- .../timezone_circleci/.circleci/config.yml | 19 +- .../timezone_circleci/.dockerignore | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../tools_groups_no_be_lint/composer.json | 13 +- .../includes/modules/settings.fast404.php | 8 - .../includes/modules/settings.fast_404.php | 7 + .../.circleci/config.yml | 19 +- .../.dockerignore | 2 +- .../composer.json | 13 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../includes/modules/settings.fast404.php | 8 - .../includes/modules/settings.fast_404.php | 7 + .../tools_groups_no_be_tests/.dockerignore | 2 +- .../.github/workflows/build-test-deploy.yml | 4 +- .../tools_groups_no_be_tests/composer.json | 14 +- .../tools_groups_no_be_tests/rector.php | 16 +- .../.circleci/config.yml | 19 +- .../.dockerignore | 2 +- .../composer.json | 14 +- .../rector.php | 16 +- .../.circleci/config.yml | 19 +- .../.dockerignore | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../.docker/cli.dockerfile | 2 +- .../rector.php | 2 +- .../.circleci/config.yml | 19 +- .../.docker/cli.dockerfile | 2 +- .../.dockerignore | 2 +- .../rector.php | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../tools_no_behat/composer.json | 10 +- .../handler_process/tools_no_behat/rector.php | 8 +- .../.circleci/config.yml | 19 +- .../tools_no_behat_circleci/.dockerignore | 2 +- .../tools_no_behat_circleci/composer.json | 10 +- .../tools_no_behat_circleci/rector.php | 8 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../.circleci/config.yml | 12 +- .../tools_no_dclint_circleci/.dockerignore | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../.circleci/config.yml | 12 +- .../.dockerignore | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../.circleci/config.yml | 19 +- .../tools_no_eslint_circleci/.dockerignore | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../.docker/cli.dockerfile | 2 +- .../tools_no_eslint_no_theme/rector.php | 2 +- .../.circleci/config.yml | 19 +- .../tools_no_hadolint_circleci/.dockerignore | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../.circleci/config.yml | 19 +- .../tools_no_jest_circleci/.dockerignore | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../tools_no_phpcs/composer.json | 10 +- .../.circleci/config.yml | 19 +- .../tools_no_phpcs_circleci/.dockerignore | 2 +- .../tools_no_phpcs_circleci/composer.json | 10 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../tools_no_phpstan/composer.json | 10 +- .../includes/modules/settings.fast404.php | 8 - .../includes/modules/settings.fast_404.php | 7 + .../.circleci/config.yml | 19 +- .../tools_no_phpstan_circleci/.dockerignore | 2 +- .../tools_no_phpstan_circleci/composer.json | 10 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../includes/modules/settings.fast404.php | 8 - .../includes/modules/settings.fast_404.php | 7 + .../tools_no_phpunit/.dockerignore | 2 +- .../.github/workflows/build-test-deploy.yml | 4 +- .../tools_no_phpunit/composer.json | 6 +- .../tools_no_phpunit/rector.php | 8 +- .../.circleci/config.yml | 19 +- .../tools_no_phpunit_circleci/.dockerignore | 2 +- .../tools_no_phpunit_circleci/composer.json | 6 +- .../tools_no_phpunit_circleci/rector.php | 8 +- .../tools_no_rector/composer.json | 12 +- .../.circleci/config.yml | 19 +- .../tools_no_rector_circleci/.dockerignore | 2 +- .../tools_no_rector_circleci/composer.json | 12 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../.circleci/config.yml | 19 +- .../tools_no_stylelint_circleci/.dockerignore | 2 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../.docker/cli.dockerfile | 2 +- .../tools_no_stylelint_no_theme/rector.php | 2 +- .../tools_no_twig/.dockerignore | 2 +- .../tools_no_twig/composer.json | 4 +- .../.circleci/config.yml | 19 +- .../tools_no_twig_circleci/.dockerignore | 2 +- .../tools_no_twig_circleci/composer.json | 4 +- .../Drupal/EnvironmentSettingsTest.php | 2 +- .../handler_process/tools_none/.dockerignore | 2 +- .../.github/workflows/build-test-deploy.yml | 4 +- .../handler_process/tools_none/composer.json | 11 +- .../includes/modules/settings.fast404.php | 8 - .../includes/modules/settings.fast_404.php | 7 + .../handler_process/version_scheme_other/.env | 2 +- .../version_scheme_semver/.env | 2 +- 385 files changed, 3442 insertions(+), 1431 deletions(-) create mode 100644 .vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/config/cli/custom.ini create mode 100644 .vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/config/php/custom.ini delete mode 100644 .vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.fast404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.fast_404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.sdc_devel.php delete mode 100644 .vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.fast404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.fast_404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.sdc_devel.php rename .vortex/cli/tests/Fixtures/handler_process/hosting_acquia/web/sites/default/includes/modules/{-settings.fast404.php => -settings.fast_404.php} (100%) rename .vortex/cli/tests/Fixtures/handler_process/{hosting_project_name___acquia/web/sites/default/includes/modules/-settings.fast404.php => hosting_acquia/web/sites/default/includes/modules/-settings.sdc_devel.php} (100%) delete mode 100644 .vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.fast404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.fast_404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.sdc_devel.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/web/sites/default/includes/modules/-settings.fast_404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/web/sites/default/includes/modules/-settings.sdc_devel.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/composer.json create mode 100644 .vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/tests/phpunit/Drupal/EnvironmentSettingsTest.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/tests/phpunit/Drupal/SwitchableSettingsTest.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/web/sites/default/includes/modules/-settings.fast_404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/tests/phpunit/Drupal/EnvironmentSettingsTest.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/web/sites/default/includes/modules/-settings.sdc_devel.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/modules_none/web/sites/default/includes/modules/-settings.fast_404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/modules_none/web/sites/default/includes/modules/-settings.sdc_devel.php delete mode 100644 .vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint/web/sites/default/includes/modules/settings.fast404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint/web/sites/default/includes/modules/settings.fast_404.php delete mode 100644 .vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/web/sites/default/includes/modules/settings.fast404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/web/sites/default/includes/modules/settings.fast_404.php delete mode 100644 .vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan/web/sites/default/includes/modules/settings.fast404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan/web/sites/default/includes/modules/settings.fast_404.php delete mode 100644 .vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/web/sites/default/includes/modules/settings.fast404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/web/sites/default/includes/modules/settings.fast_404.php delete mode 100644 .vortex/cli/tests/Fixtures/handler_process/tools_none/web/sites/default/includes/modules/settings.fast404.php create mode 100644 .vortex/cli/tests/Fixtures/handler_process/tools_none/web/sites/default/includes/modules/settings.fast_404.php diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/cli.dockerfile b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/cli.dockerfile index 0ff273086e..f2fd2c17e9 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/cli.dockerfile +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/cli.dockerfile @@ -62,11 +62,12 @@ ENV PHP_INI_SCAN_DIR="${PHP_INI_SCAN_DIR}:/app/drush/php-ini" # Add more tools. # hadolint ignore=DL3018 # the package set tracks the pinned base image RUN apk add --no-cache ncurses pv tzdata autoconf g++ make && \ - pecl install pcov && \ - docker-php-ext-enable pcov && \ + pie install --no-build-tools-check pecl/pcov && \ docker-php-ext-install pcntl && \ apk del g++ make autoconf +COPY ./.docker/config/cli/custom.ini /usr/local/etc/php/conf.d/custom.ini + # Add patches and scripts. COPY patches /app/patches COPY scripts /app/scripts @@ -78,7 +79,7 @@ COPY scripts /app/scripts # to the repository. # The .env file (and other environment files) is copied into the image, as it # may be needed by Composer scripts to access additional variables. -COPY composer.json composer.* patches.lock.* .env* auth* /app/ +COPY composer.json composer.* patches.lock.* .env* /app/ # Install PHP dependencies without development packages to avoid exposing # potential security vulnerabilities in the production environment. diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/config/cli/custom.ini b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/config/cli/custom.ini new file mode 100644 index 0000000000..f6d0b52266 --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/config/cli/custom.ini @@ -0,0 +1 @@ +; Custom configuration for the CLI service. diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/config/php/custom.ini b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/config/php/custom.ini new file mode 100644 index 0000000000..c5a72b5710 --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/config/php/custom.ini @@ -0,0 +1,6 @@ +; Custom configuration for the PHP service. + +[Session] +; Drupal does not use session upload progress, so it is turned off to reduce +; the attack surface of multipart requests. +session.upload_progress.enabled = Off diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/php.dockerfile b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/php.dockerfile index 5808dafd4c..816952940e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/php.dockerfile +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.docker/php.dockerfile @@ -14,4 +14,6 @@ FROM uselagoon/php-8.4-fpm:__VERSION__ # hadolint ignore=DL3018 # the package set tracks the pinned base image RUN apk add --no-cache tzdata +COPY ./.docker/config/php/custom.ini /usr/local/etc/php/conf.d/custom.ini + COPY --from=cli /app /app diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.dockerignore index 969dc2a0ca..3d49b3b105 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.dockerignore @@ -11,6 +11,9 @@ .vscode **/.DS_Store +# Credentials. The package token reaches the build through a build secret. +auth* + # Drupal directories generated by Composer during the image build. web/core web/libraries diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.env b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.env index 1d022ea7ac..9b0a36d4e2 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.env @@ -97,7 +97,7 @@ DRUPAL_CLAMAV_MODE=daemon ################################################################################ # By "provision", we mean the process of initialising the database (from dump -# or fresh install from profile), running updates, appying configuration +# or fresh install from profile), running updates, applying configuration # changes, clearing caches and performing other tasks that prepare the site for # use. # @see https://www.vortextemplate.com/docs/development/provision @@ -125,6 +125,12 @@ VORTEX_PROVISION_FALLBACK_TO_PROFILE=0 # drush config:import from silently overwriting those changes. VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_UPDATE=0 +# Verify that configuration was not changed by post-provision operations. +# If enabled and config files are present, the provision will fail if any +# active configuration item differs from the exported configuration once +# configuration imports, deployment hooks and deploy steps have run. +VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION=0 + # Skip database sanitization. # # Database sanitization is enabled by default in all non-production diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.github/workflows/build-test-deploy.yml index 03f99c6603..fe91abae61 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/.github/workflows/build-test-deploy.yml @@ -447,6 +447,11 @@ jobs: files: | .logs/test_results/**/*.xml + # Placed after the test steps so a dirty tree never suppresses them. + - name: Check that the build left a clean working tree + run: ./vendor/bin/vortex-check-worktree-changes + continue-on-error: ${{ vars.VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE == '1' }} + - name: Setup tmate session if: ${{ !cancelled() && github.event.inputs.enable_terminal }} uses: mxschmitt/action-tmate@__HASH__ # __VERSION__ diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/behat.yml b/.vortex/cli/tests/Fixtures/handler_process/_baseline/behat.yml index a1e99c1d52..3126490c61 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/behat.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/behat.yml @@ -18,8 +18,9 @@ default: - DrevOps\BehatScreenshotExtension\Context\ScreenshotContext formatters: - # Show test progress and explicit fail information whule continuing the test run. - progress_fail: true + # Show test progress and explicit fail information while continuing the test run. + progress: + inline_failures: true # Output test results in JUnit format. junit: @@ -93,9 +94,6 @@ default: - step - datetime - # Show explicit fail information and continue the test run. - DrevOps\BehatFormatProgressFail\FormatExtension: ~ - # Profiles for parallel testing. CI derives the profile number from the index # of the runner it is on minus 'VORTEX_CI_BEHAT_PROFILE_OFFSET', so profiles # stay numbered from 'p0' regardless of which runner Behat starts on. Adding a diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/composer.json b/.vortex/cli/tests/Fixtures/handler_process/_baseline/composer.json index 44ed3eae30..6c0307efdf 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/composer.json @@ -19,6 +19,7 @@ "drupal/devel": "__VERSION__", "drupal/drupal_helpers": "__VERSION__", "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", "drupal/navigation_extra_tools": "__VERSION__", "drupal/pathauto": "__VERSION__", @@ -34,22 +35,17 @@ "drupal/stage_file_proxy": "__VERSION__", "drupal/testmode": "__VERSION__", "drupal/xmlsitemap": "__VERSION__", - "drush/drush": "__VERSION__", - "webflo/drupal-finder": "__VERSION__" + "drush/drush": "__VERSION__" }, "require-dev": { "behat/behat": "__VERSION__", "dantleech/gherkin-lint": "__VERSION__", - "dealerdirect/phpcodesniffer-composer-installer": "__VERSION__", - "drevops/behat-format-progress-fail": "__VERSION__", "drevops/behat-screenshot": "__VERSION__", "drevops/behat-steps": "__VERSION__", "drevops/phpcs-standard": "__VERSION__", "drupal/coder": "__VERSION__", "drupal/drupal-extension": "__VERSION__", "ergebnis/composer-normalize": "__VERSION__", - "lullabot/mink-selenium2-driver": "__VERSION__", - "lullabot/php-webdriver": "__VERSION__", "mglaman/phpstan-drupal": "__VERSION__", "mikey179/vfsstream": "__VERSION__", "palantirnet/drupal-rector": "__VERSION__", @@ -59,7 +55,6 @@ "phpstan/phpstan": "__VERSION__", "phpunit/phpunit": "__VERSION__", "pyrech/composer-changelogs": "__VERSION__", - "rector/rector": "__VERSION__", "softcreatr/jsonpath": "^0.10 || ^1.0", "vincentlanglet/twig-cs-fixer": "__VERSION__" }, diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/_baseline/docker-compose.yml index ba8214bb1a..c0e1a44dbe 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/docker-compose.yml @@ -123,6 +123,7 @@ services: <<: [ *default-volumes, *default-user ] depends_on: - cli + - appserver networks: - default # This is a standard network and is used for all other environments, where requests routing is not required and/or not supported. - amazeeio-network ### This network is supported by Pygmy and used to route all requests to host machine locally. Removed in CI. diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/rector.php b/.vortex/cli/tests/Fixtures/handler_process/_baseline/rector.php index d7679978b9..91aee8fe15 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/rector.php @@ -16,7 +16,6 @@ declare(strict_types=1); -use DrupalFinder\DrupalFinderComposerRuntime; use DrupalRector\Set\DrupalSetProvider; use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector; use Rector\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector; @@ -84,9 +83,9 @@ '*/vendor/*', '*/node_modules/*', ]) - // PHP version upgrade sets - modernizes syntax to PHP 8.4. - // Includes all rules from PHP 5.3 through 8.4. - ->withPhpSets(php84: TRUE) + // PHP version upgrade sets. Called without an argument, the target version + // comes from `composer.json`, so the sets follow the project's PHP version. + ->withPhpSets() // Behat attribute sets - converts annotations to PHP 8 attributes. ->withAttributesSets(behat: TRUE) // Code quality improvement sets. @@ -98,11 +97,10 @@ privatization: TRUE, typeDeclarations: TRUE, ) - // Drupal-specific deprecation fixes. The provider binds each set to a - // `drupal/core` version and only the sets the installed core satisfies are - // loaded, so the set tracks core upgrades without changing this - // configuration. Both calls are required: the provider supplies the sets, - // `withComposerBased()` enables the group. + // Drupal deprecation fixes for the installed `drupal/core` version. Both + // calls are required: the provider supplies the sets, `withComposerBased()` + // enables the group. The sets carry the autoload paths and the file + // extensions Drupal executes PHP from, so this file declares neither. ->withSetProviders(DrupalSetProvider::class) ->withComposerBased(drupal: TRUE) // Additional rules. @@ -110,27 +108,5 @@ DeclareStrictTypesRector::class, YieldDataProviderRector::class, ]) - // Configure Drupal autoloading. - ->withAutoloadPaths((function (): array { - $drupalFinder = new DrupalFinderComposerRuntime(); - $drupalRoot = $drupalFinder->getDrupalRoot(); - - return [ - $drupalRoot . '/core', - $drupalRoot . '/modules', - $drupalRoot . '/themes', - $drupalRoot . '/profiles', - ]; - })()) - // Drupal file extensions. - ->withFileExtensions([ - 'php', - 'module', - 'install', - 'profile', - 'theme', - 'inc', - 'engine', - ]) // Import configuration. ->withImportNames(importNames: FALSE, importDocBlockNames: FALSE); diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 61f9532cdb..2f2c22c35f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -100,11 +100,25 @@ public function testEnvironmentNoOverrides(): void { $settings['config_exclude_modules'] = [ 'devel', 'generated_content', + 'reroute_email', + 'sdc_devel', 'testmode', ]; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_SUT; + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.php', + 'xmlrpc.php', + ]; $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -186,12 +200,26 @@ public function testEnvironmentOverrides(): void { $settings['config_exclude_modules'] = [ 'devel', 'generated_content', + 'reroute_email', + 'sdc_devel', 'testmode', ]; $settings['config_sync_directory'] = 'custom_config'; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_SUT; + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.php', + 'xmlrpc.php', + ]; $settings['file_public_path'] = 'custom_public'; $settings['file_private_path'] = 'custom_private'; $settings['file_temp_path'] = 'custom_temp'; @@ -246,11 +274,25 @@ public function testEnvironmentLocal(): void { $settings['config_exclude_modules'] = [ 'devel', 'generated_content', + 'reroute_email', + 'sdc_devel', 'testmode', ]; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_LOCAL; + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.php', + 'xmlrpc.php', + ]; $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -306,11 +348,25 @@ public function testEnvironmentLocalContainer(): void { $settings['config_exclude_modules'] = [ 'devel', 'generated_content', + 'reroute_email', + 'sdc_devel', 'testmode', ]; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_LOCAL; + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.php', + 'xmlrpc.php', + ]; $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; @@ -368,11 +424,25 @@ public function testEnvironmentGha(): void { $settings['config_exclude_modules'] = [ 'devel', 'generated_content', + 'reroute_email', + 'sdc_devel', 'testmode', ]; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = self::ENVIRONMENT_CI; + $settings['fast404_allow_anon_imagecache'] = TRUE; + $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; + $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + $settings['fast404_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.php', + 'xmlrpc.php', + ]; $settings['file_public_path'] = 'sites/default/files'; $settings['file_private_path'] = 'sites/default/files/private'; $settings['file_temp_path'] = '/tmp'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/cli/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/SettingsTestCase.php index 5c400e8a60..e28c3c0286 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/SettingsTestCase.php @@ -69,6 +69,7 @@ abstract class SettingsTestCase extends TestCase { // Service variables. 'DATABASE_', 'REDIS_', + 'CLAMAV_', 'COMPOSE_', 'GITHUB_', 'PACKAGE_', @@ -233,6 +234,47 @@ protected function requireSettingsFile(array $pre_settings = [], array $pre_conf $this->databases = $databases; } + /** + * Require a per-module settings file with an explicit contrib path. + * + * Per-module settings files guarded by the presence of a module directory + * are unreachable through the site's own contrib path when the module is not + * required by the project. + * + * @param string $module + * Module name as it appears in the `settings..php` file name. + * @param string $contrib_path + * Path to the contrib modules directory to expose to the settings file. + * @param array $pre_settings + * Array of settings to pre-populate. + * @param array $pre_config + * Array of configs to pre-populate. + */ + protected function requireModuleSettingsFile(string $module, string $contrib_path, array $pre_settings = [], array $pre_config = []): void { + $app_root = getcwd() . '/web'; + + if (!file_exists($app_root)) { + throw new \RuntimeException('Could not determine application root.'); + } + + $site_path = 'sites/default'; + $file = implode(DIRECTORY_SEPARATOR, [$app_root, $site_path, 'includes', 'modules', sprintf('settings.%s.php', $module)]); + + if (!file_exists($file)) { + throw new \RuntimeException(sprintf('Settings file %s does not exist.', $file)); + } + + $config = $pre_config; + $settings = $pre_settings; + + require $file; + + $this->app_root = $app_root; + $this->site_path = $site_path; + $this->config = $config; + $this->settings = $settings; + } + /** * Assert that config retrieved from the real settings file match test data. * diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/SwitchableSettingsTest.php index a0419e7ca9..668d590afe 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -4,6 +4,8 @@ namespace Drupal; +use PHPUnit\Framework\Attributes\PreserveGlobalState; +use PHPUnit\Framework\Attributes\RunInSeparateProcess; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; @@ -20,59 +22,100 @@ class SwitchableSettingsTest extends SettingsTestCase { /** - * Test ClamAV configs in Daemon mode with defaults. + * Path to the contrib modules directory fixture. */ - public function testClamavDaemonCustom(): void { - $this->setEnvVars([ - 'DRUPAL_CLAMAV_ENABLED' => TRUE, - 'DRUPAL_CLAMAV_MODE' => 'daemon', - 'CLAMAV_HOST' => 'custom_clamav_host', - 'CLAMAV_PORT' => 3333, - ]); + protected ?string $contribFixture = NULL; - $this->requireSettingsFile(); - - $config['clamav.settings']['scan_mode'] = 0; - $config['clamav.settings']['mode_daemon_tcpip']['hostname'] = 'custom_clamav_host'; - $config['clamav.settings']['mode_daemon_tcpip']['port'] = 3333; + /** + * {@inheritdoc} + */ + protected function tearDown(): void { + if (!is_null($this->contribFixture)) { + $this->removeContribFixture($this->contribFixture); + } - $this->assertConfigContains($config); + parent::tearDown(); } /** - * Test ClamAV configs in Executable mode. + * Test ClamAV config. */ - public function testClamavExecutable(): void { - $this->setEnvVars([ - 'DRUPAL_CLAMAV_ENABLED' => TRUE, - 'CLAMAV_HOST' => 'custom_clamav_host', - 'CLAMAV_PORT' => 3333, - ]); + #[DataProvider('dataProviderClamav')] + public function testClamav(array $vars, array $expected_present, array $expected_absent = []): void { + $this->setEnvVars($vars); $this->requireSettingsFile(); - $config['clamav.settings']['scan_mode'] = 1; - $config['clamav.settings']['executable_path'] = '/usr/bin/clamscan'; - - $this->assertConfigContains($config); + $this->assertConfigContains($expected_present); + $this->assertConfigNotContains($expected_absent); } /** - * Test ClamAV configs in Daemon mode with defaults. + * Data provider for testClamav(). */ - public function testClamavDaemonDefaults(): void { - $this->setEnvVars([ - 'DRUPAL_CLAMAV_ENABLED' => TRUE, - 'DRUPAL_CLAMAV_MODE' => 'daemon', - ]); + public static function dataProviderClamav(): \Iterator { + yield 'daemon mode with custom host and port' => [ + [ + 'DRUPAL_CLAMAV_ENABLED' => 1, + 'DRUPAL_CLAMAV_MODE' => 'daemon', + 'CLAMAV_HOST' => 'custom_clamav_host', + 'CLAMAV_PORT' => 3333, + ], + [ + 'clamav.settings' => [ + 'scan_mode' => 0, + 'mode_daemon_tcpip' => ['hostname' => 'custom_clamav_host', 'port' => 3333], + ], + ], + ]; - $this->requireSettingsFile(); + yield 'daemon mode with defaults' => [ + [ + 'DRUPAL_CLAMAV_ENABLED' => 1, + 'DRUPAL_CLAMAV_MODE' => 'daemon', + ], + [ + 'clamav.settings' => [ + 'scan_mode' => 0, + 'mode_daemon_tcpip' => ['hostname' => 'antivirus', 'port' => 3310], + ], + ], + ]; - $config['clamav.settings']['scan_mode'] = 0; - $config['clamav.settings']['mode_daemon_tcpip']['hostname'] = 'antivirus'; - $config['clamav.settings']['mode_daemon_tcpip']['port'] = 3310; + yield 'executable mode' => [ + [ + 'DRUPAL_CLAMAV_ENABLED' => 1, + 'CLAMAV_HOST' => 'custom_clamav_host', + 'CLAMAV_PORT' => 3333, + ], + [ + 'clamav.settings' => ['scan_mode' => 1, 'executable_path' => '/usr/bin/clamscan'], + ], + ]; - $this->assertConfigContains($config); + yield 'variable not set' => [ + [], + [], + ['clamav.settings' => ['scan_mode' => NULL]], + ]; + + yield 'variable set to an empty value' => [ + ['DRUPAL_CLAMAV_ENABLED' => ''], + [], + ['clamav.settings' => ['scan_mode' => NULL]], + ]; + + yield 'variable set to zero' => [ + ['DRUPAL_CLAMAV_ENABLED' => '0'], + [], + ['clamav.settings' => ['scan_mode' => NULL]], + ]; + + yield 'variable set to a non-numeric truthy value' => [ + ['DRUPAL_CLAMAV_ENABLED' => 'true'], + [], + ['clamav.settings' => ['scan_mode' => NULL]], + ]; } /** @@ -224,76 +267,185 @@ public static function dataProviderEnvironmentIndicator(): \Iterator { } /** - * Test Redis settings. + * Test Fast 404 settings. + * + * Runs isolated so that the module stub owns the 'fast404_preboot()' + * declaration and its invocation marker is conclusive. */ - public function testRedis(): void { - $this->setEnvVars([ - 'DRUPAL_REDIS_ENABLED' => 1, - 'REDIS_HOST' => 'redis_host', - 'REDIS_SERVICE_PORT' => 1234, - 'VORTEX_REDIS_EXTENSION_LOADED' => 1, - ]); + #[DataProvider('dataProviderFast404')] + #[RunInSeparateProcess] + #[PreserveGlobalState(FALSE)] + public function testFast404(bool $module_installed, array $expected_present, array $expected_absent = []): void { + $contrib_path = $this->createContribFixture($module_installed); - $this->requireSettingsFile(); + $this->requireModuleSettingsFile('fast_404', $contrib_path); - $settings['redis.connection']['interface'] = 'PhpRedis'; - $settings['redis.connection']['host'] = 'redis_host'; - $settings['redis.connection']['port'] = 1234; - $settings['cache']['default'] = 'cache.backend.redis'; + $this->assertSettingsContains($expected_present); + $this->assertSettingsNotContains($expected_absent); + $this->assertSame($module_installed, file_exists($contrib_path . '/fast_404/preboot'), 'Preboot invocation'); + } - $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); - unset($this->settings['bootstrap_container_definition']); + /** + * Data provider for testFast404(). + */ + public static function dataProviderFast404(): \Iterator { + yield 'module installed' => [ + TRUE, + [ + 'fast404_exts' => '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i', + 'fast404_allow_anon_imagecache' => TRUE, + 'fast404_url_whitelisting' => TRUE, + 'fast404_whitelist' => ['index.php', 'rss.xml', 'cron.php', 'xmlrpc.php'], + 'fast404_path_check' => FALSE, + 'fast404_respect_redirect' => FALSE, + 'fast404_html' => '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

', + ], + ]; + yield 'module not installed' => [ + FALSE, + [], + [ + 'fast404_exts' => NULL, + 'fast404_allow_anon_imagecache' => NULL, + 'fast404_url_whitelisting' => NULL, + 'fast404_whitelist' => NULL, + 'fast404_path_check' => NULL, + 'fast404_respect_redirect' => NULL, + 'fast404_html' => NULL, + ], + ]; + } + + /** + * Create a contrib modules directory fixture. + * + * The Fast 404 module is not required by the project, so its settings file + * guard can only be satisfied by a stub. + * + * @param bool $with_fast404 + * Create a stub of the Fast 404 module within the fixture. The stub marks + * the directory when its preboot function is called. + * + * @return string + * Path to the contrib modules directory fixture. + */ + protected function createContribFixture(bool $with_fast404): string { + $this->contribFixture = getcwd() . '/.artifacts/tmp/' . uniqid('contrib-'); + + mkdir($this->contribFixture, 0777, TRUE); + + if ($with_fast404) { + $stub = <<<'PHP' + assertSettingsContains($settings); + PHP; + + mkdir($this->contribFixture . '/fast_404'); + file_put_contents($this->contribFixture . '/fast_404/fast404.inc', $stub); + } + + return $this->contribFixture; } /** - * Test Redis settings with REDIS_* environment variables. + * Remove the contrib modules directory fixture. + * + * @param string $path + * Path to the contrib modules directory fixture. */ - public function testRedisVariables(): void { - $this->setEnvVars([ - 'DRUPAL_REDIS_ENABLED' => 1, - 'REDIS_HOST' => 'redis_host', - 'REDIS_SERVICE_PORT' => 6380, - 'VORTEX_REDIS_EXTENSION_LOADED' => 1, - ]); + protected function removeContribFixture(string $path): void { + foreach (glob($path . '/*/*') ?: [] as $file) { + unlink($file); + } - $this->requireSettingsFile(); + foreach (glob($path . '/*', GLOB_ONLYDIR) ?: [] as $dir) { + rmdir($dir); + } + + rmdir($path); + } + + /** + * Test Redis settings. + */ + #[DataProvider('dataProviderRedis')] + public function testRedis(array $vars, bool $expected_enabled, array $expected_settings): void { + $this->setEnvVars($vars); - $settings['redis.connection']['interface'] = 'PhpRedis'; - $settings['redis.connection']['host'] = 'redis_host'; - $settings['redis.connection']['port'] = 6380; - $settings['cache']['default'] = 'cache.backend.redis'; + $this->requireSettingsFile(); - $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); + $this->assertSame($expected_enabled, array_key_exists('bootstrap_container_definition', $this->settings), 'Bootstrap container definition'); unset($this->settings['bootstrap_container_definition']); - $this->assertSettingsContains($settings); + if ($expected_enabled) { + $this->assertSettingsContains($expected_settings); + + return; + } + + $this->assertSettingsNotContains($expected_settings); } /** - * Test Redis settings with custom port. + * Data provider for testRedis(). */ - public function testRedisCustomPort(): void { - $this->setEnvVars([ - 'DRUPAL_REDIS_ENABLED' => 1, - 'REDIS_HOST' => 'custom_redis_host', - 'REDIS_SERVICE_PORT' => 6380, - 'VORTEX_REDIS_EXTENSION_LOADED' => 1, - ]); + public static function dataProviderRedis(): \Iterator { + $disabled_settings = ['redis.connection' => ['interface' => NULL], 'cache' => ['default' => NULL]]; - $this->requireSettingsFile(); + yield 'default port' => [ + [ + 'DRUPAL_REDIS_ENABLED' => 1, + 'REDIS_HOST' => 'redis_host', + 'VORTEX_REDIS_EXTENSION_LOADED' => 1, + ], + TRUE, + [ + 'redis.connection' => ['interface' => 'PhpRedis', 'host' => 'redis_host', 'port' => '6379'], + 'cache' => ['default' => 'cache.backend.redis'], + ], + ]; - // Test custom Redis configuration. - $settings['redis.connection']['interface'] = 'PhpRedis'; - $settings['redis.connection']['host'] = 'custom_redis_host'; - $settings['redis.connection']['port'] = 6380; - $settings['cache']['default'] = 'cache.backend.redis'; + yield 'custom host and port' => [ + [ + 'DRUPAL_REDIS_ENABLED' => 1, + 'REDIS_HOST' => 'custom_redis_host', + 'REDIS_SERVICE_PORT' => 6380, + 'VORTEX_REDIS_EXTENSION_LOADED' => 1, + ], + TRUE, + [ + 'redis.connection' => ['interface' => 'PhpRedis', 'host' => 'custom_redis_host', 'port' => 6380], + 'cache' => ['default' => 'cache.backend.redis'], + ], + ]; - $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); - unset($this->settings['bootstrap_container_definition']); + yield 'variable not set' => [ + ['VORTEX_REDIS_EXTENSION_LOADED' => 1], + FALSE, + $disabled_settings, + ]; + + yield 'variable set to an empty value' => [ + ['DRUPAL_REDIS_ENABLED' => '', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], + FALSE, + $disabled_settings, + ]; + + yield 'variable set to zero' => [ + ['DRUPAL_REDIS_ENABLED' => '0', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], + FALSE, + $disabled_settings, + ]; - $this->assertSettingsContains($settings); + yield 'variable set to a non-numeric truthy value' => [ + ['DRUPAL_REDIS_ENABLED' => 'true', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], + FALSE, + $disabled_settings, + ]; } /** @@ -510,7 +662,7 @@ public static function dataProviderShield(): \Iterator { 'DRUPAL_SHIELD_DISABLED' => 'false', ], [ - 'shield.settings' => ['shield_enable' => FALSE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], + 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], ], ]; yield [ @@ -522,7 +674,19 @@ public static function dataProviderShield(): \Iterator { 'DRUPAL_SHIELD_DISABLED' => 'true', ], [ - 'shield.settings' => ['shield_enable' => FALSE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], + 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], + ], + ]; + yield [ + self::ENVIRONMENT_DEV, + [ + 'DRUPAL_SHIELD_USER' => 'drupal_shield_user', + 'DRUPAL_SHIELD_PASS' => 'drupal_shield_pass', + 'DRUPAL_SHIELD_PRINT' => 'drupal_shield_print', + 'DRUPAL_SHIELD_DISABLED' => '01', + ], + [ + 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], ], ]; @@ -637,6 +801,24 @@ public static function dataProviderShield(): \Iterator { 'shield.settings' => ['method' => NULL, 'paths' => NULL], ], ]; + // ACME challenge with a non-numeric truthy value - should not set. + yield [ + self::ENVIRONMENT_DEV, + [ + 'DRUPAL_SHIELD_USER' => 'drupal_shield_user', + 'DRUPAL_SHIELD_PASS' => 'drupal_shield_pass', + 'DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE' => 'true', + ], + [ + 'shield.settings' => [ + 'shield_enable' => TRUE, + 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], + ], + ], + [ + 'shield.settings' => ['method' => NULL, 'paths' => NULL], + ], + ]; yield [ self::ENVIRONMENT_DEV, @@ -747,12 +929,12 @@ public static function dataProviderRerouteEmail(): \Iterator { ], ]; - // Stage: disabled by default. + // Stage: enabled by default. yield [ self::ENVIRONMENT_STAGE, [], [ - 'reroute_email.settings' => ['enable' => FALSE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'], + 'reroute_email.settings' => ['enable' => TRUE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'], ], ]; @@ -787,6 +969,17 @@ public static function dataProviderRerouteEmail(): \Iterator { ], ]; + // Stage with DRUPAL_REROUTE_EMAIL_DISABLED: forced off. + yield [ + self::ENVIRONMENT_STAGE, + [ + 'DRUPAL_REROUTE_EMAIL_DISABLED' => 1, + ], + [ + 'reroute_email.settings' => ['enable' => FALSE], + ], + ]; + // Custom address and allowed list. yield [ self::ENVIRONMENT_DEV, @@ -831,6 +1024,18 @@ public static function dataProviderRerouteEmail(): \Iterator { 'reroute_email.settings' => ['enable' => FALSE], ], ]; + + // DRUPAL_REROUTE_EMAIL_DISABLED with a non-numeric truthy value: not + // disabled. + yield [ + self::ENVIRONMENT_DEV, + [ + 'DRUPAL_REROUTE_EMAIL_DISABLED' => 'true', + ], + [ + 'reroute_email.settings' => ['enable' => TRUE], + ], + ]; } /** @@ -1010,7 +1215,7 @@ public static function dataProviderMailCollector(): \Iterator { ], ]; - // Stage: delivered to the original recipients. + // Stage: rerouted, then delivered to the rerouting address. yield [ self::ENVIRONMENT_STAGE, [], diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 03c3132eb0..3c11dd5d38 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -86,7 +86,6 @@ public function run(): void { 'navigation_extra_tools', 'pathauto', 'redirect', - 'reroute_email', 'robotstxt', 'shield', 'stage_file_proxy', @@ -104,6 +103,8 @@ public function run(): void { $this->moduleInstaller->install(['devel']); + $this->moduleInstaller->install(['reroute_email']); + $this->moduleInstaller->install(['sw_search']); $this->moduleInstaller->install(['sw_demo']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.clamav.php b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.clamav.php index 31c129f2b1..d3996264f4 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.clamav.php +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.clamav.php @@ -7,7 +7,7 @@ declare(strict_types=1); -if (file_exists($contrib_path . '/clamav') && !empty(getenv('DRUPAL_CLAMAV_ENABLED'))) { +if (getenv('DRUPAL_CLAMAV_ENABLED') === '1') { $clamav_mode = getenv('DRUPAL_CLAMAV_MODE') ?: NULL; if (in_array(strtolower((string) $clamav_mode), ['0', 'daemon'], TRUE)) { // Drupal\clamav\Config::MODE_DAEMON. diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.fast404.php b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.fast404.php deleted file mode 100644 index 148f7d255f..0000000000 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.fast404.php +++ /dev/null @@ -1,28 +0,0 @@ -404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; - include_once $contrib_path . '/fast404/fast404.inc'; - // @phpstan-ignore-next-line - fast404_preboot($settings); - // @codeCoverageIgnoreEnd -} diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.fast_404.php b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.fast_404.php new file mode 100644 index 0000000000..4af6f182ea --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.fast_404.php @@ -0,0 +1,61 @@ +404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + + include_once $contrib_path . '/fast_404/fast404.inc'; + // Each answered request logs a TypeError after the response is sent, because + // the module passes an array where an exception is expected. Patch it with + // https://www.drupal.org/files/issues/2023-08-24/fast_404_3x-3194034-10.patch + // @see https://www.drupal.org/project/fast_404/issues/3194034 + // @phpstan-ignore-next-line + fast404_preboot($settings); +} diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.redis.php b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.redis.php index 6871347e44..f6e5612e5f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.redis.php +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.redis.php @@ -26,7 +26,7 @@ // variables would need to be removed. The next deployment (#3) would use // project-wide env variable (and since it has the same value '1' as removed // per-env variable - there will be no change in how code works). -if (file_exists($contrib_path . '/redis') && !empty(getenv('DRUPAL_REDIS_ENABLED'))) { +if (file_exists($contrib_path . '/redis') && getenv('DRUPAL_REDIS_ENABLED') === '1') { // Some providers use `REDIS_`-prefixed environment variables. $settings['redis.connection']['host'] = getenv('REDIS_HOST') ?: 'cache'; $settings['redis.connection']['port'] = getenv('REDIS_SERVICE_PORT') ?: '6379'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.reroute_email.php b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.reroute_email.php index d9701f1ddf..9443eef2d9 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.reroute_email.php +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.reroute_email.php @@ -9,29 +9,29 @@ use DrevOps\EnvironmentDetector\Environment; +$settings['config_exclude_modules'][] = 'reroute_email'; + // Default reroute email address and allowed list. $config['reroute_email.settings']['address'] = getenv('DRUPAL_REROUTE_EMAIL_ADDRESS') ?: 'webmaster@star-wars.com'; $config['reroute_email.settings']['allowed'] = getenv('DRUPAL_REROUTE_EMAIL_ALLOWED') ?: '*@star-wars.com'; -// Enable rerouting in all environments except local, ci, stage and prod. -// This covers dev and any custom environments (e.g., PR environments). -if (!in_array($settings['environment'], [ +if (in_array($settings['environment'], [ Environment::LOCAL, Environment::CI, - Environment::STAGE, Environment::PRODUCTION, ])) { + // Deliver every message to its intended recipient. Local and CI capture + // outgoing mail by other means, and production sends to real recipients. + $config['reroute_email.settings']['enable'] = FALSE; +} +else { // Send every outgoing message to the address above instead of to its // intended recipient, unless that recipient matches the allowed list. $config['reroute_email.settings']['enable'] = TRUE; } -else { - // Deliver every message to its intended recipient. - $config['reroute_email.settings']['enable'] = FALSE; -} // Allow an environment to opt out of the rerouting set above. -if (!empty(getenv('DRUPAL_REROUTE_EMAIL_DISABLED'))) { +if (getenv('DRUPAL_REROUTE_EMAIL_DISABLED') === '1') { // Deliver every message to its intended recipient. $config['reroute_email.settings']['enable'] = FALSE; } diff --git a/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.sdc_devel.php b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.sdc_devel.php new file mode 100644 index 0000000000..f0759b3ae7 --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/_baseline/web/sites/default/includes/modules/settings.sdc_devel.php @@ -0,0 +1,10 @@ +moduleInstaller->install(['sw_search']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/custom_modules_no_search/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/custom_modules_no_search/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 304a45e083..e4d5a058c6 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/custom_modules_no_search/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/custom_modules_no_search/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,6 +1,6 @@ -@@ -104,8 +104,6 @@ +@@ -105,8 +105,6 @@ - $this->moduleInstaller->install(['devel']); + $this->moduleInstaller->install(['reroute_email']); - $this->moduleInstaller->install(['sw_search']); - diff --git a/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/composer.json b/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/composer.json index d32ead2887..6a172fc24e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/composer.json @@ -1,4 +1,4 @@ -@@ -28,7 +28,6 @@ +@@ -29,7 +29,6 @@ "drupal/robotstxt": "__VERSION__", "drupal/sdc_devel": "__VERSION__", "drupal/search_api": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/docker-compose.yml index b698489a59..b6bf68a1aa 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/docker-compose.yml @@ -1,4 +1,4 @@ -@@ -157,17 +157,6 @@ +@@ -158,17 +158,6 @@ cache: image: uselagoon/valkey-8:__VERSION__ @@ -16,7 +16,7 @@ antivirus: build: context: . -@@ -198,13 +187,10 @@ +@@ -199,13 +188,10 @@ - antivirus - database - cache @@ -30,7 +30,7 @@ networks: ### Use external networks locally. Automatically removed in CI. amazeeio-network: ### Automatically removed in CI. -@@ -213,7 +199,6 @@ +@@ -214,7 +200,6 @@ volumes: app: {} files: {} diff --git a/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/tests/phpunit/Drupal/EnvironmentSettingsTest.php index f1c691cba5..251d3ff43c 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -7,7 +7,7 @@ $this->assertConfig($config); $settings['auto_create_htaccess'] = FALSE; -@@ -177,8 +175,6 @@ +@@ -191,8 +189,6 @@ $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; $config['system.performance']['cache']['page']['max_age'] = 1800; @@ -16,7 +16,7 @@ $this->assertConfig($config); // Verify settings overrides. -@@ -238,8 +234,6 @@ +@@ -266,8 +262,6 @@ $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; @@ -25,7 +25,7 @@ $this->assertConfig($config); $settings['auto_create_htaccess'] = FALSE; -@@ -298,8 +292,6 @@ +@@ -340,8 +334,6 @@ $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; @@ -34,7 +34,7 @@ $this->assertConfig($config); $settings['auto_create_htaccess'] = FALSE; -@@ -360,8 +352,6 @@ +@@ -416,8 +408,6 @@ $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; diff --git a/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/tests/phpunit/Drupal/SwitchableSettingsTest.php index a4ca21fffd..ef42d4b7bb 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,4 +1,4 @@ -@@ -297,35 +297,6 @@ +@@ -449,35 +449,6 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index a212e6cfa7..ceaa4e8bff 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/custom_modules_search_without_solr/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,4 +1,4 @@ -@@ -98,13 +98,9 @@ +@@ -97,15 +97,11 @@ $this->moduleInstaller->install(['clamav']); $this->configFactory->getEditable('clamav.settings')->set('mode_daemon_tcpip.hostname', 'clamav')->save(); @@ -7,6 +7,8 @@ $this->moduleInstaller->install(['sdc_devel']); $this->moduleInstaller->install(['devel']); + + $this->moduleInstaller->install(['reroute_email']); - - $this->moduleInstaller->install(['sw_search']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_acquia/.env b/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_acquia/.env index 73aa80e0fa..ac29806e64 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_acquia/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_acquia/.env @@ -1,4 +1,4 @@ -@@ -164,12 +164,14 @@ +@@ -170,12 +170,14 @@ VORTEX_DB_FILE=db.sql # Database fetch source. @@ -17,7 +17,7 @@ ################################################################################ # RELEASE VERSIONING # -@@ -214,17 +216,3 @@ +@@ -220,17 +222,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_container_registry/.env b/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_container_registry/.env index aadd568464..331ea90a51 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_container_registry/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_container_registry/.env @@ -1,4 +1,4 @@ -@@ -164,12 +164,11 @@ +@@ -170,12 +170,11 @@ VORTEX_DB_FILE=db.sql # Database fetch source. @@ -15,7 +15,7 @@ ################################################################################ # RELEASE VERSIONING # -@@ -214,17 +213,3 @@ +@@ -220,17 +219,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_ftp/.env b/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_ftp/.env index b3dc1ffa2e..45419a8a28 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_ftp/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_ftp/.env @@ -1,4 +1,4 @@ -@@ -164,13 +164,19 @@ +@@ -170,13 +170,19 @@ VORTEX_DB_FILE=db.sql # Database fetch source. @@ -23,7 +23,7 @@ ################################################################################ # RELEASE VERSIONING # ################################################################################ -@@ -214,17 +220,3 @@ +@@ -220,17 +226,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_lagoon/.env b/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_lagoon/.env index d50388a40f..ed167bb150 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_lagoon/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_lagoon/.env @@ -1,4 +1,4 @@ -@@ -164,12 +164,14 @@ +@@ -170,12 +170,14 @@ VORTEX_DB_FILE=db.sql # Database fetch source. @@ -17,7 +17,7 @@ ################################################################################ # RELEASE VERSIONING # -@@ -214,17 +216,3 @@ +@@ -220,17 +222,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_s3/.env b/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_s3/.env index 9b91113949..3b687f346e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_s3/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/db_fetch_source_s3/.env @@ -1,4 +1,4 @@ -@@ -164,13 +164,16 @@ +@@ -170,13 +170,16 @@ VORTEX_DB_FILE=db.sql # Database fetch source. @@ -20,7 +20,7 @@ ################################################################################ # RELEASE VERSIONING # ################################################################################ -@@ -214,17 +217,3 @@ +@@ -220,17 +223,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/.circleci/config.yml index 3a2396f99c..c222fdadbb 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/.circleci/config.yml @@ -131,9 +131,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -194,10 +199,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -434,6 +444,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/.env b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/.env index ed6caebab1..85ce6fb1ae 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/.env @@ -1,4 +1,4 @@ -@@ -187,7 +187,7 @@ +@@ -193,7 +193,7 @@ # Deployment occurs when tests pass in the CI environment. # @see https://www.vortextemplate.com/docs/deployment diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_gha/.env b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_gha/.env index ed6caebab1..85ce6fb1ae 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_gha/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_gha/.env @@ -1,4 +1,4 @@ -@@ -187,7 +187,7 @@ +@@ -193,7 +193,7 @@ # Deployment occurs when tests pass in the CI environment. # @see https://www.vortextemplate.com/docs/deployment diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_gha/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_gha/.github/workflows/build-test-deploy.yml index 1393b2d37e..56546ca20b 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_gha/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_all_gha/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -515,6 +515,24 @@ +@@ -520,6 +520,24 @@ - name: Build stack run: docker compose up --detach && docker builder prune --all --force && docker image prune --force @@ -23,7 +23,7 @@ deploy: runs-on: ubuntu-latest needs: [test, lint, build] -@@ -569,6 +587,20 @@ +@@ -574,6 +592,20 @@ - name: Load environment variables from .env run: t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && set +a && . "${t}" && env >> "$GITHUB_ENV" @@ -44,7 +44,7 @@ - name: Add SSH private key to the runner if: ${{ env.VORTEX_DEPLOY_SSH_PRIVATE_KEY != '' }} uses: shimataro/ssh-key-action@__HASH__ # __VERSION__ -@@ -589,6 +621,11 @@ +@@ -594,6 +626,11 @@ VORTEX_DEPLOY_PR: ${{ env.DEPLOY_PR_NUMBER || github.event.number }} VORTEX_DEPLOY_PR_HEAD: ${{ env.DEPLOY_PR_HEAD_SHA || github.event.pull_request.head.sha }} VORTEX_DEPLOY_PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }} diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_artifact/.env b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_artifact/.env index e5359a452f..e126a8c2dc 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_artifact/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_artifact/.env @@ -1,4 +1,4 @@ -@@ -187,7 +187,7 @@ +@@ -193,7 +193,7 @@ # Deployment occurs when tests pass in the CI environment. # @see https://www.vortextemplate.com/docs/deployment diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_artifact/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_artifact/.github/workflows/build-test-deploy.yml index ef3c4c4fd0..2a1d45054c 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_artifact/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_artifact/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -515,6 +515,24 @@ +@@ -520,6 +520,24 @@ - name: Build stack run: docker compose up --detach && docker builder prune --all --force && docker image prune --force @@ -23,7 +23,7 @@ deploy: runs-on: ubuntu-latest needs: [test, lint, build] -@@ -569,6 +587,20 @@ +@@ -574,6 +592,20 @@ - name: Load environment variables from .env run: t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && set +a && . "${t}" && env >> "$GITHUB_ENV" @@ -44,7 +44,7 @@ - name: Add SSH private key to the runner if: ${{ env.VORTEX_DEPLOY_SSH_PRIVATE_KEY != '' }} uses: shimataro/ssh-key-action@__HASH__ # __VERSION__ -@@ -589,7 +621,11 @@ +@@ -594,7 +626,11 @@ VORTEX_DEPLOY_PR: ${{ env.DEPLOY_PR_NUMBER || github.event.number }} VORTEX_DEPLOY_PR_HEAD: ${{ env.DEPLOY_PR_HEAD_SHA || github.event.pull_request.head.sha }} VORTEX_DEPLOY_PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }} diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_lagoon/.env b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_lagoon/.env index c6c5fdf14d..b698950a0d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_lagoon/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_lagoon/.env @@ -1,4 +1,4 @@ -@@ -187,7 +187,7 @@ +@@ -193,7 +193,7 @@ # Deployment occurs when tests pass in the CI environment. # @see https://www.vortextemplate.com/docs/deployment diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_lagoon/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_lagoon/.github/workflows/build-test-deploy.yml index f462fc681b..f923f62abb 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_lagoon/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_lagoon/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -589,7 +589,6 @@ +@@ -594,7 +594,6 @@ VORTEX_DEPLOY_PR: ${{ env.DEPLOY_PR_NUMBER || github.event.number }} VORTEX_DEPLOY_PR_HEAD: ${{ env.DEPLOY_PR_HEAD_SHA || github.event.pull_request.head.sha }} VORTEX_DEPLOY_PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }} diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/.circleci/config.yml index 59dbe55e4a..e688c75442 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/.circleci/config.yml @@ -120,9 +120,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -183,10 +188,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -423,6 +433,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + ################################################################################ # WORKFLOWS ################################################################################ diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/.env b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/.env index b89c319831..7bb6458a30 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/.env @@ -1,4 +1,4 @@ -@@ -182,14 +182,6 @@ +@@ -188,14 +188,6 @@ VORTEX_RELEASE_VERSION_SCHEME=calver ################################################################################ diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_gha/.env b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_gha/.env index b89c319831..7bb6458a30 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_gha/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_gha/.env @@ -1,4 +1,4 @@ -@@ -182,14 +182,6 @@ +@@ -188,14 +188,6 @@ VORTEX_RELEASE_VERSION_SCHEME=calver ################################################################################ diff --git a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_gha/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_gha/.github/workflows/build-test-deploy.yml index a957f35071..f2972a8ec7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_gha/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/deploy_types_none_gha/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -453,147 +453,3 @@ +@@ -458,147 +458,3 @@ timeout-minutes: 120 # Cancel the action after 120 minutes, regardless of whether a connection has been established. with: detached: true diff --git a/.vortex/cli/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.circleci/config.yml index 4acc6eb0fc..3029359759 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -188,10 +193,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -428,6 +438,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/.dockerignore index 5d1e4895ee..1c380b297b 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/.dockerignore @@ -1,5 +1,5 @@ -@@ -12,28 +12,28 @@ - **/.DS_Store +@@ -15,28 +15,28 @@ + auth* # Drupal directories generated by Composer during the image build. -web/core diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/.env b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/.env index 4708d62d8d..c446472a65 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/.env @@ -7,7 +7,7 @@ # The timezone used within the containers. TZ=UTC -@@ -142,6 +142,13 @@ +@@ -148,6 +148,13 @@ VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 ################################################################################ @@ -21,7 +21,7 @@ # DATABASE SOURCE # ################################################################################ -@@ -164,13 +171,18 @@ +@@ -170,13 +177,18 @@ VORTEX_DB_FILE=db.sql # Database fetch source. @@ -44,7 +44,7 @@ ################################################################################ # RELEASE VERSIONING # ################################################################################ -@@ -187,7 +199,7 @@ +@@ -193,7 +205,7 @@ # Deployment occurs when tests pass in the CI environment. # @see https://www.vortextemplate.com/docs/deployment @@ -53,7 +53,7 @@ ################################################################################ # NOTIFICATIONS # -@@ -214,17 +226,3 @@ +@@ -220,17 +232,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/.github/workflows/build-test-deploy.yml index 8936035f4d..105e8dd36f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/.github/workflows/build-test-deploy.yml @@ -8,7 +8,7 @@ - name: Build stack run: docker compose up --detach && docker builder prune --all --force && docker image prune --force -@@ -515,6 +518,24 @@ +@@ -520,6 +523,24 @@ - name: Build stack run: docker compose up --detach && docker builder prune --all --force && docker image prune --force @@ -33,7 +33,7 @@ deploy: runs-on: ubuntu-latest needs: [test, lint, build] -@@ -569,6 +590,20 @@ +@@ -574,6 +595,20 @@ - name: Load environment variables from .env run: t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && set +a && . "${t}" && env >> "$GITHUB_ENV" @@ -54,7 +54,7 @@ - name: Add SSH private key to the runner if: ${{ env.VORTEX_DEPLOY_SSH_PRIVATE_KEY != '' }} uses: shimataro/ssh-key-action@__HASH__ # __VERSION__ -@@ -589,7 +624,11 @@ +@@ -594,7 +629,11 @@ VORTEX_DEPLOY_PR: ${{ env.DEPLOY_PR_NUMBER || github.event.number }} VORTEX_DEPLOY_PR_HEAD: ${{ env.DEPLOY_PR_HEAD_SHA || github.event.pull_request.head.sha }} VORTEX_DEPLOY_PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }} diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/behat.yml b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/behat.yml index 3a5099ceac..0d3130dfb8 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/behat.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/behat.yml @@ -1,4 +1,4 @@ -@@ -52,9 +52,9 @@ +@@ -53,9 +53,9 @@ api_driver: drupal drush_driver: drush drupal: diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/composer.json b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/composer.json index be9c53acca..e82cd35062 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/composer.json @@ -1,4 +1,4 @@ -@@ -127,38 +127,38 @@ +@@ -122,38 +122,38 @@ "[web-root]/update.php": false }, "locations": { diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 03c3132eb0..3c11dd5d38 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -86,7 +86,6 @@ public function run(): void { 'navigation_extra_tools', 'pathauto', 'redirect', - 'reroute_email', 'robotstxt', 'shield', 'stage_file_proxy', @@ -104,6 +103,8 @@ public function run(): void { $this->moduleInstaller->install(['devel']); + $this->moduleInstaller->install(['reroute_email']); + $this->moduleInstaller->install(['sw_search']); $this->moduleInstaller->install(['sw_demo']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.clamav.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.clamav.php index 31c129f2b1..d3996264f4 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.clamav.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.clamav.php @@ -7,7 +7,7 @@ declare(strict_types=1); -if (file_exists($contrib_path . '/clamav') && !empty(getenv('DRUPAL_CLAMAV_ENABLED'))) { +if (getenv('DRUPAL_CLAMAV_ENABLED') === '1') { $clamav_mode = getenv('DRUPAL_CLAMAV_MODE') ?: NULL; if (in_array(strtolower((string) $clamav_mode), ['0', 'daemon'], TRUE)) { // Drupal\clamav\Config::MODE_DAEMON. diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.fast404.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.fast404.php deleted file mode 100644 index 148f7d255f..0000000000 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.fast404.php +++ /dev/null @@ -1,28 +0,0 @@ -404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; - include_once $contrib_path . '/fast404/fast404.inc'; - // @phpstan-ignore-next-line - fast404_preboot($settings); - // @codeCoverageIgnoreEnd -} diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.fast_404.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.fast_404.php new file mode 100644 index 0000000000..4af6f182ea --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.fast_404.php @@ -0,0 +1,61 @@ +404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + + include_once $contrib_path . '/fast_404/fast404.inc'; + // Each answered request logs a TypeError after the response is sent, because + // the module passes an array where an exception is expected. Patch it with + // https://www.drupal.org/files/issues/2023-08-24/fast_404_3x-3194034-10.patch + // @see https://www.drupal.org/project/fast_404/issues/3194034 + // @phpstan-ignore-next-line + fast404_preboot($settings); +} diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.redis.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.redis.php index 6871347e44..f6e5612e5f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.redis.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.redis.php @@ -26,7 +26,7 @@ // variables would need to be removed. The next deployment (#3) would use // project-wide env variable (and since it has the same value '1' as removed // per-env variable - there will be no change in how code works). -if (file_exists($contrib_path . '/redis') && !empty(getenv('DRUPAL_REDIS_ENABLED'))) { +if (file_exists($contrib_path . '/redis') && getenv('DRUPAL_REDIS_ENABLED') === '1') { // Some providers use `REDIS_`-prefixed environment variables. $settings['redis.connection']['host'] = getenv('REDIS_HOST') ?: 'cache'; $settings['redis.connection']['port'] = getenv('REDIS_SERVICE_PORT') ?: '6379'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.reroute_email.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.reroute_email.php index d9701f1ddf..9443eef2d9 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.reroute_email.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.reroute_email.php @@ -9,29 +9,29 @@ use DrevOps\EnvironmentDetector\Environment; +$settings['config_exclude_modules'][] = 'reroute_email'; + // Default reroute email address and allowed list. $config['reroute_email.settings']['address'] = getenv('DRUPAL_REROUTE_EMAIL_ADDRESS') ?: 'webmaster@star-wars.com'; $config['reroute_email.settings']['allowed'] = getenv('DRUPAL_REROUTE_EMAIL_ALLOWED') ?: '*@star-wars.com'; -// Enable rerouting in all environments except local, ci, stage and prod. -// This covers dev and any custom environments (e.g., PR environments). -if (!in_array($settings['environment'], [ +if (in_array($settings['environment'], [ Environment::LOCAL, Environment::CI, - Environment::STAGE, Environment::PRODUCTION, ])) { + // Deliver every message to its intended recipient. Local and CI capture + // outgoing mail by other means, and production sends to real recipients. + $config['reroute_email.settings']['enable'] = FALSE; +} +else { // Send every outgoing message to the address above instead of to its // intended recipient, unless that recipient matches the allowed list. $config['reroute_email.settings']['enable'] = TRUE; } -else { - // Deliver every message to its intended recipient. - $config['reroute_email.settings']['enable'] = FALSE; -} // Allow an environment to opt out of the rerouting set above. -if (!empty(getenv('DRUPAL_REROUTE_EMAIL_DISABLED'))) { +if (getenv('DRUPAL_REROUTE_EMAIL_DISABLED') === '1') { // Deliver every message to its intended recipient. $config['reroute_email.settings']['enable'] = FALSE; } diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.sdc_devel.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.sdc_devel.php new file mode 100644 index 0000000000..f0759b3ae7 --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/docroot/sites/default/includes/modules/settings.sdc_devel.php @@ -0,0 +1,10 @@ +/dev/null || exit 1 - -[ "${VORTEX_TASK_COPY_DB_ACQUIA_SKIP}" = "1" ] && echo "Skipping copying of database between Acquia environments." && exit 0 +[ "${VORTEX_TASK_COPY_DB_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping copying of database between Acquia environments." && exit 0 export VORTEX_PLATFORM=acquia -export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY?not set}" -export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET?not set}" +export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY:?Missing required value.}" +export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET:?Missing required value.}" export VORTEX_ACQUIA_APP_NAME="${VORTEX_ACQUIA_APP_NAME:-${site}}" export VORTEX_TASK_COPY_DB_ACQUIA_SRC="${VORTEX_TASK_COPY_DB_ACQUIA_SRC:-prod}" export VORTEX_TASK_COPY_DB_ACQUIA_DST="${VORTEX_TASK_COPY_DB_ACQUIA_DST:-${target_env}}" -export VORTEX_TASK_COPY_DB_ACQUIA_NAME="${VORTEX_TASK_COPY_DB_ACQUIA_NAME?not set}" +export VORTEX_TASK_COPY_DB_ACQUIA_NAME="${VORTEX_TASK_COPY_DB_ACQUIA_NAME:?Missing required value.}" + +pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 ./vendor/bin/vortex-task copy-db diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/copy-files.sh b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/copy-files.sh index c432622059..b2f1760784 100755 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/copy-files.sh +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/copy-files.sh @@ -4,23 +4,23 @@ # # Environment variables must be set in Acquia UI globally or for each environment. -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" -pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 - -[ "${VORTEX_TASK_COPY_FILES_ACQUIA_SKIP}" = "1" ] && echo "Skipping copying of files between Acquia environments." && exit 0 +[ "${VORTEX_TASK_COPY_FILES_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping copying of files between Acquia environments." && exit 0 export VORTEX_PLATFORM=acquia -export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY?not set}" -export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET?not set}" +export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY:?Missing required value.}" +export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET:?Missing required value.}" export VORTEX_ACQUIA_APP_NAME="${VORTEX_ACQUIA_APP_NAME:-${site}}" export VORTEX_TASK_COPY_FILES_ACQUIA_SRC="${VORTEX_TASK_COPY_FILES_ACQUIA_SRC:-prod}" export VORTEX_TASK_COPY_FILES_ACQUIA_DST="${VORTEX_TASK_COPY_FILES_ACQUIA_DST:-${target_env}}" +pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 + ./vendor/bin/vortex-task copy-files popd >/dev/null || exit 1 diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/notify-deployment.sh b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/notify-deployment.sh index 45cd103240..6f970da90f 100755 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/notify-deployment.sh +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/notify-deployment.sh @@ -3,26 +3,25 @@ # Acquia Cloud hook: Send deployment notifications. # -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" -branch="${3}" -ref="${4}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" +branch="${3:?Missing required branch name.}" +ref="${4:?Missing required commit reference.}" + +[ "${VORTEX_NOTIFY_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping sending of deployment notifications in Acquia environment." && exit 0 # Custom domain name for the environment, including subdomain. # Examples: "dev.example.com", "test.example.com", "www.example.com" VORTEX_NOTIFY_ENVIRONMENT_DOMAIN="${VORTEX_NOTIFY_ENVIRONMENT_DOMAIN:-}" -pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 - -# Set URL to Acquia domain by default. -url="https://${AH_SITE_NAME}.${AH_REALM:-prod}.acquia-sites.com" - -# Use custom domain in URL, if provided. +# Use custom domain in URL, if provided, or the Acquia domain otherwise. if [ -n "${VORTEX_NOTIFY_ENVIRONMENT_DOMAIN}" ]; then url="https://${VORTEX_NOTIFY_ENVIRONMENT_DOMAIN}" +else + url="https://${AH_SITE_NAME:?Missing required value.}.${AH_REALM:-prod}.acquia-sites.com" fi export VORTEX_NOTIFY_PROJECT="${site}" @@ -32,6 +31,8 @@ export VORTEX_NOTIFY_PR_NUMBER="" export VORTEX_NOTIFY_LABEL="${branch}" export VORTEX_NOTIFY_ENVIRONMENT_URL="${url}" +pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 + ./vendor/bin/vortex-notify popd >/dev/null || exit 1 diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/provision.sh b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/provision.sh index 3fdeee319f..82ee8541be 100755 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/provision.sh +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/provision.sh @@ -3,11 +3,13 @@ # Acquia Cloud hook: Provision site. # -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" + +[ "${VORTEX_PROVISION_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping provisioning of the site in Acquia environment." && exit 0 pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/purge-cache.sh b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/purge-cache.sh index 58513bffc6..f2537f599b 100755 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/purge-cache.sh +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/hooks/library/purge-cache.sh @@ -4,23 +4,23 @@ # # Environment variables must be set in Acquia UI globally or for each environment. -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" -pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 - -[ "${VORTEX_PURGE_CACHE_ACQUIA_SKIP}" = "1" ] && echo "Skipping purging of cache in Acquia environment." && exit 0 +[ "${VORTEX_PURGE_CACHE_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping purging of cache in Acquia environment." && exit 0 export VORTEX_PLATFORM=acquia -export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY?not set}" -export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET?not set}" +export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY:?Missing required value.}" +export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET:?Missing required value.}" export VORTEX_ACQUIA_APP_NAME="${VORTEX_ACQUIA_APP_NAME:-${site}}" export VORTEX_TASK_PURGE_CACHE_ACQUIA_ENV="${VORTEX_TASK_PURGE_CACHE_ACQUIA_ENV:-${target_env}}" export VORTEX_TASK_PURGE_CACHE_ACQUIA_DOMAINS_FILE="${VORTEX_TASK_PURGE_CACHE_ACQUIA_DOMAINS_FILE:-"/var/www/html/${site}.${target_env}/hooks/library/domains.txt"}" +pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 + ./vendor/bin/vortex-task purge-cache popd >/dev/null || exit 1 diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/rector.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/rector.php index c1f2ff0845..d375a07093 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/rector.php @@ -1,4 +1,4 @@ -@@ -47,10 +47,10 @@ +@@ -46,10 +46,10 @@ return RectorConfig::configure() ->withPaths([ @@ -13,7 +13,7 @@ __DIR__ . '/tests', ]) ->withSkip([ -@@ -78,7 +78,7 @@ +@@ -77,7 +77,7 @@ RenameVariableToMatchNewTypeRector::class, SimplifyEmptyCheckOnEmptyArrayRector::class, StringClassNameToClassConstantRector::class => [ diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 6a29e7fef9..faaf2c6e1a 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -49,7 +49,7 @@ } /** -@@ -384,6 +428,349 @@ +@@ -454,6 +498,433 @@ $settings['maintenance_theme'] = 'claro'; $settings['skip_permissions_hardening'] = TRUE; $settings['config_sync_directory'] = '../config/default'; @@ -94,11 +94,25 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PREVIEW; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -150,11 +164,25 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_DEV; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -191,7 +219,7 @@ + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; -+ $config['reroute_email.settings']['enable'] = FALSE; ++ $config['reroute_email.settings']['enable'] = TRUE; + $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; + $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; + $config['shield.settings']['shield_enable'] = TRUE; @@ -206,11 +234,25 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_STAGE; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -259,11 +301,25 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PROD; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -316,12 +372,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = 'custom_acquia_config'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_DEV; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -380,6 +450,8 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '/var/www/site-php/mysite/config'; @@ -387,6 +459,18 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_DEV; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/tests/phpunit/Drupal/SettingsTestCase.php index 051064cd21..7102139b85 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/tests/phpunit/Drupal/SettingsTestCase.php @@ -1,4 +1,4 @@ -@@ -204,7 +204,7 @@ +@@ -205,7 +205,7 @@ * Require settings file. */ protected function requireSettingsFile(array $pre_settings = [], array $pre_config = []): void { @@ -7,3 +7,12 @@ protected function requireSettingsFile(array $pre_settings = [], array $pre_conf if (!file_exists($app_root)) { throw new \RuntimeException('Could not determine application root.'); +@@ -251,7 +251,7 @@ + * Array of configs to pre-populate. + */ + protected function requireModuleSettingsFile(string $module, string $contrib_path, array $pre_settings = [], array $pre_config = []): void { +- $app_root = getcwd() . '/web'; ++ $app_root = getcwd() . '/docroot'; + + if (!file_exists($app_root)) { + throw new \RuntimeException('Could not determine application root.'); diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/web/sites/default/includes/modules/-settings.fast404.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/web/sites/default/includes/modules/-settings.fast_404.php similarity index 100% rename from .vortex/cli/tests/Fixtures/handler_process/hosting_acquia/web/sites/default/includes/modules/-settings.fast404.php rename to .vortex/cli/tests/Fixtures/handler_process/hosting_acquia/web/sites/default/includes/modules/-settings.fast_404.php diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/web/sites/default/includes/modules/-settings.fast404.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_acquia/web/sites/default/includes/modules/-settings.sdc_devel.php similarity index 100% rename from .vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/web/sites/default/includes/modules/-settings.fast404.php rename to .vortex/cli/tests/Fixtures/handler_process/hosting_acquia/web/sites/default/includes/modules/-settings.sdc_devel.php diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/.env b/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/.env index 6741b81b05..fcb07a3f1c 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/.env @@ -1,4 +1,4 @@ -@@ -142,6 +142,18 @@ +@@ -148,6 +148,18 @@ VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 ################################################################################ @@ -17,7 +17,7 @@ # DATABASE SOURCE # ################################################################################ -@@ -164,12 +176,14 @@ +@@ -170,12 +182,14 @@ VORTEX_DB_FILE=db.sql # Database fetch source. @@ -36,7 +36,7 @@ ################################################################################ # RELEASE VERSIONING # -@@ -187,7 +201,7 @@ +@@ -193,7 +207,7 @@ # Deployment occurs when tests pass in the CI environment. # @see https://www.vortextemplate.com/docs/deployment @@ -45,7 +45,7 @@ ################################################################################ # NOTIFICATIONS # -@@ -214,17 +228,3 @@ +@@ -220,17 +234,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/.github/workflows/build-test-deploy.yml index 3569e59c68..5de23e5207 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/.github/workflows/build-test-deploy.yml @@ -14,7 +14,7 @@ # On the first build of the day (cache miss), fetch a fresh DB dump. # On subsequent builds, the restored cache already contains the dump and # the fetch script skips itself, leaving no semaphore file behind. -@@ -589,7 +598,6 @@ +@@ -594,7 +603,6 @@ VORTEX_DEPLOY_PR: ${{ env.DEPLOY_PR_NUMBER || github.event.number }} VORTEX_DEPLOY_PR_HEAD: ${{ env.DEPLOY_PR_HEAD_SHA || github.event.pull_request.head.sha }} VORTEX_DEPLOY_PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }} diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/composer.json b/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/composer.json index 17423e068c..54a9a90cf9 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,7 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,7 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/lagoon_logs": "__VERSION__", "drupal/navigation_extra_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/docker-compose.yml index 274b83248e..a5a8de4809 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/docker-compose.yml @@ -17,7 +17,7 @@ webserver: build: -@@ -126,6 +131,11 @@ +@@ -127,6 +132,11 @@ networks: - default # This is a standard network and is used for all other environments, where requests routing is not required and/or not supported. - amazeeio-network ### This network is supported by Pygmy and used to route all requests to host machine locally. Removed in CI. @@ -29,7 +29,7 @@ # PHP FPM container. All web requests are going through this container. appserver: -@@ -141,6 +151,11 @@ +@@ -142,6 +152,11 @@ <<: [ *default-volumes, *default-user ] depends_on: - cli @@ -41,7 +41,7 @@ database: build: -@@ -153,9 +168,13 @@ +@@ -154,9 +169,13 @@ <<: *default-user ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -55,7 +55,7 @@ search: build: -@@ -167,6 +186,8 @@ +@@ -168,6 +187,8 @@ - search:/var/solr ports: - '8983' # Solr port in a container. Find port on host with `ahoy info` or `docker compose port search 8983`. @@ -64,7 +64,7 @@ antivirus: build: -@@ -178,6 +199,10 @@ +@@ -179,6 +200,10 @@ - '3310' # Find port on host with `docker compose port antivirus 3310`. networks: - default @@ -75,7 +75,7 @@ # Browser container, used for browser testing. browser: -@@ -190,6 +215,8 @@ +@@ -191,6 +216,8 @@ ports: - '7900' # Find port on host with `docker compose port browser 7900`. shm_size: '1gb' # Increase '/dev/shm' partition size to avoid browser crashing. @@ -84,7 +84,7 @@ # Helper container to wait for services to become available. wait-for-dependencies: -@@ -205,6 +232,8 @@ +@@ -206,6 +233,8 @@ - cache:6379 - search:8983 - curl -s "http://search:8983/solr/drupal/select?q=*:*&rows=0&wt=json" | grep response diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 9fd3befa4f..d52bba592e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -193,7 +193,7 @@ } /** -@@ -387,6 +575,268 @@ +@@ -457,6 +645,324 @@ $settings['trusted_host_patterns'] = [ '^localhost$', '^127\.0\.0\.1$', @@ -240,12 +240,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PREVIEW; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -306,12 +320,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_DEV; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -356,7 +384,7 @@ + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; -+ $config['reroute_email.settings']['enable'] = FALSE; ++ $config['reroute_email.settings']['enable'] = TRUE; + $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; + $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; + $config['shield.settings']['shield_enable'] = TRUE; @@ -372,12 +400,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_STAGE; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -436,12 +478,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PROD; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/.dockerignore index 5d1e4895ee..1c380b297b 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/.dockerignore @@ -1,5 +1,5 @@ -@@ -12,28 +12,28 @@ - **/.DS_Store +@@ -15,28 +15,28 @@ + auth* # Drupal directories generated by Composer during the image build. -web/core diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/.env b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/.env index 0a66497ab3..16b7f3651e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/.env @@ -7,7 +7,7 @@ # The timezone used within the containers. TZ=UTC -@@ -142,6 +142,13 @@ +@@ -148,6 +148,13 @@ VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 ################################################################################ @@ -21,7 +21,7 @@ # DATABASE SOURCE # ################################################################################ -@@ -164,13 +171,18 @@ +@@ -170,13 +177,18 @@ VORTEX_DB_FILE=db.sql # Database fetch source. @@ -44,7 +44,7 @@ ################################################################################ # RELEASE VERSIONING # ################################################################################ -@@ -187,7 +199,7 @@ +@@ -193,7 +205,7 @@ # Deployment occurs when tests pass in the CI environment. # @see https://www.vortextemplate.com/docs/deployment @@ -53,7 +53,7 @@ ################################################################################ # NOTIFICATIONS # -@@ -214,17 +226,3 @@ +@@ -220,17 +232,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/.github/workflows/build-test-deploy.yml index 8936035f4d..105e8dd36f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/.github/workflows/build-test-deploy.yml @@ -8,7 +8,7 @@ - name: Build stack run: docker compose up --detach && docker builder prune --all --force && docker image prune --force -@@ -515,6 +518,24 @@ +@@ -520,6 +523,24 @@ - name: Build stack run: docker compose up --detach && docker builder prune --all --force && docker image prune --force @@ -33,7 +33,7 @@ deploy: runs-on: ubuntu-latest needs: [test, lint, build] -@@ -569,6 +590,20 @@ +@@ -574,6 +595,20 @@ - name: Load environment variables from .env run: t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && set +a && . "${t}" && env >> "$GITHUB_ENV" @@ -54,7 +54,7 @@ - name: Add SSH private key to the runner if: ${{ env.VORTEX_DEPLOY_SSH_PRIVATE_KEY != '' }} uses: shimataro/ssh-key-action@__HASH__ # __VERSION__ -@@ -589,7 +624,11 @@ +@@ -594,7 +629,11 @@ VORTEX_DEPLOY_PR: ${{ env.DEPLOY_PR_NUMBER || github.event.number }} VORTEX_DEPLOY_PR_HEAD: ${{ env.DEPLOY_PR_HEAD_SHA || github.event.pull_request.head.sha }} VORTEX_DEPLOY_PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }} diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/behat.yml b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/behat.yml index 3a5099ceac..0d3130dfb8 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/behat.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/behat.yml @@ -1,4 +1,4 @@ -@@ -52,9 +52,9 @@ +@@ -53,9 +53,9 @@ api_driver: drupal drush_driver: drush drupal: diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/composer.json b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/composer.json index be9c53acca..e82cd35062 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/composer.json @@ -1,4 +1,4 @@ -@@ -127,38 +127,38 @@ +@@ -122,38 +122,38 @@ "[web-root]/update.php": false }, "locations": { diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 03c3132eb0..3c11dd5d38 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -86,7 +86,6 @@ public function run(): void { 'navigation_extra_tools', 'pathauto', 'redirect', - 'reroute_email', 'robotstxt', 'shield', 'stage_file_proxy', @@ -104,6 +103,8 @@ public function run(): void { $this->moduleInstaller->install(['devel']); + $this->moduleInstaller->install(['reroute_email']); + $this->moduleInstaller->install(['sw_search']); $this->moduleInstaller->install(['sw_demo']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.clamav.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.clamav.php index 31c129f2b1..d3996264f4 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.clamav.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.clamav.php @@ -7,7 +7,7 @@ declare(strict_types=1); -if (file_exists($contrib_path . '/clamav') && !empty(getenv('DRUPAL_CLAMAV_ENABLED'))) { +if (getenv('DRUPAL_CLAMAV_ENABLED') === '1') { $clamav_mode = getenv('DRUPAL_CLAMAV_MODE') ?: NULL; if (in_array(strtolower((string) $clamav_mode), ['0', 'daemon'], TRUE)) { // Drupal\clamav\Config::MODE_DAEMON. diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.fast404.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.fast404.php deleted file mode 100644 index 148f7d255f..0000000000 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.fast404.php +++ /dev/null @@ -1,28 +0,0 @@ -404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; - include_once $contrib_path . '/fast404/fast404.inc'; - // @phpstan-ignore-next-line - fast404_preboot($settings); - // @codeCoverageIgnoreEnd -} diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.fast_404.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.fast_404.php new file mode 100644 index 0000000000..4af6f182ea --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.fast_404.php @@ -0,0 +1,61 @@ +404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; + + include_once $contrib_path . '/fast_404/fast404.inc'; + // Each answered request logs a TypeError after the response is sent, because + // the module passes an array where an exception is expected. Patch it with + // https://www.drupal.org/files/issues/2023-08-24/fast_404_3x-3194034-10.patch + // @see https://www.drupal.org/project/fast_404/issues/3194034 + // @phpstan-ignore-next-line + fast404_preboot($settings); +} diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.redis.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.redis.php index 6871347e44..f6e5612e5f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.redis.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.redis.php @@ -26,7 +26,7 @@ // variables would need to be removed. The next deployment (#3) would use // project-wide env variable (and since it has the same value '1' as removed // per-env variable - there will be no change in how code works). -if (file_exists($contrib_path . '/redis') && !empty(getenv('DRUPAL_REDIS_ENABLED'))) { +if (file_exists($contrib_path . '/redis') && getenv('DRUPAL_REDIS_ENABLED') === '1') { // Some providers use `REDIS_`-prefixed environment variables. $settings['redis.connection']['host'] = getenv('REDIS_HOST') ?: 'cache'; $settings['redis.connection']['port'] = getenv('REDIS_SERVICE_PORT') ?: '6379'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.reroute_email.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.reroute_email.php index d9701f1ddf..9443eef2d9 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.reroute_email.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.reroute_email.php @@ -9,29 +9,29 @@ use DrevOps\EnvironmentDetector\Environment; +$settings['config_exclude_modules'][] = 'reroute_email'; + // Default reroute email address and allowed list. $config['reroute_email.settings']['address'] = getenv('DRUPAL_REROUTE_EMAIL_ADDRESS') ?: 'webmaster@star-wars.com'; $config['reroute_email.settings']['allowed'] = getenv('DRUPAL_REROUTE_EMAIL_ALLOWED') ?: '*@star-wars.com'; -// Enable rerouting in all environments except local, ci, stage and prod. -// This covers dev and any custom environments (e.g., PR environments). -if (!in_array($settings['environment'], [ +if (in_array($settings['environment'], [ Environment::LOCAL, Environment::CI, - Environment::STAGE, Environment::PRODUCTION, ])) { + // Deliver every message to its intended recipient. Local and CI capture + // outgoing mail by other means, and production sends to real recipients. + $config['reroute_email.settings']['enable'] = FALSE; +} +else { // Send every outgoing message to the address above instead of to its // intended recipient, unless that recipient matches the allowed list. $config['reroute_email.settings']['enable'] = TRUE; } -else { - // Deliver every message to its intended recipient. - $config['reroute_email.settings']['enable'] = FALSE; -} // Allow an environment to opt out of the rerouting set above. -if (!empty(getenv('DRUPAL_REROUTE_EMAIL_DISABLED'))) { +if (getenv('DRUPAL_REROUTE_EMAIL_DISABLED') === '1') { // Deliver every message to its intended recipient. $config['reroute_email.settings']['enable'] = FALSE; } diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.sdc_devel.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.sdc_devel.php new file mode 100644 index 0000000000..f0759b3ae7 --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/docroot/sites/default/includes/modules/settings.sdc_devel.php @@ -0,0 +1,10 @@ +/dev/null || exit 1 - -[ "${VORTEX_TASK_COPY_DB_ACQUIA_SKIP}" = "1" ] && echo "Skipping copying of database between Acquia environments." && exit 0 +[ "${VORTEX_TASK_COPY_DB_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping copying of database between Acquia environments." && exit 0 export VORTEX_PLATFORM=acquia -export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY?not set}" -export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET?not set}" +export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY:?Missing required value.}" +export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET:?Missing required value.}" export VORTEX_ACQUIA_APP_NAME="${VORTEX_ACQUIA_APP_NAME:-${site}}" export VORTEX_TASK_COPY_DB_ACQUIA_SRC="${VORTEX_TASK_COPY_DB_ACQUIA_SRC:-prod}" export VORTEX_TASK_COPY_DB_ACQUIA_DST="${VORTEX_TASK_COPY_DB_ACQUIA_DST:-${target_env}}" -export VORTEX_TASK_COPY_DB_ACQUIA_NAME="${VORTEX_TASK_COPY_DB_ACQUIA_NAME?not set}" +export VORTEX_TASK_COPY_DB_ACQUIA_NAME="${VORTEX_TASK_COPY_DB_ACQUIA_NAME:?Missing required value.}" + +pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 ./vendor/bin/vortex-task copy-db diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/copy-files.sh b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/copy-files.sh index c432622059..b2f1760784 100755 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/copy-files.sh +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/copy-files.sh @@ -4,23 +4,23 @@ # # Environment variables must be set in Acquia UI globally or for each environment. -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" -pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 - -[ "${VORTEX_TASK_COPY_FILES_ACQUIA_SKIP}" = "1" ] && echo "Skipping copying of files between Acquia environments." && exit 0 +[ "${VORTEX_TASK_COPY_FILES_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping copying of files between Acquia environments." && exit 0 export VORTEX_PLATFORM=acquia -export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY?not set}" -export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET?not set}" +export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY:?Missing required value.}" +export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET:?Missing required value.}" export VORTEX_ACQUIA_APP_NAME="${VORTEX_ACQUIA_APP_NAME:-${site}}" export VORTEX_TASK_COPY_FILES_ACQUIA_SRC="${VORTEX_TASK_COPY_FILES_ACQUIA_SRC:-prod}" export VORTEX_TASK_COPY_FILES_ACQUIA_DST="${VORTEX_TASK_COPY_FILES_ACQUIA_DST:-${target_env}}" +pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 + ./vendor/bin/vortex-task copy-files popd >/dev/null || exit 1 diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/notify-deployment.sh b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/notify-deployment.sh index 45cd103240..6f970da90f 100755 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/notify-deployment.sh +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/notify-deployment.sh @@ -3,26 +3,25 @@ # Acquia Cloud hook: Send deployment notifications. # -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" -branch="${3}" -ref="${4}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" +branch="${3:?Missing required branch name.}" +ref="${4:?Missing required commit reference.}" + +[ "${VORTEX_NOTIFY_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping sending of deployment notifications in Acquia environment." && exit 0 # Custom domain name for the environment, including subdomain. # Examples: "dev.example.com", "test.example.com", "www.example.com" VORTEX_NOTIFY_ENVIRONMENT_DOMAIN="${VORTEX_NOTIFY_ENVIRONMENT_DOMAIN:-}" -pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 - -# Set URL to Acquia domain by default. -url="https://${AH_SITE_NAME}.${AH_REALM:-prod}.acquia-sites.com" - -# Use custom domain in URL, if provided. +# Use custom domain in URL, if provided, or the Acquia domain otherwise. if [ -n "${VORTEX_NOTIFY_ENVIRONMENT_DOMAIN}" ]; then url="https://${VORTEX_NOTIFY_ENVIRONMENT_DOMAIN}" +else + url="https://${AH_SITE_NAME:?Missing required value.}.${AH_REALM:-prod}.acquia-sites.com" fi export VORTEX_NOTIFY_PROJECT="${site}" @@ -32,6 +31,8 @@ export VORTEX_NOTIFY_PR_NUMBER="" export VORTEX_NOTIFY_LABEL="${branch}" export VORTEX_NOTIFY_ENVIRONMENT_URL="${url}" +pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 + ./vendor/bin/vortex-notify popd >/dev/null || exit 1 diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/provision.sh b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/provision.sh index 3fdeee319f..82ee8541be 100755 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/provision.sh +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/provision.sh @@ -3,11 +3,13 @@ # Acquia Cloud hook: Provision site. # -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" + +[ "${VORTEX_PROVISION_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping provisioning of the site in Acquia environment." && exit 0 pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/purge-cache.sh b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/purge-cache.sh index 58513bffc6..f2537f599b 100755 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/purge-cache.sh +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/hooks/library/purge-cache.sh @@ -4,23 +4,23 @@ # # Environment variables must be set in Acquia UI globally or for each environment. -set -e -[ -n "${VORTEX_DEBUG}" ] && set -x +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x -site="${1}" -target_env="${2}" +site="${1:?Missing required site name.}" +target_env="${2:?Missing required target environment name.}" -pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 - -[ "${VORTEX_PURGE_CACHE_ACQUIA_SKIP}" = "1" ] && echo "Skipping purging of cache in Acquia environment." && exit 0 +[ "${VORTEX_PURGE_CACHE_ACQUIA_SKIP:-}" = "1" ] && echo "Skipping purging of cache in Acquia environment." && exit 0 export VORTEX_PLATFORM=acquia -export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY?not set}" -export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET?not set}" +export VORTEX_ACQUIA_KEY="${VORTEX_ACQUIA_KEY:?Missing required value.}" +export VORTEX_ACQUIA_SECRET="${VORTEX_ACQUIA_SECRET:?Missing required value.}" export VORTEX_ACQUIA_APP_NAME="${VORTEX_ACQUIA_APP_NAME:-${site}}" export VORTEX_TASK_PURGE_CACHE_ACQUIA_ENV="${VORTEX_TASK_PURGE_CACHE_ACQUIA_ENV:-${target_env}}" export VORTEX_TASK_PURGE_CACHE_ACQUIA_DOMAINS_FILE="${VORTEX_TASK_PURGE_CACHE_ACQUIA_DOMAINS_FILE:-"/var/www/html/${site}.${target_env}/hooks/library/domains.txt"}" +pushd "/var/www/html/${site}.${target_env}" >/dev/null || exit 1 + ./vendor/bin/vortex-task purge-cache popd >/dev/null || exit 1 diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/rector.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/rector.php index c1f2ff0845..d375a07093 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/rector.php @@ -1,4 +1,4 @@ -@@ -47,10 +47,10 @@ +@@ -46,10 +46,10 @@ return RectorConfig::configure() ->withPaths([ @@ -13,7 +13,7 @@ __DIR__ . '/tests', ]) ->withSkip([ -@@ -78,7 +78,7 @@ +@@ -77,7 +77,7 @@ RenameVariableToMatchNewTypeRector::class, SimplifyEmptyCheckOnEmptyArrayRector::class, StringClassNameToClassConstantRector::class => [ diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 6a29e7fef9..faaf2c6e1a 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -49,7 +49,7 @@ } /** -@@ -384,6 +428,349 @@ +@@ -454,6 +498,433 @@ $settings['maintenance_theme'] = 'claro'; $settings['skip_permissions_hardening'] = TRUE; $settings['config_sync_directory'] = '../config/default'; @@ -94,11 +94,25 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PREVIEW; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -150,11 +164,25 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_DEV; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -191,7 +219,7 @@ + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; -+ $config['reroute_email.settings']['enable'] = FALSE; ++ $config['reroute_email.settings']['enable'] = TRUE; + $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; + $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; + $config['shield.settings']['shield_enable'] = TRUE; @@ -206,11 +234,25 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_STAGE; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -259,11 +301,25 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PROD; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -316,12 +372,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = 'custom_acquia_config'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_DEV; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -380,6 +450,8 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '/var/www/site-php/mysite/config'; @@ -387,6 +459,18 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_DEV; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/tests/phpunit/Drupal/SettingsTestCase.php index 051064cd21..7102139b85 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/tests/phpunit/Drupal/SettingsTestCase.php @@ -1,4 +1,4 @@ -@@ -204,7 +204,7 @@ +@@ -205,7 +205,7 @@ * Require settings file. */ protected function requireSettingsFile(array $pre_settings = [], array $pre_config = []): void { @@ -7,3 +7,12 @@ protected function requireSettingsFile(array $pre_settings = [], array $pre_conf if (!file_exists($app_root)) { throw new \RuntimeException('Could not determine application root.'); +@@ -251,7 +251,7 @@ + * Array of configs to pre-populate. + */ + protected function requireModuleSettingsFile(string $module, string $contrib_path, array $pre_settings = [], array $pre_config = []): void { +- $app_root = getcwd() . '/web'; ++ $app_root = getcwd() . '/docroot'; + + if (!file_exists($app_root)) { + throw new \RuntimeException('Could not determine application root.'); diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/web/sites/default/includes/modules/-settings.fast_404.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/web/sites/default/includes/modules/-settings.fast_404.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/web/sites/default/includes/modules/-settings.sdc_devel.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___acquia/web/sites/default/includes/modules/-settings.sdc_devel.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/.env b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/.env index a31b3e0a88..cc7c90d7bf 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/.env @@ -1,4 +1,4 @@ -@@ -142,6 +142,18 @@ +@@ -148,6 +148,18 @@ VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 ################################################################################ @@ -17,7 +17,7 @@ # DATABASE SOURCE # ################################################################################ -@@ -164,12 +176,14 @@ +@@ -170,12 +182,14 @@ VORTEX_DB_FILE=db.sql # Database fetch source. @@ -36,7 +36,7 @@ ################################################################################ # RELEASE VERSIONING # -@@ -187,7 +201,7 @@ +@@ -193,7 +207,7 @@ # Deployment occurs when tests pass in the CI environment. # @see https://www.vortextemplate.com/docs/deployment @@ -45,7 +45,7 @@ ################################################################################ # NOTIFICATIONS # -@@ -214,17 +228,3 @@ +@@ -220,17 +234,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/.github/workflows/build-test-deploy.yml index 3569e59c68..5de23e5207 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/.github/workflows/build-test-deploy.yml @@ -14,7 +14,7 @@ # On the first build of the day (cache miss), fetch a fresh DB dump. # On subsequent builds, the restored cache already contains the dump and # the fetch script skips itself, leaving no semaphore file behind. -@@ -589,7 +598,6 @@ +@@ -594,7 +603,6 @@ VORTEX_DEPLOY_PR: ${{ env.DEPLOY_PR_NUMBER || github.event.number }} VORTEX_DEPLOY_PR_HEAD: ${{ env.DEPLOY_PR_HEAD_SHA || github.event.pull_request.head.sha }} VORTEX_DEPLOY_PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }} diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/composer.json b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/composer.json index 17423e068c..54a9a90cf9 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,7 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,7 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/lagoon_logs": "__VERSION__", "drupal/navigation_extra_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/docker-compose.yml index 274b83248e..a5a8de4809 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/docker-compose.yml @@ -17,7 +17,7 @@ webserver: build: -@@ -126,6 +131,11 @@ +@@ -127,6 +132,11 @@ networks: - default # This is a standard network and is used for all other environments, where requests routing is not required and/or not supported. - amazeeio-network ### This network is supported by Pygmy and used to route all requests to host machine locally. Removed in CI. @@ -29,7 +29,7 @@ # PHP FPM container. All web requests are going through this container. appserver: -@@ -141,6 +151,11 @@ +@@ -142,6 +152,11 @@ <<: [ *default-volumes, *default-user ] depends_on: - cli @@ -41,7 +41,7 @@ database: build: -@@ -153,9 +168,13 @@ +@@ -154,9 +169,13 @@ <<: *default-user ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -55,7 +55,7 @@ search: build: -@@ -167,6 +186,8 @@ +@@ -168,6 +187,8 @@ - search:/var/solr ports: - '8983' # Solr port in a container. Find port on host with `ahoy info` or `docker compose port search 8983`. @@ -64,7 +64,7 @@ antivirus: build: -@@ -178,6 +199,10 @@ +@@ -179,6 +200,10 @@ - '3310' # Find port on host with `docker compose port antivirus 3310`. networks: - default @@ -75,7 +75,7 @@ # Browser container, used for browser testing. browser: -@@ -190,6 +215,8 @@ +@@ -191,6 +216,8 @@ ports: - '7900' # Find port on host with `docker compose port browser 7900`. shm_size: '1gb' # Increase '/dev/shm' partition size to avoid browser crashing. @@ -84,7 +84,7 @@ # Helper container to wait for services to become available. wait-for-dependencies: -@@ -205,6 +232,8 @@ +@@ -206,6 +233,8 @@ - cache:6379 - search:8983 - curl -s "http://search:8983/solr/drupal/select?q=*:*&rows=0&wt=json" | grep response diff --git a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 9fd3befa4f..d52bba592e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/hosting_project_name___lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -193,7 +193,7 @@ } /** -@@ -387,6 +575,268 @@ +@@ -457,6 +645,324 @@ $settings['trusted_host_patterns'] = [ '^localhost$', '^127\.0\.0\.1$', @@ -240,12 +240,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PREVIEW; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -306,12 +320,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_DEV; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -356,7 +384,7 @@ + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; -+ $config['reroute_email.settings']['enable'] = FALSE; ++ $config['reroute_email.settings']['enable'] = TRUE; + $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; + $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; + $config['shield.settings']['shield_enable'] = TRUE; @@ -372,12 +400,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_STAGE; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -436,12 +478,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PROD; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_circleci/.circleci/config.yml index 4acc6eb0fc..3029359759 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -188,10 +193,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -428,6 +438,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/.env b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/.env index 6741b81b05..fcb07a3f1c 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/.env @@ -1,4 +1,4 @@ -@@ -142,6 +142,18 @@ +@@ -148,6 +148,18 @@ VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 ################################################################################ @@ -17,7 +17,7 @@ # DATABASE SOURCE # ################################################################################ -@@ -164,12 +176,14 @@ +@@ -170,12 +182,14 @@ VORTEX_DB_FILE=db.sql # Database fetch source. @@ -36,7 +36,7 @@ ################################################################################ # RELEASE VERSIONING # -@@ -187,7 +201,7 @@ +@@ -193,7 +207,7 @@ # Deployment occurs when tests pass in the CI environment. # @see https://www.vortextemplate.com/docs/deployment @@ -45,7 +45,7 @@ ################################################################################ # NOTIFICATIONS # -@@ -214,17 +228,3 @@ +@@ -220,17 +234,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/.github/workflows/build-test-deploy.yml index 3569e59c68..5de23e5207 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/.github/workflows/build-test-deploy.yml @@ -14,7 +14,7 @@ # On the first build of the day (cache miss), fetch a fresh DB dump. # On subsequent builds, the restored cache already contains the dump and # the fetch script skips itself, leaving no semaphore file behind. -@@ -589,7 +598,6 @@ +@@ -594,7 +603,6 @@ VORTEX_DEPLOY_PR: ${{ env.DEPLOY_PR_NUMBER || github.event.number }} VORTEX_DEPLOY_PR_HEAD: ${{ env.DEPLOY_PR_HEAD_SHA || github.event.pull_request.head.sha }} VORTEX_DEPLOY_PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }} diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/composer.json b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/composer.json index 17423e068c..54a9a90cf9 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,7 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,7 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/lagoon_logs": "__VERSION__", "drupal/navigation_extra_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/docker-compose.yml index 274b83248e..a5a8de4809 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/docker-compose.yml @@ -17,7 +17,7 @@ webserver: build: -@@ -126,6 +131,11 @@ +@@ -127,6 +132,11 @@ networks: - default # This is a standard network and is used for all other environments, where requests routing is not required and/or not supported. - amazeeio-network ### This network is supported by Pygmy and used to route all requests to host machine locally. Removed in CI. @@ -29,7 +29,7 @@ # PHP FPM container. All web requests are going through this container. appserver: -@@ -141,6 +151,11 @@ +@@ -142,6 +152,11 @@ <<: [ *default-volumes, *default-user ] depends_on: - cli @@ -41,7 +41,7 @@ database: build: -@@ -153,9 +168,13 @@ +@@ -154,9 +169,13 @@ <<: *default-user ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -55,7 +55,7 @@ search: build: -@@ -167,6 +186,8 @@ +@@ -168,6 +187,8 @@ - search:/var/solr ports: - '8983' # Solr port in a container. Find port on host with `ahoy info` or `docker compose port search 8983`. @@ -64,7 +64,7 @@ antivirus: build: -@@ -178,6 +199,10 @@ +@@ -179,6 +200,10 @@ - '3310' # Find port on host with `docker compose port antivirus 3310`. networks: - default @@ -75,7 +75,7 @@ # Browser container, used for browser testing. browser: -@@ -190,6 +215,8 @@ +@@ -191,6 +216,8 @@ ports: - '7900' # Find port on host with `docker compose port browser 7900`. shm_size: '1gb' # Increase '/dev/shm' partition size to avoid browser crashing. @@ -84,7 +84,7 @@ # Helper container to wait for services to become available. wait-for-dependencies: -@@ -205,6 +232,8 @@ +@@ -206,6 +233,8 @@ - cache:6379 - search:8983 - curl -s "http://search:8983/solr/drupal/select?q=*:*&rows=0&wt=json" | grep response diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 9fd3befa4f..d52bba592e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_disabled_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -193,7 +193,7 @@ } /** -@@ -387,6 +575,268 @@ +@@ -457,6 +645,324 @@ $settings['trusted_host_patterns'] = [ '^localhost$', '^127\.0\.0\.1$', @@ -240,12 +240,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PREVIEW; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -306,12 +320,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_DEV; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -356,7 +384,7 @@ + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; -+ $config['reroute_email.settings']['enable'] = FALSE; ++ $config['reroute_email.settings']['enable'] = TRUE; + $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; + $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; + $config['shield.settings']['shield_enable'] = TRUE; @@ -372,12 +400,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_STAGE; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -436,12 +478,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PROD; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/.env b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/.env index 685e4a1fb0..ccbd3e5ee6 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/.env @@ -1,4 +1,4 @@ -@@ -172,6 +172,24 @@ +@@ -178,6 +178,24 @@ VORTEX_FETCH_DB_URL= ################################################################################ @@ -23,7 +23,7 @@ # RELEASE VERSIONING # ################################################################################ -@@ -228,3 +246,6 @@ +@@ -234,3 +252,6 @@ # URL of the database used for demonstration with URL database fetch type. VORTEX_FETCH_DB_URL=https://github.com/drevops/vortex/releases/download/__VERSION__/db.demo.sql diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/composer.json b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/composer.json index 929ec82a05..3fbb6f8b24 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,8 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,8 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/migrate_plus": "__VERSION__", + "drupal/migrate_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/docker-compose.yml index 0832fd028e..b7040520b7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/docker-compose.yml @@ -15,7 +15,7 @@ # The default user under which the containers should run. x-user: &default-user -@@ -154,6 +164,19 @@ +@@ -155,6 +165,19 @@ ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -35,7 +35,7 @@ cache: image: uselagoon/valkey-8:__VERSION__ -@@ -197,11 +220,13 @@ +@@ -198,11 +221,13 @@ depends_on: - antivirus - database diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 637212985c..bbc0904833 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -161,6 +161,13 @@ +@@ -175,6 +175,13 @@ $databases['default']['default']['collation'] = 'utf8_general_ci'; $databases['default']['default']['driver'] = 'mysql'; $databases['default']['default']['prefix'] = ''; diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/tests/phpunit/Drupal/SettingsTestCase.php index 5da9cd8793..d23b3c0de1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled/tests/phpunit/Drupal/SettingsTestCase.php @@ -4,5 +4,5 @@ 'DATABASE_', + 'DATABASE2_', 'REDIS_', + 'CLAMAV_', 'COMPOSE_', - 'GITHUB_', diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/.circleci/config.yml index 0003848156..5a60f1909b 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -188,10 +193,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -438,6 +448,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/.env b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/.env index 685e4a1fb0..ccbd3e5ee6 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/.env @@ -1,4 +1,4 @@ -@@ -172,6 +172,24 @@ +@@ -178,6 +178,24 @@ VORTEX_FETCH_DB_URL= ################################################################################ @@ -23,7 +23,7 @@ # RELEASE VERSIONING # ################################################################################ -@@ -228,3 +246,6 @@ +@@ -234,3 +252,6 @@ # URL of the database used for demonstration with URL database fetch type. VORTEX_FETCH_DB_URL=https://github.com/drevops/vortex/releases/download/__VERSION__/db.demo.sql diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/composer.json b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/composer.json index 929ec82a05..3fbb6f8b24 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,8 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,8 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/migrate_plus": "__VERSION__", + "drupal/migrate_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/docker-compose.yml index 0832fd028e..b7040520b7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/docker-compose.yml @@ -15,7 +15,7 @@ # The default user under which the containers should run. x-user: &default-user -@@ -154,6 +164,19 @@ +@@ -155,6 +165,19 @@ ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -35,7 +35,7 @@ cache: image: uselagoon/valkey-8:__VERSION__ -@@ -197,11 +220,13 @@ +@@ -198,11 +221,13 @@ depends_on: - antivirus - database diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 4620253313..8dbdd62e6c 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -161,6 +161,13 @@ +@@ -175,6 +175,13 @@ $databases['default']['default']['collation'] = 'utf8_general_ci'; $databases['default']['default']['driver'] = 'mysql'; $databases['default']['default']['prefix'] = ''; @@ -12,7 +12,7 @@ $this->assertEquals($databases, $this->databases); // Verify key config overrides. -@@ -332,9 +339,9 @@ +@@ -388,9 +395,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/tests/phpunit/Drupal/SettingsTestCase.php index 5da9cd8793..d23b3c0de1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_circleci/tests/phpunit/Drupal/SettingsTestCase.php @@ -4,5 +4,5 @@ 'DATABASE_', + 'DATABASE2_', 'REDIS_', + 'CLAMAV_', 'COMPOSE_', - 'GITHUB_', diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/.env b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/.env index 7e7c03adf5..9c87e86f44 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/.env @@ -1,4 +1,4 @@ -@@ -142,6 +142,18 @@ +@@ -148,6 +148,18 @@ VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 ################################################################################ @@ -17,7 +17,7 @@ # DATABASE SOURCE # ################################################################################ -@@ -164,14 +176,34 @@ +@@ -170,14 +182,34 @@ VORTEX_DB_FILE=db.sql # Database fetch source. @@ -56,7 +56,7 @@ # RELEASE VERSIONING # ################################################################################ -@@ -187,7 +219,7 @@ +@@ -193,7 +225,7 @@ # Deployment occurs when tests pass in the CI environment. # @see https://www.vortextemplate.com/docs/deployment @@ -65,7 +65,7 @@ ################################################################################ # NOTIFICATIONS # -@@ -214,17 +246,3 @@ +@@ -220,17 +252,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/.github/workflows/build-test-deploy.yml index e025e1ba1f..b52861b284 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/.github/workflows/build-test-deploy.yml @@ -36,7 +36,7 @@ docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli ./vendor/bin/vortex-provision timeout-minutes: 30 -@@ -589,7 +606,6 @@ +@@ -594,7 +611,6 @@ VORTEX_DEPLOY_PR: ${{ env.DEPLOY_PR_NUMBER || github.event.number }} VORTEX_DEPLOY_PR_HEAD: ${{ env.DEPLOY_PR_HEAD_SHA || github.event.pull_request.head.sha }} VORTEX_DEPLOY_PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }} diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/composer.json b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/composer.json index c02ce63a1f..42a1a5da9f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,9 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,9 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/lagoon_logs": "__VERSION__", + "drupal/migrate_plus": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/docker-compose.yml index d97f8c8f50..27a7ad4ec3 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/docker-compose.yml @@ -34,7 +34,7 @@ webserver: build: -@@ -126,6 +141,11 @@ +@@ -127,6 +142,11 @@ networks: - default # This is a standard network and is used for all other environments, where requests routing is not required and/or not supported. - amazeeio-network ### This network is supported by Pygmy and used to route all requests to host machine locally. Removed in CI. @@ -46,7 +46,7 @@ # PHP FPM container. All web requests are going through this container. appserver: -@@ -141,6 +161,11 @@ +@@ -142,6 +162,11 @@ <<: [ *default-volumes, *default-user ] depends_on: - cli @@ -58,7 +58,7 @@ database: build: -@@ -153,9 +178,26 @@ +@@ -154,9 +179,26 @@ <<: *default-user ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -85,7 +85,7 @@ search: build: -@@ -167,6 +209,8 @@ +@@ -168,6 +210,8 @@ - search:/var/solr ports: - '8983' # Solr port in a container. Find port on host with `ahoy info` or `docker compose port search 8983`. @@ -94,7 +94,7 @@ antivirus: build: -@@ -178,6 +222,10 @@ +@@ -179,6 +223,10 @@ - '3310' # Find port on host with `docker compose port antivirus 3310`. networks: - default @@ -105,7 +105,7 @@ # Browser container, used for browser testing. browser: -@@ -190,6 +238,8 @@ +@@ -191,6 +239,8 @@ ports: - '7900' # Find port on host with `docker compose port browser 7900`. shm_size: '1gb' # Increase '/dev/shm' partition size to avoid browser crashing. @@ -114,7 +114,7 @@ # Helper container to wait for services to become available. wait-for-dependencies: -@@ -197,14 +247,18 @@ +@@ -198,14 +248,18 @@ depends_on: - antivirus - database diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 0e761edc83..fce123ddd3 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -193,7 +193,7 @@ } /** -@@ -161,6 +349,13 @@ +@@ -175,6 +363,13 @@ $databases['default']['default']['collation'] = 'utf8_general_ci'; $databases['default']['default']['driver'] = 'mysql'; $databases['default']['default']['prefix'] = ''; @@ -207,7 +207,7 @@ $this->assertEquals($databases, $this->databases); // Verify key config overrides. -@@ -387,6 +582,268 @@ +@@ -457,6 +652,324 @@ $settings['trusted_host_patterns'] = [ '^localhost$', '^127\.0\.0\.1$', @@ -254,12 +254,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PREVIEW; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -320,12 +334,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_DEV; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -370,7 +398,7 @@ + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; -+ $config['reroute_email.settings']['enable'] = FALSE; ++ $config['reroute_email.settings']['enable'] = TRUE; + $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; + $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; + $config['shield.settings']['shield_enable'] = TRUE; @@ -386,12 +414,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_STAGE; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -450,12 +492,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PROD; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/tests/phpunit/Drupal/SettingsTestCase.php index 5da9cd8793..d23b3c0de1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_enabled_lagoon/tests/phpunit/Drupal/SettingsTestCase.php @@ -4,5 +4,5 @@ 'DATABASE_', + 'DATABASE2_', 'REDIS_', + 'CLAMAV_', 'COMPOSE_', - 'GITHUB_', diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/.env b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/.env index 3c1e49ebf4..e3cb09227d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/.env @@ -1,4 +1,4 @@ -@@ -172,6 +172,24 @@ +@@ -178,6 +178,24 @@ VORTEX_FETCH_DB_URL= ################################################################################ diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/composer.json b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/composer.json index 929ec82a05..3fbb6f8b24 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,8 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,8 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/migrate_plus": "__VERSION__", + "drupal/migrate_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/docker-compose.yml index 0832fd028e..b7040520b7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/docker-compose.yml @@ -15,7 +15,7 @@ # The default user under which the containers should run. x-user: &default-user -@@ -154,6 +164,19 @@ +@@ -155,6 +165,19 @@ ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -35,7 +35,7 @@ cache: image: uselagoon/valkey-8:__VERSION__ -@@ -197,11 +220,13 @@ +@@ -198,11 +221,13 @@ depends_on: - antivirus - database diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 637212985c..bbc0904833 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -161,6 +161,13 @@ +@@ -175,6 +175,13 @@ $databases['default']['default']['collation'] = 'utf8_general_ci'; $databases['default']['default']['driver'] = 'mysql'; $databases['default']['default']['prefix'] = ''; diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/tests/phpunit/Drupal/SettingsTestCase.php index 5da9cd8793..d23b3c0de1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_acquia/tests/phpunit/Drupal/SettingsTestCase.php @@ -4,5 +4,5 @@ 'DATABASE_', + 'DATABASE2_', 'REDIS_', + 'CLAMAV_', 'COMPOSE_', - 'GITHUB_', diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/.env b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/.env index bf1e3c0919..52cdab317a 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/.env @@ -1,4 +1,4 @@ -@@ -172,6 +172,23 @@ +@@ -178,6 +178,23 @@ VORTEX_FETCH_DB_URL= ################################################################################ diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/composer.json b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/composer.json index 929ec82a05..3fbb6f8b24 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,8 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,8 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/migrate_plus": "__VERSION__", + "drupal/migrate_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/docker-compose.yml index 0832fd028e..b7040520b7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/docker-compose.yml @@ -15,7 +15,7 @@ # The default user under which the containers should run. x-user: &default-user -@@ -154,6 +164,19 @@ +@@ -155,6 +165,19 @@ ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -35,7 +35,7 @@ cache: image: uselagoon/valkey-8:__VERSION__ -@@ -197,11 +220,13 @@ +@@ -198,11 +221,13 @@ depends_on: - antivirus - database diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 637212985c..bbc0904833 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -161,6 +161,13 @@ +@@ -175,6 +175,13 @@ $databases['default']['default']['collation'] = 'utf8_general_ci'; $databases['default']['default']['driver'] = 'mysql'; $databases['default']['default']['prefix'] = ''; diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/tests/phpunit/Drupal/SettingsTestCase.php index 5da9cd8793..d23b3c0de1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_container_registry/tests/phpunit/Drupal/SettingsTestCase.php @@ -4,5 +4,5 @@ 'DATABASE_', + 'DATABASE2_', 'REDIS_', + 'CLAMAV_', 'COMPOSE_', - 'GITHUB_', diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/.env b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/.env index b0fcb6c541..42adc5bb62 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/.env @@ -1,4 +1,4 @@ -@@ -172,6 +172,30 @@ +@@ -178,6 +178,30 @@ VORTEX_FETCH_DB_URL= ################################################################################ diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/composer.json b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/composer.json index 929ec82a05..3fbb6f8b24 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,8 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,8 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/migrate_plus": "__VERSION__", + "drupal/migrate_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/docker-compose.yml index 0832fd028e..b7040520b7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/docker-compose.yml @@ -15,7 +15,7 @@ # The default user under which the containers should run. x-user: &default-user -@@ -154,6 +164,19 @@ +@@ -155,6 +165,19 @@ ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -35,7 +35,7 @@ cache: image: uselagoon/valkey-8:__VERSION__ -@@ -197,11 +220,13 @@ +@@ -198,11 +221,13 @@ depends_on: - antivirus - database diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 637212985c..bbc0904833 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -161,6 +161,13 @@ +@@ -175,6 +175,13 @@ $databases['default']['default']['collation'] = 'utf8_general_ci'; $databases['default']['default']['driver'] = 'mysql'; $databases['default']['default']['prefix'] = ''; diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/tests/phpunit/Drupal/SettingsTestCase.php index 5da9cd8793..d23b3c0de1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_ftp/tests/phpunit/Drupal/SettingsTestCase.php @@ -4,5 +4,5 @@ 'DATABASE_', + 'DATABASE2_', 'REDIS_', + 'CLAMAV_', 'COMPOSE_', - 'GITHUB_', diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/.env b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/.env index dda7bce666..58fc94bb83 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/.env @@ -1,4 +1,4 @@ -@@ -172,6 +172,24 @@ +@@ -178,6 +178,24 @@ VORTEX_FETCH_DB_URL= ################################################################################ diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/composer.json b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/composer.json index 929ec82a05..3fbb6f8b24 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,8 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,8 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/migrate_plus": "__VERSION__", + "drupal/migrate_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/docker-compose.yml index 0832fd028e..b7040520b7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/docker-compose.yml @@ -15,7 +15,7 @@ # The default user under which the containers should run. x-user: &default-user -@@ -154,6 +164,19 @@ +@@ -155,6 +165,19 @@ ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -35,7 +35,7 @@ cache: image: uselagoon/valkey-8:__VERSION__ -@@ -197,11 +220,13 @@ +@@ -198,11 +221,13 @@ depends_on: - antivirus - database diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 637212985c..bbc0904833 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -161,6 +161,13 @@ +@@ -175,6 +175,13 @@ $databases['default']['default']['collation'] = 'utf8_general_ci'; $databases['default']['default']['driver'] = 'mysql'; $databases['default']['default']['prefix'] = ''; diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/tests/phpunit/Drupal/SettingsTestCase.php index 5da9cd8793..d23b3c0de1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_lagoon/tests/phpunit/Drupal/SettingsTestCase.php @@ -4,5 +4,5 @@ 'DATABASE_', + 'DATABASE2_', 'REDIS_', + 'CLAMAV_', 'COMPOSE_', - 'GITHUB_', diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/.env b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/.env index 47628f1640..597e9512e2 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/.env @@ -1,4 +1,4 @@ -@@ -172,6 +172,27 @@ +@@ -178,6 +178,27 @@ VORTEX_FETCH_DB_URL= ################################################################################ diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/composer.json b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/composer.json index 929ec82a05..3fbb6f8b24 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,8 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,8 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/migrate_plus": "__VERSION__", + "drupal/migrate_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/docker-compose.yml index 0832fd028e..b7040520b7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/docker-compose.yml @@ -15,7 +15,7 @@ # The default user under which the containers should run. x-user: &default-user -@@ -154,6 +164,19 @@ +@@ -155,6 +165,19 @@ ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -35,7 +35,7 @@ cache: image: uselagoon/valkey-8:__VERSION__ -@@ -197,11 +220,13 @@ +@@ -198,11 +221,13 @@ depends_on: - antivirus - database diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 637212985c..bbc0904833 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -161,6 +161,13 @@ +@@ -175,6 +175,13 @@ $databases['default']['default']['collation'] = 'utf8_general_ci'; $databases['default']['default']['driver'] = 'mysql'; $databases['default']['default']['prefix'] = ''; diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/tests/phpunit/Drupal/SettingsTestCase.php index 5da9cd8793..d23b3c0de1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_s3/tests/phpunit/Drupal/SettingsTestCase.php @@ -4,5 +4,5 @@ 'DATABASE_', + 'DATABASE2_', 'REDIS_', + 'CLAMAV_', 'COMPOSE_', - 'GITHUB_', diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/.env b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/.env index 685e4a1fb0..ccbd3e5ee6 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/.env @@ -1,4 +1,4 @@ -@@ -172,6 +172,24 @@ +@@ -178,6 +178,24 @@ VORTEX_FETCH_DB_URL= ################################################################################ @@ -23,7 +23,7 @@ # RELEASE VERSIONING # ################################################################################ -@@ -228,3 +246,6 @@ +@@ -234,3 +252,6 @@ # URL of the database used for demonstration with URL database fetch type. VORTEX_FETCH_DB_URL=https://github.com/drevops/vortex/releases/download/__VERSION__/db.demo.sql diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/composer.json b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/composer.json index 929ec82a05..3fbb6f8b24 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,8 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,8 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/migrate_plus": "__VERSION__", + "drupal/migrate_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/docker-compose.yml index 0832fd028e..b7040520b7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/docker-compose.yml @@ -15,7 +15,7 @@ # The default user under which the containers should run. x-user: &default-user -@@ -154,6 +164,19 @@ +@@ -155,6 +165,19 @@ ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -35,7 +35,7 @@ cache: image: uselagoon/valkey-8:__VERSION__ -@@ -197,11 +220,13 @@ +@@ -198,11 +221,13 @@ depends_on: - antivirus - database diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 637212985c..bbc0904833 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -161,6 +161,13 @@ +@@ -175,6 +175,13 @@ $databases['default']['default']['collation'] = 'utf8_general_ci'; $databases['default']['default']['driver'] = 'mysql'; $databases['default']['default']['prefix'] = ''; diff --git a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/tests/phpunit/Drupal/SettingsTestCase.php index 5da9cd8793..d23b3c0de1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/cli/tests/Fixtures/handler_process/migration_fetch_source_url/tests/phpunit/Drupal/SettingsTestCase.php @@ -4,5 +4,5 @@ 'DATABASE_', + 'DATABASE2_', 'REDIS_', + 'CLAMAV_', 'COMPOSE_', - 'GITHUB_', diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_config_split/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_config_split/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 644023553c..a26933fe29 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_config_split/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_config_split/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -221,7 +221,6 @@ +@@ -249,7 +249,6 @@ $this->requireSettingsFile(); $config['automated_cron.settings']['interval'] = 0; @@ -6,7 +6,7 @@ $config['environment_indicator.indicator']['bg_color'] = '#006600'; $config['environment_indicator.indicator']['fg_color'] = '#ffffff'; $config['environment_indicator.indicator']['name'] = self::ENVIRONMENT_LOCAL; -@@ -281,7 +280,6 @@ +@@ -323,7 +322,6 @@ $this->requireSettingsFile(); $config['automated_cron.settings']['interval'] = 0; @@ -14,7 +14,7 @@ $config['environment_indicator.indicator']['bg_color'] = '#006600'; $config['environment_indicator.indicator']['fg_color'] = '#ffffff'; $config['environment_indicator.indicator']['name'] = self::ENVIRONMENT_LOCAL; -@@ -342,7 +340,6 @@ +@@ -398,7 +396,6 @@ $this->requireSettingsFile(); $config['automated_cron.settings']['interval'] = 0; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_config_split/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_config_split/tests/phpunit/Drupal/SwitchableSettingsTest.php index 476aa8044b..33114ffa6f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_config_split/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_config_split/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,4 +1,4 @@ -@@ -76,91 +76,6 @@ +@@ -119,91 +119,6 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_devel/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_devel/composer.json index 47ecfbf761..3eeed0ad03 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_devel/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_devel/composer.json @@ -5,4 +5,4 @@ - "drupal/devel": "__VERSION__", "drupal/drupal_helpers": "__VERSION__", "drupal/environment_indicator": "__VERSION__", - "drupal/generated_content": "__VERSION__", + "drupal/fast_404": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_devel/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_devel/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 50e6d32d0c..94a51044d7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_devel/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_devel/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -4,37 +4,37 @@ $settings['config_exclude_modules'] = [ - 'devel', 'generated_content', - 'testmode', - ]; -@@ -184,7 +183,6 @@ + 'reroute_email', + 'sdc_devel', +@@ -198,7 +197,6 @@ // Verify settings overrides. $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ - 'devel', 'generated_content', - 'testmode', - ]; -@@ -244,7 +242,6 @@ + 'reroute_email', + 'sdc_devel', +@@ -272,7 +270,6 @@ $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ - 'devel', 'generated_content', - 'testmode', - ]; -@@ -304,7 +301,6 @@ + 'reroute_email', + 'sdc_devel', +@@ -346,7 +343,6 @@ $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ - 'devel', 'generated_content', - 'testmode', - ]; -@@ -366,7 +362,6 @@ + 'reroute_email', + 'sdc_devel', +@@ -422,7 +418,6 @@ $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ - 'devel', 'generated_content', - 'testmode', - ]; + 'reroute_email', + 'sdc_devel', diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_devel/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_devel/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 90be61fb25..195b46f52e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_devel/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_devel/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,9 +1,9 @@ -@@ -102,8 +102,6 @@ +@@ -101,8 +101,6 @@ $this->moduleInstaller->install(['sdc_devel']); - $this->moduleInstaller->install(['devel']); - - $this->moduleInstaller->install(['sw_search']); + $this->moduleInstaller->install(['reroute_email']); - $this->moduleInstaller->install(['sw_demo']); + $this->moduleInstaller->install(['sw_search']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_drupal_helpers/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_drupal_helpers/composer.json index ed10d5a1f4..4aed551ce8 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_drupal_helpers/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_drupal_helpers/composer.json @@ -4,5 +4,5 @@ "drupal/devel": "__VERSION__", - "drupal/drupal_helpers": "__VERSION__", "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", - "drupal/navigation_extra_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_environment_indicator/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_environment_indicator/composer.json index 1edb950025..029112d0d6 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_environment_indicator/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_environment_indicator/composer.json @@ -3,6 +3,6 @@ "drupal/devel": "__VERSION__", "drupal/drupal_helpers": "__VERSION__", - "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", "drupal/navigation_extra_tools": "__VERSION__", - "drupal/pathauto": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_environment_indicator/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_environment_indicator/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 3d6674e51b..eb3c33fd17 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_environment_indicator/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_environment_indicator/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -10,7 +10,7 @@ $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; $config['shield.settings']['shield_enable'] = TRUE; $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; -@@ -164,11 +159,6 @@ +@@ -178,11 +173,6 @@ $this->assertEquals($databases, $this->databases); // Verify key config overrides. @@ -22,7 +22,7 @@ $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; $config['shield.settings']['shield_enable'] = TRUE; $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; -@@ -222,11 +212,6 @@ +@@ -250,11 +240,6 @@ $config['automated_cron.settings']['interval'] = 0; $config['config_split.config_split.local']['status'] = TRUE; @@ -34,7 +34,7 @@ $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; $config['shield.settings']['shield_enable'] = FALSE; $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; -@@ -282,11 +267,6 @@ +@@ -324,11 +309,6 @@ $config['automated_cron.settings']['interval'] = 0; $config['config_split.config_split.local']['status'] = TRUE; @@ -46,7 +46,7 @@ $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; $config['shield.settings']['shield_enable'] = FALSE; $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; -@@ -343,11 +323,6 @@ +@@ -399,11 +379,6 @@ $config['automated_cron.settings']['interval'] = 0; $config['config_split.config_split.ci']['status'] = TRUE; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_environment_indicator/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_environment_indicator/tests/phpunit/Drupal/SwitchableSettingsTest.php index 0c6765d951..94b2c64510 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_environment_indicator/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_environment_indicator/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,4 +1,4 @@ -@@ -161,69 +161,6 @@ +@@ -204,69 +204,6 @@ } /** @@ -65,6 +65,6 @@ - } - - /** - * Test Redis settings. - */ - public function testRedis(): void { + * Test Fast 404 settings. + * + * Runs isolated so that the module stub owns the 'fast404_preboot()' diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/composer.json new file mode 100644 index 0000000000..c44493d12f --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/composer.json @@ -0,0 +1,8 @@ +@@ -19,7 +19,6 @@ + "drupal/devel": "__VERSION__", + "drupal/drupal_helpers": "__VERSION__", + "drupal/environment_indicator": "__VERSION__", +- "drupal/fast_404": "__VERSION__", + "drupal/generated_content": "__VERSION__", + "drupal/navigation_extra_tools": "__VERSION__", + "drupal/pathauto": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/tests/phpunit/Drupal/EnvironmentSettingsTest.php new file mode 100644 index 0000000000..3619ca29af --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -0,0 +1,95 @@ +@@ -107,18 +107,6 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_SUT; +- $settings['fast404_allow_anon_imagecache'] = TRUE; +- $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +- $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; +- $settings['fast404_path_check'] = FALSE; +- $settings['fast404_respect_redirect'] = FALSE; +- $settings['fast404_url_whitelisting'] = TRUE; +- $settings['fast404_whitelist'] = [ +- 'index.php', +- 'rss.xml', +- 'cron.php', +- 'xmlrpc.php', +- ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; +@@ -208,18 +196,6 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_SUT; +- $settings['fast404_allow_anon_imagecache'] = TRUE; +- $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +- $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; +- $settings['fast404_path_check'] = FALSE; +- $settings['fast404_respect_redirect'] = FALSE; +- $settings['fast404_url_whitelisting'] = TRUE; +- $settings['fast404_whitelist'] = [ +- 'index.php', +- 'rss.xml', +- 'cron.php', +- 'xmlrpc.php', +- ]; + $settings['file_public_path'] = 'custom_public'; + $settings['file_private_path'] = 'custom_private'; + $settings['file_temp_path'] = 'custom_temp'; +@@ -281,18 +257,6 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_LOCAL; +- $settings['fast404_allow_anon_imagecache'] = TRUE; +- $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +- $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; +- $settings['fast404_path_check'] = FALSE; +- $settings['fast404_respect_redirect'] = FALSE; +- $settings['fast404_url_whitelisting'] = TRUE; +- $settings['fast404_whitelist'] = [ +- 'index.php', +- 'rss.xml', +- 'cron.php', +- 'xmlrpc.php', +- ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; +@@ -355,18 +319,6 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_LOCAL; +- $settings['fast404_allow_anon_imagecache'] = TRUE; +- $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +- $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; +- $settings['fast404_path_check'] = FALSE; +- $settings['fast404_respect_redirect'] = FALSE; +- $settings['fast404_url_whitelisting'] = TRUE; +- $settings['fast404_whitelist'] = [ +- 'index.php', +- 'rss.xml', +- 'cron.php', +- 'xmlrpc.php', +- ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; +@@ -431,18 +383,6 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_CI; +- $settings['fast404_allow_anon_imagecache'] = TRUE; +- $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +- $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; +- $settings['fast404_path_check'] = FALSE; +- $settings['fast404_respect_redirect'] = FALSE; +- $settings['fast404_url_whitelisting'] = TRUE; +- $settings['fast404_whitelist'] = [ +- 'index.php', +- 'rss.xml', +- 'cron.php', +- 'xmlrpc.php', +- ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/tests/phpunit/Drupal/SwitchableSettingsTest.php new file mode 100644 index 0000000000..cda7c9c0f7 --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -0,0 +1,142 @@ +@@ -4,8 +4,6 @@ + + namespace Drupal; + +-use PHPUnit\Framework\Attributes\PreserveGlobalState; +-use PHPUnit\Framework\Attributes\RunInSeparateProcess; + use PHPUnit\Framework\Attributes\DataProvider; + use PHPUnit\Framework\Attributes\Group; + +@@ -22,22 +20,6 @@ + class SwitchableSettingsTest extends SettingsTestCase { + + /** +- * Path to the contrib modules directory fixture. +- */ +- protected ?string $contribFixture = NULL; +- +- /** +- * {@inheritdoc} +- */ +- protected function tearDown(): void { +- if (!is_null($this->contribFixture)) { +- $this->removeContribFixture($this->contribFixture); +- } +- +- parent::tearDown(); +- } +- +- /** + * Test ClamAV config. + */ + #[DataProvider('dataProviderClamav')] +@@ -264,109 +246,6 @@ + 'environment_indicator.settings' => ['toolbar_integration' => [TRUE], 'favicon' => TRUE], + ], + ]; +- } +- +- /** +- * Test Fast 404 settings. +- * +- * Runs isolated so that the module stub owns the 'fast404_preboot()' +- * declaration and its invocation marker is conclusive. +- */ +- #[DataProvider('dataProviderFast404')] +- #[RunInSeparateProcess] +- #[PreserveGlobalState(FALSE)] +- public function testFast404(bool $module_installed, array $expected_present, array $expected_absent = []): void { +- $contrib_path = $this->createContribFixture($module_installed); +- +- $this->requireModuleSettingsFile('fast_404', $contrib_path); +- +- $this->assertSettingsContains($expected_present); +- $this->assertSettingsNotContains($expected_absent); +- $this->assertSame($module_installed, file_exists($contrib_path . '/fast_404/preboot'), 'Preboot invocation'); +- } +- +- /** +- * Data provider for testFast404(). +- */ +- public static function dataProviderFast404(): \Iterator { +- yield 'module installed' => [ +- TRUE, +- [ +- 'fast404_exts' => '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i', +- 'fast404_allow_anon_imagecache' => TRUE, +- 'fast404_url_whitelisting' => TRUE, +- 'fast404_whitelist' => ['index.php', 'rss.xml', 'cron.php', 'xmlrpc.php'], +- 'fast404_path_check' => FALSE, +- 'fast404_respect_redirect' => FALSE, +- 'fast404_html' => '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

', +- ], +- ]; +- yield 'module not installed' => [ +- FALSE, +- [], +- [ +- 'fast404_exts' => NULL, +- 'fast404_allow_anon_imagecache' => NULL, +- 'fast404_url_whitelisting' => NULL, +- 'fast404_whitelist' => NULL, +- 'fast404_path_check' => NULL, +- 'fast404_respect_redirect' => NULL, +- 'fast404_html' => NULL, +- ], +- ]; +- } +- +- /** +- * Create a contrib modules directory fixture. +- * +- * The Fast 404 module is not required by the project, so its settings file +- * guard can only be satisfied by a stub. +- * +- * @param bool $with_fast404 +- * Create a stub of the Fast 404 module within the fixture. The stub marks +- * the directory when its preboot function is called. +- * +- * @return string +- * Path to the contrib modules directory fixture. +- */ +- protected function createContribFixture(bool $with_fast404): string { +- $this->contribFixture = getcwd() . '/.artifacts/tmp/' . uniqid('contrib-'); +- +- mkdir($this->contribFixture, 0777, TRUE); +- +- if ($with_fast404) { +- $stub = <<<'PHP' +- contribFixture . '/fast_404'); +- file_put_contents($this->contribFixture . '/fast_404/fast404.inc', $stub); +- } +- +- return $this->contribFixture; +- } +- +- /** +- * Remove the contrib modules directory fixture. +- * +- * @param string $path +- * Path to the contrib modules directory fixture. +- */ +- protected function removeContribFixture(string $path): void { +- foreach (glob($path . '/*/*') ?: [] as $file) { +- unlink($file); +- } +- +- foreach (glob($path . '/*', GLOB_ONLYDIR) ?: [] as $dir) { +- rmdir($dir); +- } +- +- rmdir($path); + } + + /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/web/sites/default/includes/modules/-settings.fast_404.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_fast_404/web/sites/default/includes/modules/-settings.fast_404.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_generated_content/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_generated_content/composer.json index 6ee5b6fc1b..16718488cc 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_generated_content/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_generated_content/composer.json @@ -1,7 +1,7 @@ -@@ -19,7 +19,6 @@ - "drupal/devel": "__VERSION__", +@@ -20,7 +20,6 @@ "drupal/drupal_helpers": "__VERSION__", "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", - "drupal/generated_content": "__VERSION__", "drupal/navigation_extra_tools": "__VERSION__", "drupal/pathauto": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_generated_content/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_generated_content/tests/phpunit/Drupal/EnvironmentSettingsTest.php index a5738b526f..201d9b8217 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_generated_content/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_generated_content/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -3,38 +3,38 @@ $settings['config_exclude_modules'] = [ 'devel', - 'generated_content', + 'reroute_email', + 'sdc_devel', 'testmode', - ]; - $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; -@@ -185,7 +184,6 @@ +@@ -199,7 +198,6 @@ $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ 'devel', - 'generated_content', + 'reroute_email', + 'sdc_devel', 'testmode', - ]; - $settings['config_sync_directory'] = 'custom_config'; -@@ -245,7 +243,6 @@ +@@ -273,7 +271,6 @@ $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ 'devel', - 'generated_content', + 'reroute_email', + 'sdc_devel', 'testmode', - ]; - $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; -@@ -305,7 +302,6 @@ +@@ -347,7 +344,6 @@ $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ 'devel', - 'generated_content', + 'reroute_email', + 'sdc_devel', 'testmode', - ]; - $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; -@@ -367,7 +363,6 @@ +@@ -423,7 +419,6 @@ $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ 'devel', - 'generated_content', + 'reroute_email', + 'sdc_devel', 'testmode', - ]; - $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_generated_content/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_generated_content/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index c415227578..961b822daf 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_generated_content/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_generated_content/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,4 +1,4 @@ -@@ -108,15 +108,6 @@ +@@ -109,15 +109,6 @@ $this->moduleInstaller->install(['sw_demo']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_navigation_extra_tools/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_navigation_extra_tools/composer.json index 90c95d443c..214ae5b707 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_navigation_extra_tools/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_navigation_extra_tools/composer.json @@ -1,6 +1,6 @@ -@@ -20,7 +20,6 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,7 +21,6 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", - "drupal/navigation_extra_tools": "__VERSION__", "drupal/pathauto": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_navigation_extra_tools/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_navigation_extra_tools/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 695c96c3eb..d4adf75378 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_navigation_extra_tools/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_navigation_extra_tools/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -5,4 +5,4 @@ - 'navigation_extra_tools', 'pathauto', 'redirect', - 'reroute_email', + 'robotstxt', diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_pathauto/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_pathauto/composer.json index b54611a338..69ea126f26 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_pathauto/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_pathauto/composer.json @@ -1,5 +1,5 @@ -@@ -21,7 +21,6 @@ - "drupal/environment_indicator": "__VERSION__", +@@ -22,7 +22,6 @@ + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", "drupal/navigation_extra_tools": "__VERSION__", - "drupal/pathauto": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_pathauto/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_pathauto/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 55fce236d3..c251ada8a6 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_pathauto/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_pathauto/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -4,5 +4,5 @@ 'navigation_extra_tools', - 'pathauto', 'redirect', - 'reroute_email', 'robotstxt', + 'shield', diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_redirect/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_redirect/composer.json index de2520ce2e..3971214493 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_redirect/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_redirect/composer.json @@ -1,4 +1,4 @@ -@@ -22,7 +22,6 @@ +@@ -23,7 +23,6 @@ "drupal/generated_content": "__VERSION__", "drupal/navigation_extra_tools": "__VERSION__", "drupal/pathauto": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_redirect/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_redirect/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 6b3716de27..bd2bad5537 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_redirect/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_redirect/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -3,6 +3,6 @@ 'navigation_extra_tools', 'pathauto', - 'redirect', - 'reroute_email', 'robotstxt', 'shield', + 'stage_file_proxy', diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/composer.json index a381927536..a54f7a0be7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/composer.json @@ -1,4 +1,4 @@ -@@ -24,7 +24,6 @@ +@@ -25,7 +25,6 @@ "drupal/pathauto": "__VERSION__", "drupal/redirect": "__VERSION__", "drupal/redis": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 6c62a2d9be..fb36f5a410 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -8,7 +8,15 @@ $config['system.performance']['cache']['page']['max_age'] = 900; $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; -@@ -173,9 +170,6 @@ +@@ -100,7 +97,6 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', +- 'reroute_email', + 'sdc_devel', + 'testmode', + ]; +@@ -187,9 +183,6 @@ $config['shield.settings']['shield_enable'] = TRUE; $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; @@ -18,7 +26,15 @@ $config['system.performance']['cache']['page']['max_age'] = 1800; $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; -@@ -233,9 +227,6 @@ +@@ -200,7 +193,6 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', +- 'reroute_email', + 'sdc_devel', + 'testmode', + ]; +@@ -261,9 +253,6 @@ $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['system.logging']['error_level'] = 'all'; $config['system.performance']['cache']['page']['max_age'] = 900; @@ -28,7 +44,15 @@ $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; -@@ -293,9 +284,6 @@ +@@ -274,7 +263,6 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', +- 'reroute_email', + 'sdc_devel', + 'testmode', + ]; +@@ -335,9 +323,6 @@ $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['system.logging']['error_level'] = 'all'; $config['system.performance']['cache']['page']['max_age'] = 900; @@ -38,7 +62,15 @@ $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; -@@ -355,9 +343,6 @@ +@@ -348,7 +333,6 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', +- 'reroute_email', + 'sdc_devel', + 'testmode', + ]; +@@ -411,9 +395,6 @@ $config['system.logging']['error_level'] = 'all'; $config['system.mail']['interface']['default'] = 'test_mail_collector'; $config['system.performance']['cache']['page']['max_age'] = 900; @@ -48,3 +80,11 @@ $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; +@@ -424,7 +405,6 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', +- 'reroute_email', + 'sdc_devel', + 'testmode', + ]; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/tests/phpunit/Drupal/SwitchableSettingsTest.php index 849f56abe4..71496b2d35 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,4 +1,4 @@ -@@ -695,145 +695,6 @@ +@@ -877,168 +877,6 @@ } /** @@ -54,12 +54,12 @@ - ], - ]; - -- // Stage: disabled by default. +- // Stage: enabled by default. - yield [ - self::ENVIRONMENT_STAGE, - [], - [ -- 'reroute_email.settings' => ['enable' => FALSE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'], +- 'reroute_email.settings' => ['enable' => TRUE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'], - ], - ]; - @@ -94,6 +94,17 @@ - ], - ]; - +- // Stage with DRUPAL_REROUTE_EMAIL_DISABLED: forced off. +- yield [ +- self::ENVIRONMENT_STAGE, +- [ +- 'DRUPAL_REROUTE_EMAIL_DISABLED' => 1, +- ], +- [ +- 'reroute_email.settings' => ['enable' => FALSE], +- ], +- ]; +- - // Custom address and allowed list. - yield [ - self::ENVIRONMENT_DEV, @@ -138,6 +149,18 @@ - 'reroute_email.settings' => ['enable' => FALSE], - ], - ]; +- +- // DRUPAL_REROUTE_EMAIL_DISABLED with a non-numeric truthy value: not +- // disabled. +- yield [ +- self::ENVIRONMENT_DEV, +- [ +- 'DRUPAL_REROUTE_EMAIL_DISABLED' => 'true', +- ], +- [ +- 'reroute_email.settings' => ['enable' => TRUE], +- ], +- ]; - } - - /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index bca24df1d6..d17503861a 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_reroute_email/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,8 +1,9 @@ -@@ -86,7 +86,6 @@ - 'navigation_extra_tools', - 'pathauto', - 'redirect', -- 'reroute_email', - 'robotstxt', - 'shield', - 'stage_file_proxy', +@@ -103,8 +103,6 @@ + + $this->moduleInstaller->install(['devel']); + +- $this->moduleInstaller->install(['reroute_email']); +- + $this->moduleInstaller->install(['sw_search']); + + $this->moduleInstaller->install(['sw_demo']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_robotstxt/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_robotstxt/composer.json index b5b2c86807..187d5a8176 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_robotstxt/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_robotstxt/composer.json @@ -1,4 +1,4 @@ -@@ -25,7 +25,6 @@ +@@ -26,7 +26,6 @@ "drupal/redirect": "__VERSION__", "drupal/redis": "__VERSION__", "drupal/reroute_email": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_robotstxt/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_robotstxt/tests/phpunit/Drupal/EnvironmentSettingsTest.php index f46f237b57..1fb257c826 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_robotstxt/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_robotstxt/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -6,7 +6,7 @@ $config['shield.settings']['shield_enable'] = TRUE; $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; -@@ -169,7 +168,6 @@ +@@ -183,7 +182,6 @@ $config['environment_indicator.indicator']['name'] = self::ENVIRONMENT_SUT; $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; @@ -14,7 +14,7 @@ $config['shield.settings']['shield_enable'] = TRUE; $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; -@@ -227,7 +225,6 @@ +@@ -255,7 +253,6 @@ $config['environment_indicator.indicator']['name'] = self::ENVIRONMENT_LOCAL; $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; @@ -22,7 +22,7 @@ $config['shield.settings']['shield_enable'] = FALSE; $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; -@@ -287,7 +284,6 @@ +@@ -329,7 +326,6 @@ $config['environment_indicator.indicator']['name'] = self::ENVIRONMENT_LOCAL; $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; @@ -30,7 +30,7 @@ $config['shield.settings']['shield_enable'] = FALSE; $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; -@@ -348,7 +344,6 @@ +@@ -404,7 +400,6 @@ $config['environment_indicator.indicator']['name'] = self::ENVIRONMENT_CI; $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_robotstxt/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_robotstxt/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 88def8942e..209537244c 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_robotstxt/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_robotstxt/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,7 +1,7 @@ -@@ -87,7 +87,6 @@ +@@ -86,7 +86,6 @@ + 'navigation_extra_tools', 'pathauto', 'redirect', - 'reroute_email', - 'robotstxt', 'shield', 'stage_file_proxy', diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/composer.json index 78eb61dd8e..16a6bcffdf 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/composer.json @@ -1,4 +1,4 @@ -@@ -26,7 +26,6 @@ +@@ -27,7 +27,6 @@ "drupal/redis": "__VERSION__", "drupal/reroute_email": "__VERSION__", "drupal/robotstxt": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/tests/phpunit/Drupal/EnvironmentSettingsTest.php new file mode 100644 index 0000000000..b3c5b1a6fa --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -0,0 +1,40 @@ +@@ -101,7 +101,6 @@ + 'devel', + 'generated_content', + 'reroute_email', +- 'sdc_devel', + 'testmode', + ]; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; +@@ -201,7 +200,6 @@ + 'devel', + 'generated_content', + 'reroute_email', +- 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = 'custom_config'; +@@ -275,7 +273,6 @@ + 'devel', + 'generated_content', + 'reroute_email', +- 'sdc_devel', + 'testmode', + ]; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; +@@ -349,7 +346,6 @@ + 'devel', + 'generated_content', + 'reroute_email', +- 'sdc_devel', + 'testmode', + ]; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; +@@ -425,7 +421,6 @@ + 'devel', + 'generated_content', + 'reroute_email', +- 'sdc_devel', + 'testmode', + ]; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 990c04a4a9..bb853a4411 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,4 +1,4 @@ -@@ -100,8 +100,6 @@ +@@ -99,8 +99,6 @@ $this->moduleInstaller->install(['search_api', 'search_api_solr']); @@ -6,4 +6,4 @@ - $this->moduleInstaller->install(['devel']); - $this->moduleInstaller->install(['sw_search']); + $this->moduleInstaller->install(['reroute_email']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/web/sites/default/includes/modules/-settings.sdc_devel.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_sdc_devel/web/sites/default/includes/modules/-settings.sdc_devel.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit/composer.json index c287a767a7..13f5411494 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit/composer.json @@ -1,4 +1,4 @@ -@@ -29,7 +29,6 @@ +@@ -30,7 +30,6 @@ "drupal/sdc_devel": "__VERSION__", "drupal/search_api": "__VERSION__", "drupal/search_api_solr": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 8ee865058a..a5c22fdd7c 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -236,8 +236,6 @@ +@@ -264,8 +264,6 @@ $config['reroute_email.settings']['enable'] = FALSE; $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; @@ -7,7 +7,7 @@ $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; $this->assertConfig($config); -@@ -296,8 +294,6 @@ +@@ -338,8 +336,6 @@ $config['reroute_email.settings']['enable'] = FALSE; $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; @@ -16,7 +16,7 @@ $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; $this->assertConfig($config); -@@ -358,8 +354,6 @@ +@@ -414,8 +410,6 @@ $config['reroute_email.settings']['enable'] = FALSE; $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/composer.json index 7ead686ee5..c69a54aa37 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/composer.json @@ -1,4 +1,4 @@ -@@ -29,9 +29,6 @@ +@@ -30,9 +30,6 @@ "drupal/sdc_devel": "__VERSION__", "drupal/search_api": "__VERSION__", "drupal/search_api_solr": "__VERSION__", @@ -7,4 +7,4 @@ - "drupal/stage_file_proxy": "__VERSION__", "drupal/testmode": "__VERSION__", "drupal/xmlsitemap": "__VERSION__", - "drush/drush": "__VERSION__", + "drush/drush": "__VERSION__" diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 82ec15bfee..a29d23d067 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -6,7 +6,7 @@ $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['reroute_email.settings']['enable'] = TRUE; -@@ -170,7 +169,6 @@ +@@ -184,7 +183,6 @@ $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; @@ -14,7 +14,7 @@ $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['reroute_email.settings']['enable'] = TRUE; -@@ -228,7 +226,6 @@ +@@ -256,7 +254,6 @@ $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; @@ -22,7 +22,7 @@ $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['system.logging']['error_level'] = 'all'; -@@ -236,8 +233,6 @@ +@@ -264,8 +261,6 @@ $config['reroute_email.settings']['enable'] = FALSE; $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; @@ -31,7 +31,7 @@ $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; $this->assertConfig($config); -@@ -288,7 +283,6 @@ +@@ -330,7 +325,6 @@ $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; @@ -39,7 +39,7 @@ $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['system.logging']['error_level'] = 'all'; -@@ -296,8 +290,6 @@ +@@ -338,8 +332,6 @@ $config['reroute_email.settings']['enable'] = FALSE; $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; @@ -48,7 +48,7 @@ $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; $this->assertConfig($config); -@@ -349,7 +341,6 @@ +@@ -405,7 +397,6 @@ $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; @@ -56,7 +56,7 @@ $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['system.logging']['error_level'] = 'all'; -@@ -358,8 +349,6 @@ +@@ -414,8 +405,6 @@ $config['reroute_email.settings']['enable'] = FALSE; $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/tests/phpunit/Drupal/SwitchableSettingsTest.php index f1b25872ed..45865a85fa 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,4 +1,4 @@ -@@ -326,375 +326,6 @@ +@@ -478,405 +478,6 @@ } /** @@ -186,7 +186,7 @@ - 'DRUPAL_SHIELD_DISABLED' => 'false', - ], - [ -- 'shield.settings' => ['shield_enable' => FALSE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], +- 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], - ], - ]; - yield [ @@ -198,7 +198,19 @@ - 'DRUPAL_SHIELD_DISABLED' => 'true', - ], - [ -- 'shield.settings' => ['shield_enable' => FALSE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], +- 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], +- ], +- ]; +- yield [ +- self::ENVIRONMENT_DEV, +- [ +- 'DRUPAL_SHIELD_USER' => 'drupal_shield_user', +- 'DRUPAL_SHIELD_PASS' => 'drupal_shield_pass', +- 'DRUPAL_SHIELD_PRINT' => 'drupal_shield_print', +- 'DRUPAL_SHIELD_DISABLED' => '01', +- ], +- [ +- 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], - ], - ]; - @@ -313,6 +325,24 @@ - 'shield.settings' => ['method' => NULL, 'paths' => NULL], - ], - ]; +- // ACME challenge with a non-numeric truthy value - should not set. +- yield [ +- self::ENVIRONMENT_DEV, +- [ +- 'DRUPAL_SHIELD_USER' => 'drupal_shield_user', +- 'DRUPAL_SHIELD_PASS' => 'drupal_shield_pass', +- 'DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE' => 'true', +- ], +- [ +- 'shield.settings' => [ +- 'shield_enable' => TRUE, +- 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], +- ], +- ], +- [ +- 'shield.settings' => ['method' => NULL, 'paths' => NULL], +- ], +- ]; - - yield [ - self::ENVIRONMENT_DEV, @@ -374,9 +404,9 @@ * Test Reroute Email config. */ #[DataProvider('dataProviderRerouteEmail')] -@@ -830,131 +461,6 @@ +@@ -1035,131 +636,6 @@ [ - 'reroute_email.settings' => ['enable' => FALSE], + 'reroute_email.settings' => ['enable' => TRUE], ], - ]; - } diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 68c4a99523..fb98d0c17f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_seckit_shield_stage_file_proxy/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,6 +1,6 @@ -@@ -88,8 +88,6 @@ +@@ -87,8 +87,6 @@ + 'pathauto', 'redirect', - 'reroute_email', 'robotstxt', - 'shield', - 'stage_file_proxy', diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/composer.json index 4e15c8e9dc..63a3d38120 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/composer.json @@ -1,4 +1,4 @@ -@@ -30,7 +30,6 @@ +@@ -31,7 +31,6 @@ "drupal/search_api": "__VERSION__", "drupal/search_api_solr": "__VERSION__", "drupal/seckit": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/tests/phpunit/Drupal/EnvironmentSettingsTest.php index f508e1214b..854bcef229 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -6,7 +6,7 @@ $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['reroute_email.settings']['enable'] = TRUE; -@@ -170,7 +169,6 @@ +@@ -184,7 +183,6 @@ $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; @@ -14,7 +14,7 @@ $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['reroute_email.settings']['enable'] = TRUE; -@@ -228,7 +226,6 @@ +@@ -256,7 +254,6 @@ $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; @@ -22,7 +22,7 @@ $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['system.logging']['error_level'] = 'all'; -@@ -288,7 +285,6 @@ +@@ -330,7 +327,6 @@ $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; @@ -30,7 +30,7 @@ $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['system.logging']['error_level'] = 'all'; -@@ -349,7 +345,6 @@ +@@ -405,7 +401,6 @@ $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/tests/phpunit/Drupal/SwitchableSettingsTest.php index 5f6d83832b..2f4127f8fd 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,4 +1,4 @@ -@@ -326,375 +326,6 @@ +@@ -478,405 +478,6 @@ } /** @@ -186,7 +186,7 @@ - 'DRUPAL_SHIELD_DISABLED' => 'false', - ], - [ -- 'shield.settings' => ['shield_enable' => FALSE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], +- 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], - ], - ]; - yield [ @@ -198,7 +198,19 @@ - 'DRUPAL_SHIELD_DISABLED' => 'true', - ], - [ -- 'shield.settings' => ['shield_enable' => FALSE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], +- 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], +- ], +- ]; +- yield [ +- self::ENVIRONMENT_DEV, +- [ +- 'DRUPAL_SHIELD_USER' => 'drupal_shield_user', +- 'DRUPAL_SHIELD_PASS' => 'drupal_shield_pass', +- 'DRUPAL_SHIELD_PRINT' => 'drupal_shield_print', +- 'DRUPAL_SHIELD_DISABLED' => '01', +- ], +- [ +- 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], - ], - ]; - @@ -313,6 +325,24 @@ - 'shield.settings' => ['method' => NULL, 'paths' => NULL], - ], - ]; +- // ACME challenge with a non-numeric truthy value - should not set. +- yield [ +- self::ENVIRONMENT_DEV, +- [ +- 'DRUPAL_SHIELD_USER' => 'drupal_shield_user', +- 'DRUPAL_SHIELD_PASS' => 'drupal_shield_pass', +- 'DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE' => 'true', +- ], +- [ +- 'shield.settings' => [ +- 'shield_enable' => TRUE, +- 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], +- ], +- ], +- [ +- 'shield.settings' => ['method' => NULL, 'paths' => NULL], +- ], +- ]; - - yield [ - self::ENVIRONMENT_DEV, diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index eea8be563f..3ba226d837 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_shield/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,6 +1,6 @@ -@@ -88,7 +88,6 @@ +@@ -87,7 +87,6 @@ + 'pathauto', 'redirect', - 'reroute_email', 'robotstxt', - 'shield', 'stage_file_proxy', diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_stage_file_proxy/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_stage_file_proxy/composer.json index 279a00c573..736259e05d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_stage_file_proxy/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_stage_file_proxy/composer.json @@ -1,8 +1,8 @@ -@@ -31,7 +31,6 @@ +@@ -32,7 +32,6 @@ "drupal/search_api_solr": "__VERSION__", "drupal/seckit": "__VERSION__", "drupal/shield": "__VERSION__", - "drupal/stage_file_proxy": "__VERSION__", "drupal/testmode": "__VERSION__", "drupal/xmlsitemap": "__VERSION__", - "drush/drush": "__VERSION__", + "drush/drush": "__VERSION__" diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_stage_file_proxy/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_stage_file_proxy/tests/phpunit/Drupal/SwitchableSettingsTest.php index cc5de867f3..3aa7e2d05d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_stage_file_proxy/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_stage_file_proxy/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,4 +1,4 @@ -@@ -834,131 +834,6 @@ +@@ -1039,131 +1039,6 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_stage_file_proxy/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_stage_file_proxy/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index dd60b851db..31f349ebeb 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_stage_file_proxy/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_stage_file_proxy/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,5 +1,5 @@ -@@ -89,7 +89,6 @@ - 'reroute_email', +@@ -88,7 +88,6 @@ + 'redirect', 'robotstxt', 'shield', - 'stage_file_proxy', diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_testmode/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_testmode/composer.json index d90f9e1a95..7c5d808b0b 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_testmode/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_testmode/composer.json @@ -1,8 +1,8 @@ -@@ -32,7 +32,6 @@ +@@ -33,7 +33,6 @@ "drupal/seckit": "__VERSION__", "drupal/shield": "__VERSION__", "drupal/stage_file_proxy": "__VERSION__", - "drupal/testmode": "__VERSION__", "drupal/xmlsitemap": "__VERSION__", - "drush/drush": "__VERSION__", - "webflo/drupal-finder": "__VERSION__" + "drush/drush": "__VERSION__" + }, diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_testmode/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_testmode/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 158b74c80f..be7d40931f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_testmode/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_testmode/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,39 +1,39 @@ -@@ -100,7 +100,6 @@ - $settings['config_exclude_modules'] = [ - 'devel', +@@ -102,7 +102,6 @@ 'generated_content', + 'reroute_email', + 'sdc_devel', - 'testmode', ]; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; -@@ -186,7 +185,6 @@ - $settings['config_exclude_modules'] = [ - 'devel', +@@ -202,7 +201,6 @@ 'generated_content', + 'reroute_email', + 'sdc_devel', - 'testmode', ]; $settings['config_sync_directory'] = 'custom_config'; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; -@@ -246,7 +244,6 @@ - $settings['config_exclude_modules'] = [ - 'devel', +@@ -276,7 +274,6 @@ 'generated_content', + 'reroute_email', + 'sdc_devel', - 'testmode', ]; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; -@@ -306,7 +303,6 @@ - $settings['config_exclude_modules'] = [ - 'devel', +@@ -350,7 +347,6 @@ 'generated_content', + 'reroute_email', + 'sdc_devel', - 'testmode', ]; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; -@@ -368,7 +364,6 @@ - $settings['config_exclude_modules'] = [ - 'devel', +@@ -426,7 +422,6 @@ 'generated_content', + 'reroute_email', + 'sdc_devel', - 'testmode', ]; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_xmlsitemap/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_no_xmlsitemap/composer.json index 033a8e45d8..cd9b06dfd5 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_xmlsitemap/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_xmlsitemap/composer.json @@ -1,8 +1,8 @@ -@@ -33,7 +33,6 @@ +@@ -34,7 +34,6 @@ "drupal/shield": "__VERSION__", "drupal/stage_file_proxy": "__VERSION__", "drupal/testmode": "__VERSION__", - "drupal/xmlsitemap": "__VERSION__", - "drush/drush": "__VERSION__", - "webflo/drupal-finder": "__VERSION__" + "drush/drush": "__VERSION__" }, + "require-dev": { diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_xmlsitemap/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_xmlsitemap/tests/phpunit/Drupal/EnvironmentSettingsTest.php index dd5da03733..1f94be5838 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_xmlsitemap/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_xmlsitemap/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -6,7 +6,7 @@ $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['reroute_email.settings']['enable'] = TRUE; $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; -@@ -171,7 +170,6 @@ +@@ -185,7 +184,6 @@ $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; $config['shield.settings']['shield_enable'] = TRUE; @@ -14,7 +14,7 @@ $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['reroute_email.settings']['enable'] = TRUE; $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; -@@ -229,7 +227,6 @@ +@@ -257,7 +255,6 @@ $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; $config['shield.settings']['shield_enable'] = FALSE; @@ -22,7 +22,7 @@ $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['system.logging']['error_level'] = 'all'; $config['system.performance']['cache']['page']['max_age'] = 900; -@@ -289,7 +286,6 @@ +@@ -331,7 +328,6 @@ $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; $config['shield.settings']['shield_enable'] = FALSE; @@ -30,7 +30,7 @@ $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['system.logging']['error_level'] = 'all'; $config['system.performance']['cache']['page']['max_age'] = 900; -@@ -350,7 +346,6 @@ +@@ -406,7 +402,6 @@ $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; $config['shield.settings']['shield_enable'] = FALSE; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_no_xmlsitemap/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_no_xmlsitemap/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index d5033407f0..ea805a962b 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_no_xmlsitemap/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_no_xmlsitemap/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,4 +1,4 @@ -@@ -90,7 +90,6 @@ +@@ -89,7 +89,6 @@ 'robotstxt', 'shield', 'stage_file_proxy', diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_none/composer.json b/.vortex/cli/tests/Fixtures/handler_process/modules_none/composer.json index c57d0a10ad..c34e6bd843 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_none/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_none/composer.json @@ -1,4 +1,4 @@ -@@ -10,30 +10,12 @@ +@@ -10,31 +10,12 @@ "drevops/environment-detector": "__VERSION__", "drevops/vortex-tooling": "__VERSION__", "drupal/clamav": "__VERSION__", @@ -11,6 +11,7 @@ - "drupal/devel": "__VERSION__", - "drupal/drupal_helpers": "__VERSION__", - "drupal/environment_indicator": "__VERSION__", +- "drupal/fast_404": "__VERSION__", - "drupal/generated_content": "__VERSION__", - "drupal/navigation_extra_tools": "__VERSION__", - "drupal/pathauto": "__VERSION__", @@ -26,6 +27,6 @@ - "drupal/stage_file_proxy": "__VERSION__", - "drupal/testmode": "__VERSION__", - "drupal/xmlsitemap": "__VERSION__", - "drush/drush": "__VERSION__", - "webflo/drupal-finder": "__VERSION__" + "drush/drush": "__VERSION__" }, + "require-dev": { diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_none/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_none/tests/phpunit/Drupal/EnvironmentSettingsTest.php index b8c9cdafaf..3ea01956f8 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_none/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_none/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -17,17 +17,35 @@ $config['system.performance']['cache']['page']['max_age'] = 900; $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; -@@ -98,9 +87,6 @@ +@@ -98,27 +87,10 @@ $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ - 'devel', - 'generated_content', +- 'reroute_email', +- 'sdc_devel', - 'testmode', ]; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; -@@ -164,18 +150,7 @@ + $settings['environment'] = self::ENVIRONMENT_SUT; +- $settings['fast404_allow_anon_imagecache'] = TRUE; +- $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +- $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; +- $settings['fast404_path_check'] = FALSE; +- $settings['fast404_respect_redirect'] = FALSE; +- $settings['fast404_url_whitelisting'] = TRUE; +- $settings['fast404_whitelist'] = [ +- 'index.php', +- 'rss.xml', +- 'cron.php', +- 'xmlrpc.php', +- ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; +@@ -178,18 +150,7 @@ $this->assertEquals($databases, $this->databases); // Verify key config overrides. @@ -46,17 +64,36 @@ $config['system.performance']['cache']['page']['max_age'] = 1800; $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; -@@ -184,9 +159,6 @@ +@@ -198,28 +159,11 @@ // Verify settings overrides. $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ - 'devel', - 'generated_content', +- 'reroute_email', +- 'sdc_devel', - 'testmode', ]; $settings['config_sync_directory'] = 'custom_config'; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; -@@ -221,23 +193,9 @@ + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_SUT; +- $settings['fast404_allow_anon_imagecache'] = TRUE; +- $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +- $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; +- $settings['fast404_path_check'] = FALSE; +- $settings['fast404_respect_redirect'] = FALSE; +- $settings['fast404_url_whitelisting'] = TRUE; +- $settings['fast404_whitelist'] = [ +- 'index.php', +- 'rss.xml', +- 'cron.php', +- 'xmlrpc.php', +- ]; + $settings['file_public_path'] = 'custom_public'; + $settings['file_private_path'] = 'custom_private'; + $settings['file_temp_path'] = 'custom_temp'; +@@ -249,23 +193,9 @@ $this->requireSettingsFile(); $config['automated_cron.settings']['interval'] = 0; @@ -80,17 +117,35 @@ $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; $this->assertConfig($config); -@@ -244,9 +202,6 @@ +@@ -272,27 +202,10 @@ $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ - 'devel', - 'generated_content', +- 'reroute_email', +- 'sdc_devel', - 'testmode', ]; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; -@@ -281,23 +236,9 @@ + $settings['environment'] = self::ENVIRONMENT_LOCAL; +- $settings['fast404_allow_anon_imagecache'] = TRUE; +- $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +- $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; +- $settings['fast404_path_check'] = FALSE; +- $settings['fast404_respect_redirect'] = FALSE; +- $settings['fast404_url_whitelisting'] = TRUE; +- $settings['fast404_whitelist'] = [ +- 'index.php', +- 'rss.xml', +- 'cron.php', +- 'xmlrpc.php', +- ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; +@@ -323,23 +236,9 @@ $this->requireSettingsFile(); $config['automated_cron.settings']['interval'] = 0; @@ -114,17 +169,35 @@ $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; $this->assertConfig($config); -@@ -304,9 +245,6 @@ +@@ -346,27 +245,10 @@ $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ - 'devel', - 'generated_content', +- 'reroute_email', +- 'sdc_devel', - 'testmode', ]; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; -@@ -342,24 +280,10 @@ + $settings['environment'] = self::ENVIRONMENT_LOCAL; +- $settings['fast404_allow_anon_imagecache'] = TRUE; +- $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +- $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; +- $settings['fast404_path_check'] = FALSE; +- $settings['fast404_respect_redirect'] = FALSE; +- $settings['fast404_url_whitelisting'] = TRUE; +- $settings['fast404_whitelist'] = [ +- 'index.php', +- 'rss.xml', +- 'cron.php', +- 'xmlrpc.php', +- ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; +@@ -398,24 +280,10 @@ $this->requireSettingsFile(); $config['automated_cron.settings']['interval'] = 0; @@ -149,13 +222,31 @@ $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; $this->assertConfig($config); -@@ -366,9 +290,6 @@ +@@ -422,27 +290,10 @@ $settings['auto_create_htaccess'] = FALSE; $settings['config_exclude_modules'] = [ - 'devel', - 'generated_content', +- 'reroute_email', +- 'sdc_devel', - 'testmode', ]; $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_CI; +- $settings['fast404_allow_anon_imagecache'] = TRUE; +- $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +- $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; +- $settings['fast404_path_check'] = FALSE; +- $settings['fast404_respect_redirect'] = FALSE; +- $settings['fast404_url_whitelisting'] = TRUE; +- $settings['fast404_whitelist'] = [ +- 'index.php', +- 'rss.xml', +- 'cron.php', +- 'xmlrpc.php', +- ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_none/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/modules_none/tests/phpunit/Drupal/SwitchableSettingsTest.php index 342f4211d1..d03764a83e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_none/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_none/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,4 +1,36 @@ -@@ -76,154 +76,6 @@ +@@ -4,8 +4,6 @@ + + namespace Drupal; + +-use PHPUnit\Framework\Attributes\PreserveGlobalState; +-use PHPUnit\Framework\Attributes\RunInSeparateProcess; + use PHPUnit\Framework\Attributes\DataProvider; + use PHPUnit\Framework\Attributes\Group; + +@@ -22,22 +20,6 @@ + class SwitchableSettingsTest extends SettingsTestCase { + + /** +- * Path to the contrib modules directory fixture. +- */ +- protected ?string $contribFixture = NULL; +- +- /** +- * {@inheritdoc} +- */ +- protected function tearDown(): void { +- if (!is_null($this->contribFixture)) { +- $this->removeContribFixture($this->contribFixture); +- } +- +- parent::tearDown(); +- } +- +- /** + * Test ClamAV config. + */ + #[DataProvider('dataProviderClamav')] +@@ -119,257 +101,6 @@ } /** @@ -149,11 +181,114 @@ - ]; - } - +- /** +- * Test Fast 404 settings. +- * +- * Runs isolated so that the module stub owns the 'fast404_preboot()' +- * declaration and its invocation marker is conclusive. +- */ +- #[DataProvider('dataProviderFast404')] +- #[RunInSeparateProcess] +- #[PreserveGlobalState(FALSE)] +- public function testFast404(bool $module_installed, array $expected_present, array $expected_absent = []): void { +- $contrib_path = $this->createContribFixture($module_installed); +- +- $this->requireModuleSettingsFile('fast_404', $contrib_path); +- +- $this->assertSettingsContains($expected_present); +- $this->assertSettingsNotContains($expected_absent); +- $this->assertSame($module_installed, file_exists($contrib_path . '/fast_404/preboot'), 'Preboot invocation'); +- } +- +- /** +- * Data provider for testFast404(). +- */ +- public static function dataProviderFast404(): \Iterator { +- yield 'module installed' => [ +- TRUE, +- [ +- 'fast404_exts' => '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i', +- 'fast404_allow_anon_imagecache' => TRUE, +- 'fast404_url_whitelisting' => TRUE, +- 'fast404_whitelist' => ['index.php', 'rss.xml', 'cron.php', 'xmlrpc.php'], +- 'fast404_path_check' => FALSE, +- 'fast404_respect_redirect' => FALSE, +- 'fast404_html' => '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

', +- ], +- ]; +- yield 'module not installed' => [ +- FALSE, +- [], +- [ +- 'fast404_exts' => NULL, +- 'fast404_allow_anon_imagecache' => NULL, +- 'fast404_url_whitelisting' => NULL, +- 'fast404_whitelist' => NULL, +- 'fast404_path_check' => NULL, +- 'fast404_respect_redirect' => NULL, +- 'fast404_html' => NULL, +- ], +- ]; +- } +- +- /** +- * Create a contrib modules directory fixture. +- * +- * The Fast 404 module is not required by the project, so its settings file +- * guard can only be satisfied by a stub. +- * +- * @param bool $with_fast404 +- * Create a stub of the Fast 404 module within the fixture. The stub marks +- * the directory when its preboot function is called. +- * +- * @return string +- * Path to the contrib modules directory fixture. +- */ +- protected function createContribFixture(bool $with_fast404): string { +- $this->contribFixture = getcwd() . '/.artifacts/tmp/' . uniqid('contrib-'); +- +- mkdir($this->contribFixture, 0777, TRUE); +- +- if ($with_fast404) { +- $stub = <<<'PHP' +- contribFixture . '/fast_404'); +- file_put_contents($this->contribFixture . '/fast_404/fast404.inc', $stub); +- } +- +- return $this->contribFixture; +- } +- +- /** +- * Remove the contrib modules directory fixture. +- * +- * @param string $path +- * Path to the contrib modules directory fixture. +- */ +- protected function removeContribFixture(string $path): void { +- foreach (glob($path . '/*/*') ?: [] as $file) { +- unlink($file); +- } +- +- foreach (glob($path . '/*', GLOB_ONLYDIR) ?: [] as $dir) { +- rmdir($dir); +- } +- +- rmdir($path); +- } +- - /** * Test Redis settings. */ - public function testRedis(): void { -@@ -323,639 +175,6 @@ + #[DataProvider('dataProviderRedis')] +@@ -475,692 +206,6 @@ $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 9999; $this->assertConfigContains($config); @@ -344,7 +479,7 @@ public function testRedis(): void { - 'DRUPAL_SHIELD_DISABLED' => 'false', - ], - [ -- 'shield.settings' => ['shield_enable' => FALSE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], +- 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], - ], - ]; - yield [ @@ -356,7 +491,19 @@ public function testRedis(): void { - 'DRUPAL_SHIELD_DISABLED' => 'true', - ], - [ -- 'shield.settings' => ['shield_enable' => FALSE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], +- 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], +- ], +- ]; +- yield [ +- self::ENVIRONMENT_DEV, +- [ +- 'DRUPAL_SHIELD_USER' => 'drupal_shield_user', +- 'DRUPAL_SHIELD_PASS' => 'drupal_shield_pass', +- 'DRUPAL_SHIELD_PRINT' => 'drupal_shield_print', +- 'DRUPAL_SHIELD_DISABLED' => '01', +- ], +- [ +- 'shield.settings' => ['shield_enable' => TRUE, 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], 'print' => 'drupal_shield_print'], - ], - ]; - @@ -471,6 +618,24 @@ public function testRedis(): void { - 'shield.settings' => ['method' => NULL, 'paths' => NULL], - ], - ]; +- // ACME challenge with a non-numeric truthy value - should not set. +- yield [ +- self::ENVIRONMENT_DEV, +- [ +- 'DRUPAL_SHIELD_USER' => 'drupal_shield_user', +- 'DRUPAL_SHIELD_PASS' => 'drupal_shield_pass', +- 'DRUPAL_SHIELD_ALLOW_ACME_CHALLENGE' => 'true', +- ], +- [ +- 'shield.settings' => [ +- 'shield_enable' => TRUE, +- 'credentials' => ['shield' => ['user' => 'drupal_shield_user', 'pass' => 'drupal_shield_pass']], +- ], +- ], +- [ +- 'shield.settings' => ['method' => NULL, 'paths' => NULL], +- ], +- ]; - - yield [ - self::ENVIRONMENT_DEV, @@ -581,12 +746,12 @@ public function testRedis(): void { - ], - ]; - -- // Stage: disabled by default. +- // Stage: enabled by default. - yield [ - self::ENVIRONMENT_STAGE, - [], - [ -- 'reroute_email.settings' => ['enable' => FALSE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'], +- 'reroute_email.settings' => ['enable' => TRUE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'], - ], - ]; - @@ -621,6 +786,17 @@ public function testRedis(): void { - ], - ]; - +- // Stage with DRUPAL_REROUTE_EMAIL_DISABLED: forced off. +- yield [ +- self::ENVIRONMENT_STAGE, +- [ +- 'DRUPAL_REROUTE_EMAIL_DISABLED' => 1, +- ], +- [ +- 'reroute_email.settings' => ['enable' => FALSE], +- ], +- ]; +- - // Custom address and allowed list. - yield [ - self::ENVIRONMENT_DEV, @@ -665,6 +841,18 @@ public function testRedis(): void { - 'reroute_email.settings' => ['enable' => FALSE], - ], - ]; +- +- // DRUPAL_REROUTE_EMAIL_DISABLED with a non-numeric truthy value: not +- // disabled. +- yield [ +- self::ENVIRONMENT_DEV, +- [ +- 'DRUPAL_REROUTE_EMAIL_DISABLED' => 'true', +- ], +- [ +- 'reroute_email.settings' => ['enable' => TRUE], +- ], +- ]; - } - - /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_none/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/modules_none/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index a82d5f89bf..58786f9090 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/modules_none/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/modules_none/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,4 +1,4 @@ -@@ -77,22 +77,6 @@ +@@ -77,21 +77,6 @@ $this->moduleInstaller->uninstall(['toolbar']); } @@ -11,7 +11,6 @@ - 'navigation_extra_tools', - 'pathauto', - 'redirect', -- 'reroute_email', - 'robotstxt', - 'shield', - 'stage_file_proxy', @@ -21,13 +20,15 @@ $this->moduleInstaller->install(['redis']); $this->moduleInstaller->install(['clamav']); -@@ -100,23 +84,10 @@ +@@ -99,25 +84,10 @@ $this->moduleInstaller->install(['search_api', 'search_api_solr']); - $this->moduleInstaller->install(['sdc_devel']); - - $this->moduleInstaller->install(['devel']); +- +- $this->moduleInstaller->install(['reroute_email']); - $this->moduleInstaller->install(['sw_search']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_none/web/sites/default/includes/modules/-settings.fast_404.php b/.vortex/cli/tests/Fixtures/handler_process/modules_none/web/sites/default/includes/modules/-settings.fast_404.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.vortex/cli/tests/Fixtures/handler_process/modules_none/web/sites/default/includes/modules/-settings.sdc_devel.php b/.vortex/cli/tests/Fixtures/handler_process/modules_none/web/sites/default/includes/modules/-settings.sdc_devel.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.vortex/cli/tests/Fixtures/handler_process/names/.env b/.vortex/cli/tests/Fixtures/handler_process/names/.env index f1e9a7ed28..dfccef7e9d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/names/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/names/.env @@ -33,7 +33,7 @@ # Shield message. DRUPAL_SHIELD_PRINT="Restricted access." -@@ -136,7 +136,7 @@ +@@ -142,7 +142,7 @@ # # Applied if database sanitization is enabled. # @see https://www.vortextemplate.com/docs/development/provision#database-sanitization @@ -42,7 +42,7 @@ # Put the site into a maintenance mode during site provisioning. VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 -@@ -204,7 +204,7 @@ +@@ -210,7 +210,7 @@ # An email address to send notifications from. # # Applies to email notifications. @@ -51,7 +51,7 @@ # Email address(es) to send notifications to. # -@@ -213,7 +213,7 @@ +@@ -219,7 +219,7 @@ # Multiple names can be specified as a comma-separated list of email addresses # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" diff --git a/.vortex/cli/tests/Fixtures/handler_process/names/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/names/tests/phpunit/Drupal/EnvironmentSettingsTest.php index b156e8c13f..9abe80eb73 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/names/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/names/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -9,7 +9,7 @@ $config['system.performance']['cache']['page']['max_age'] = 900; $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; -@@ -174,8 +174,8 @@ +@@ -188,8 +188,8 @@ $config['xmlsitemap.settings']['disable_cron_regeneration'] = TRUE; $config['xmlsitemap_engines.settings']['submit'] = FALSE; $config['reroute_email.settings']['enable'] = TRUE; @@ -20,7 +20,7 @@ $config['system.performance']['cache']['page']['max_age'] = 1800; $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; $config['search_api.server.solr']['backend_config']['connector_config']['port'] = 8983; -@@ -234,8 +234,8 @@ +@@ -262,8 +262,8 @@ $config['system.logging']['error_level'] = 'all'; $config['system.performance']['cache']['page']['max_age'] = 900; $config['reroute_email.settings']['enable'] = FALSE; @@ -31,7 +31,7 @@ $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; -@@ -294,8 +294,8 @@ +@@ -336,8 +336,8 @@ $config['system.logging']['error_level'] = 'all'; $config['system.performance']['cache']['page']['max_age'] = 900; $config['reroute_email.settings']['enable'] = FALSE; @@ -42,7 +42,7 @@ $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; $config['search_api.server.solr']['backend_config']['connector_config']['host'] = 'search'; -@@ -356,8 +356,8 @@ +@@ -412,8 +412,8 @@ $config['system.mail']['interface']['default'] = 'test_mail_collector'; $config['system.performance']['cache']['page']['max_age'] = 900; $config['reroute_email.settings']['enable'] = FALSE; diff --git a/.vortex/cli/tests/Fixtures/handler_process/names/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/names/tests/phpunit/Drupal/SwitchableSettingsTest.php index 5379cad7cd..91b111e79a 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/names/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/names/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,4 +1,4 @@ -@@ -716,7 +716,7 @@ +@@ -898,7 +898,7 @@ self::ENVIRONMENT_LOCAL, [], [ @@ -7,7 +7,7 @@ ], ]; -@@ -725,7 +725,7 @@ +@@ -907,7 +907,7 @@ self::ENVIRONMENT_CI, [], [ @@ -16,7 +16,7 @@ ], ]; -@@ -734,7 +734,7 @@ +@@ -916,7 +916,7 @@ self::ENVIRONMENT_DEV, [], [ @@ -25,7 +25,7 @@ ], ]; -@@ -743,7 +743,7 @@ +@@ -925,7 +925,7 @@ self::ENVIRONMENT_SUT, [], [ @@ -34,16 +34,16 @@ ], ]; -@@ -752,7 +752,7 @@ +@@ -934,7 +934,7 @@ self::ENVIRONMENT_STAGE, [], [ -- 'reroute_email.settings' => ['enable' => FALSE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'], -+ 'reroute_email.settings' => ['enable' => FALSE, 'address' => 'webmaster@death-star.com', 'allowed' => '*@death-star.com'], +- 'reroute_email.settings' => ['enable' => TRUE, 'address' => 'webmaster@star-wars.com', 'allowed' => '*@star-wars.com'], ++ 'reroute_email.settings' => ['enable' => TRUE, 'address' => 'webmaster@death-star.com', 'allowed' => '*@death-star.com'], ], ]; -@@ -761,7 +761,7 @@ +@@ -943,7 +943,7 @@ self::ENVIRONMENT_PROD, [], [ diff --git a/.vortex/cli/tests/Fixtures/handler_process/names/web/modules/custom/the_force_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/names/web/modules/custom/the_force_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 055a1e2592..163c4fdb81 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/names/web/modules/custom/the_force_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/names/web/modules/custom/the_force_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -86,7 +86,6 @@ public function run(): void { 'navigation_extra_tools', 'pathauto', 'redirect', - 'reroute_email', 'robotstxt', 'shield', 'stage_file_proxy', @@ -104,6 +103,8 @@ public function run(): void { $this->moduleInstaller->install(['devel']); + $this->moduleInstaller->install(['reroute_email']); + $this->moduleInstaller->install(['the_force_search']); $this->moduleInstaller->install(['the_force_demo']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/names/web/sites/default/includes/modules/settings.reroute_email.php b/.vortex/cli/tests/Fixtures/handler_process/names/web/sites/default/includes/modules/settings.reroute_email.php index 08a51a95ca..92bbb96cbd 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/names/web/sites/default/includes/modules/settings.reroute_email.php +++ b/.vortex/cli/tests/Fixtures/handler_process/names/web/sites/default/includes/modules/settings.reroute_email.php @@ -1,5 +1,5 @@ -@@ -10,8 +10,8 @@ - use DrevOps\EnvironmentDetector\Environment; +@@ -12,8 +12,8 @@ + $settings['config_exclude_modules'][] = 'reroute_email'; // Default reroute email address and allowed list. -$config['reroute_email.settings']['address'] = getenv('DRUPAL_REROUTE_EMAIL_ADDRESS') ?: 'webmaster@star-wars.com'; @@ -7,5 +7,5 @@ +$config['reroute_email.settings']['address'] = getenv('DRUPAL_REROUTE_EMAIL_ADDRESS') ?: 'webmaster@death-star.com'; +$config['reroute_email.settings']['allowed'] = getenv('DRUPAL_REROUTE_EMAIL_ALLOWED') ?: '*@death-star.com'; - // Enable rerouting in all environments except local, ci, stage and prod. - // This covers dev and any custom environments (e.g., PR environments). + if (in_array($settings['environment'], [ + Environment::LOCAL, diff --git a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/composer.json b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/composer.json index c259827343..920bb69660 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/composer.json @@ -7,7 +7,7 @@ "license": "proprietary", "type": "project", "require": { -@@ -23,7 +23,6 @@ +@@ -24,7 +24,6 @@ "drupal/navigation_extra_tools": "__VERSION__", "drupal/pathauto": "__VERSION__", "drupal/redirect": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/docker-compose.yml index 9b37b1cb0e..757d8b7587 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/docker-compose.yml @@ -7,7 +7,7 @@ # The default user under which the containers should run. x-user: &default-user -@@ -154,9 +152,6 @@ +@@ -155,9 +153,6 @@ ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -17,7 +17,7 @@ search: build: context: . -@@ -197,12 +192,10 @@ +@@ -198,12 +193,10 @@ depends_on: - antivirus - database diff --git a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/tests/phpunit/Drupal/SwitchableSettingsTest.php index c4572cfd53..575be64ae1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,77 +1,83 @@ -@@ -224,79 +224,6 @@ +@@ -370,85 +370,6 @@ } /** - * Test Redis settings. - */ -- public function testRedis(): void { -- $this->setEnvVars([ -- 'DRUPAL_REDIS_ENABLED' => 1, -- 'REDIS_HOST' => 'redis_host', -- 'REDIS_SERVICE_PORT' => 1234, -- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, -- ]); +- #[DataProvider('dataProviderRedis')] +- public function testRedis(array $vars, bool $expected_enabled, array $expected_settings): void { +- $this->setEnvVars($vars); - - $this->requireSettingsFile(); - -- $settings['redis.connection']['interface'] = 'PhpRedis'; -- $settings['redis.connection']['host'] = 'redis_host'; -- $settings['redis.connection']['port'] = 1234; -- $settings['cache']['default'] = 'cache.backend.redis'; -- -- $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); +- $this->assertSame($expected_enabled, array_key_exists('bootstrap_container_definition', $this->settings), 'Bootstrap container definition'); - unset($this->settings['bootstrap_container_definition']); - -- $this->assertSettingsContains($settings); -- } -- -- /** -- * Test Redis settings with REDIS_* environment variables. -- */ -- public function testRedisVariables(): void { -- $this->setEnvVars([ -- 'DRUPAL_REDIS_ENABLED' => 1, -- 'REDIS_HOST' => 'redis_host', -- 'REDIS_SERVICE_PORT' => 6380, -- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, -- ]); -- -- $this->requireSettingsFile(); +- if ($expected_enabled) { +- $this->assertSettingsContains($expected_settings); - -- $settings['redis.connection']['interface'] = 'PhpRedis'; -- $settings['redis.connection']['host'] = 'redis_host'; -- $settings['redis.connection']['port'] = 6380; -- $settings['cache']['default'] = 'cache.backend.redis'; +- return; +- } - -- $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); -- unset($this->settings['bootstrap_container_definition']); -- -- $this->assertSettingsContains($settings); +- $this->assertSettingsNotContains($expected_settings); - } - - /** -- * Test Redis settings with custom port. +- * Data provider for testRedis(). - */ -- public function testRedisCustomPort(): void { -- $this->setEnvVars([ -- 'DRUPAL_REDIS_ENABLED' => 1, -- 'REDIS_HOST' => 'custom_redis_host', -- 'REDIS_SERVICE_PORT' => 6380, -- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, -- ]); +- public static function dataProviderRedis(): \Iterator { +- $disabled_settings = ['redis.connection' => ['interface' => NULL], 'cache' => ['default' => NULL]]; - -- $this->requireSettingsFile(); +- yield 'default port' => [ +- [ +- 'DRUPAL_REDIS_ENABLED' => 1, +- 'REDIS_HOST' => 'redis_host', +- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, +- ], +- TRUE, +- [ +- 'redis.connection' => ['interface' => 'PhpRedis', 'host' => 'redis_host', 'port' => '6379'], +- 'cache' => ['default' => 'cache.backend.redis'], +- ], +- ]; - -- // Test custom Redis configuration. -- $settings['redis.connection']['interface'] = 'PhpRedis'; -- $settings['redis.connection']['host'] = 'custom_redis_host'; -- $settings['redis.connection']['port'] = 6380; -- $settings['cache']['default'] = 'cache.backend.redis'; +- yield 'custom host and port' => [ +- [ +- 'DRUPAL_REDIS_ENABLED' => 1, +- 'REDIS_HOST' => 'custom_redis_host', +- 'REDIS_SERVICE_PORT' => 6380, +- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, +- ], +- TRUE, +- [ +- 'redis.connection' => ['interface' => 'PhpRedis', 'host' => 'custom_redis_host', 'port' => 6380], +- 'cache' => ['default' => 'cache.backend.redis'], +- ], +- ]; - -- $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); -- unset($this->settings['bootstrap_container_definition']); +- yield 'variable not set' => [ +- ['VORTEX_REDIS_EXTENSION_LOADED' => 1], +- FALSE, +- $disabled_settings, +- ]; +- +- yield 'variable set to an empty value' => [ +- ['DRUPAL_REDIS_ENABLED' => '', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], +- FALSE, +- $disabled_settings, +- ]; +- +- yield 'variable set to zero' => [ +- ['DRUPAL_REDIS_ENABLED' => '0', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], +- FALSE, +- $disabled_settings, +- ]; - -- $this->assertSettingsContains($settings); +- yield 'variable set to a non-numeric truthy value' => [ +- ['DRUPAL_REDIS_ENABLED' => 'true', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], +- FALSE, +- $disabled_settings, +- ]; - } - - /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 306b51a3a4..29aeac80b2 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_file/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,4 +1,4 @@ -@@ -93,8 +93,6 @@ +@@ -92,8 +92,6 @@ 'xmlsitemap', ]); diff --git a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_string/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_string/docker-compose.yml index e517520d18..2beee1553e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_string/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_string/docker-compose.yml @@ -1,4 +1,4 @@ -@@ -168,17 +168,6 @@ +@@ -169,17 +169,6 @@ ports: - '8983' # Solr port in a container. Find port on host with `ahoy info` or `docker compose port search 8983`. @@ -16,7 +16,7 @@ # Browser container, used for browser testing. browser: image: selenium/standalone-chromium:__VERSION__ -@@ -195,12 +184,10 @@ +@@ -196,12 +185,10 @@ wait-for-dependencies: image: drevops/docker-wait-for-dependencies:__VERSION__ depends_on: diff --git a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_string/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_string/tests/phpunit/Drupal/SwitchableSettingsTest.php index b474a63ae0..a9d7116019 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_string/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_string/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,60 +1,85 @@ -@@ -20,62 +20,6 @@ - class SwitchableSettingsTest extends SettingsTestCase { +@@ -38,87 +38,6 @@ + } /** -- * Test ClamAV configs in Daemon mode with defaults. +- * Test ClamAV config. - */ -- public function testClamavDaemonCustom(): void { -- $this->setEnvVars([ -- 'DRUPAL_CLAMAV_ENABLED' => TRUE, -- 'DRUPAL_CLAMAV_MODE' => 'daemon', -- 'CLAMAV_HOST' => 'custom_clamav_host', -- 'CLAMAV_PORT' => 3333, -- ]); +- #[DataProvider('dataProviderClamav')] +- public function testClamav(array $vars, array $expected_present, array $expected_absent = []): void { +- $this->setEnvVars($vars); - - $this->requireSettingsFile(); - -- $config['clamav.settings']['scan_mode'] = 0; -- $config['clamav.settings']['mode_daemon_tcpip']['hostname'] = 'custom_clamav_host'; -- $config['clamav.settings']['mode_daemon_tcpip']['port'] = 3333; -- -- $this->assertConfigContains($config); +- $this->assertConfigContains($expected_present); +- $this->assertConfigNotContains($expected_absent); - } - - /** -- * Test ClamAV configs in Executable mode. +- * Data provider for testClamav(). - */ -- public function testClamavExecutable(): void { -- $this->setEnvVars([ -- 'DRUPAL_CLAMAV_ENABLED' => TRUE, -- 'CLAMAV_HOST' => 'custom_clamav_host', -- 'CLAMAV_PORT' => 3333, -- ]); +- public static function dataProviderClamav(): \Iterator { +- yield 'daemon mode with custom host and port' => [ +- [ +- 'DRUPAL_CLAMAV_ENABLED' => 1, +- 'DRUPAL_CLAMAV_MODE' => 'daemon', +- 'CLAMAV_HOST' => 'custom_clamav_host', +- 'CLAMAV_PORT' => 3333, +- ], +- [ +- 'clamav.settings' => [ +- 'scan_mode' => 0, +- 'mode_daemon_tcpip' => ['hostname' => 'custom_clamav_host', 'port' => 3333], +- ], +- ], +- ]; - -- $this->requireSettingsFile(); +- yield 'daemon mode with defaults' => [ +- [ +- 'DRUPAL_CLAMAV_ENABLED' => 1, +- 'DRUPAL_CLAMAV_MODE' => 'daemon', +- ], +- [ +- 'clamav.settings' => [ +- 'scan_mode' => 0, +- 'mode_daemon_tcpip' => ['hostname' => 'antivirus', 'port' => 3310], +- ], +- ], +- ]; - -- $config['clamav.settings']['scan_mode'] = 1; -- $config['clamav.settings']['executable_path'] = '/usr/bin/clamscan'; +- yield 'executable mode' => [ +- [ +- 'DRUPAL_CLAMAV_ENABLED' => 1, +- 'CLAMAV_HOST' => 'custom_clamav_host', +- 'CLAMAV_PORT' => 3333, +- ], +- [ +- 'clamav.settings' => ['scan_mode' => 1, 'executable_path' => '/usr/bin/clamscan'], +- ], +- ]; - -- $this->assertConfigContains($config); -- } +- yield 'variable not set' => [ +- [], +- [], +- ['clamav.settings' => ['scan_mode' => NULL]], +- ]; - -- /** -- * Test ClamAV configs in Daemon mode with defaults. -- */ -- public function testClamavDaemonDefaults(): void { -- $this->setEnvVars([ -- 'DRUPAL_CLAMAV_ENABLED' => TRUE, -- 'DRUPAL_CLAMAV_MODE' => 'daemon', -- ]); -- -- $this->requireSettingsFile(); +- yield 'variable set to an empty value' => [ +- ['DRUPAL_CLAMAV_ENABLED' => ''], +- [], +- ['clamav.settings' => ['scan_mode' => NULL]], +- ]; - -- $config['clamav.settings']['scan_mode'] = 0; -- $config['clamav.settings']['mode_daemon_tcpip']['hostname'] = 'antivirus'; -- $config['clamav.settings']['mode_daemon_tcpip']['port'] = 3310; +- yield 'variable set to zero' => [ +- ['DRUPAL_CLAMAV_ENABLED' => '0'], +- [], +- ['clamav.settings' => ['scan_mode' => NULL]], +- ]; - -- $this->assertConfigContains($config); +- yield 'variable set to a non-numeric truthy value' => [ +- ['DRUPAL_CLAMAV_ENABLED' => 'true'], +- [], +- ['clamav.settings' => ['scan_mode' => NULL]], +- ]; - } - - /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_string/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_string/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 0cfb943dba..eb7ac8eb35 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_string/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/non_interactive_config_string/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,4 +1,4 @@ -@@ -95,9 +95,6 @@ +@@ -94,9 +94,6 @@ $this->moduleInstaller->install(['redis']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_all/.env b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_all/.env index b856d08f93..18302c8603 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_all/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_all/.env @@ -1,4 +1,4 @@ -@@ -199,7 +199,7 @@ +@@ -205,7 +205,7 @@ # The channels of the notifications. # # A combination of comma-separated values: email,slack,newrelic,github,jira,webhook,diffy @@ -7,7 +7,7 @@ # An email address to send notifications from. # -@@ -214,6 +214,12 @@ +@@ -220,6 +220,12 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_github_only/.env b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_github_only/.env index 178a73ae66..6a62e9b2e1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_github_only/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_github_only/.env @@ -1,4 +1,4 @@ -@@ -199,21 +199,7 @@ +@@ -205,21 +205,7 @@ # The channels of the notifications. # # A combination of comma-separated values: email,slack,newrelic,github,jira,webhook,diffy diff --git a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_jira_only/.env b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_jira_only/.env index 71e2b09291..c9e1f11e76 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_jira_only/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_jira_only/.env @@ -1,4 +1,4 @@ -@@ -199,21 +199,10 @@ +@@ -205,21 +205,10 @@ # The channels of the notifications. # # A combination of comma-separated values: email,slack,newrelic,github,jira,webhook,diffy diff --git a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_newrelic_only/.env b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_newrelic_only/.env index 397b8a2ef9..3ca3248af5 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_newrelic_only/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_newrelic_only/.env @@ -1,4 +1,4 @@ -@@ -199,21 +199,7 @@ +@@ -205,21 +205,7 @@ # The channels of the notifications. # # A combination of comma-separated values: email,slack,newrelic,github,jira,webhook,diffy diff --git a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_none/.env b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_none/.env index 63fbcd6263..f1d17416db 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_none/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_none/.env @@ -1,4 +1,4 @@ -@@ -199,21 +199,7 @@ +@@ -205,21 +205,7 @@ # The channels of the notifications. # # A combination of comma-separated values: email,slack,newrelic,github,jira,webhook,diffy diff --git a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_slack_only/.env b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_slack_only/.env index 6f16237af1..972a5f7fc6 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_slack_only/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_slack_only/.env @@ -1,4 +1,4 @@ -@@ -199,21 +199,7 @@ +@@ -205,21 +205,7 @@ # The channels of the notifications. # # A combination of comma-separated values: email,slack,newrelic,github,jira,webhook,diffy diff --git a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_webhook_only/.env b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_webhook_only/.env index c9cbfd1ad3..57a49e77b5 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/notification_channels_webhook_only/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/notification_channels_webhook_only/.env @@ -1,4 +1,4 @@ -@@ -199,21 +199,10 @@ +@@ -205,21 +205,10 @@ # The channels of the notifications. # # A combination of comma-separated values: email,slack,newrelic,github,jira,webhook,diffy diff --git a/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/.env b/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/.env index 6741b81b05..fcb07a3f1c 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/.env @@ -1,4 +1,4 @@ -@@ -142,6 +142,18 @@ +@@ -148,6 +148,18 @@ VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 ################################################################################ @@ -17,7 +17,7 @@ # DATABASE SOURCE # ################################################################################ -@@ -164,12 +176,14 @@ +@@ -170,12 +182,14 @@ VORTEX_DB_FILE=db.sql # Database fetch source. @@ -36,7 +36,7 @@ ################################################################################ # RELEASE VERSIONING # -@@ -187,7 +201,7 @@ +@@ -193,7 +207,7 @@ # Deployment occurs when tests pass in the CI environment. # @see https://www.vortextemplate.com/docs/deployment @@ -45,7 +45,7 @@ ################################################################################ # NOTIFICATIONS # -@@ -214,17 +228,3 @@ +@@ -220,17 +234,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/.github/workflows/build-test-deploy.yml index 3569e59c68..5de23e5207 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/.github/workflows/build-test-deploy.yml @@ -14,7 +14,7 @@ # On the first build of the day (cache miss), fetch a fresh DB dump. # On subsequent builds, the restored cache already contains the dump and # the fetch script skips itself, leaving no semaphore file behind. -@@ -589,7 +598,6 @@ +@@ -594,7 +603,6 @@ VORTEX_DEPLOY_PR: ${{ env.DEPLOY_PR_NUMBER || github.event.number }} VORTEX_DEPLOY_PR_HEAD: ${{ env.DEPLOY_PR_HEAD_SHA || github.event.pull_request.head.sha }} VORTEX_DEPLOY_PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }} diff --git a/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/composer.json b/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/composer.json index 17423e068c..54a9a90cf9 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/composer.json @@ -1,6 +1,6 @@ -@@ -20,6 +20,7 @@ - "drupal/drupal_helpers": "__VERSION__", +@@ -21,6 +21,7 @@ "drupal/environment_indicator": "__VERSION__", + "drupal/fast_404": "__VERSION__", "drupal/generated_content": "__VERSION__", + "drupal/lagoon_logs": "__VERSION__", "drupal/navigation_extra_tools": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/docker-compose.yml index 274b83248e..a5a8de4809 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/docker-compose.yml @@ -17,7 +17,7 @@ webserver: build: -@@ -126,6 +131,11 @@ +@@ -127,6 +132,11 @@ networks: - default # This is a standard network and is used for all other environments, where requests routing is not required and/or not supported. - amazeeio-network ### This network is supported by Pygmy and used to route all requests to host machine locally. Removed in CI. @@ -29,7 +29,7 @@ # PHP FPM container. All web requests are going through this container. appserver: -@@ -141,6 +151,11 @@ +@@ -142,6 +152,11 @@ <<: [ *default-volumes, *default-user ] depends_on: - cli @@ -41,7 +41,7 @@ database: build: -@@ -153,9 +168,13 @@ +@@ -154,9 +169,13 @@ <<: *default-user ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -55,7 +55,7 @@ search: build: -@@ -167,6 +186,8 @@ +@@ -168,6 +187,8 @@ - search:/var/solr ports: - '8983' # Solr port in a container. Find port on host with `ahoy info` or `docker compose port search 8983`. @@ -64,7 +64,7 @@ antivirus: build: -@@ -178,6 +199,10 @@ +@@ -179,6 +200,10 @@ - '3310' # Find port on host with `docker compose port antivirus 3310`. networks: - default @@ -75,7 +75,7 @@ # Browser container, used for browser testing. browser: -@@ -190,6 +215,8 @@ +@@ -191,6 +216,8 @@ ports: - '7900' # Find port on host with `docker compose port browser 7900`. shm_size: '1gb' # Increase '/dev/shm' partition size to avoid browser crashing. @@ -84,7 +84,7 @@ # Helper container to wait for services to become available. wait-for-dependencies: -@@ -205,6 +232,8 @@ +@@ -206,6 +233,8 @@ - cache:6379 - search:8983 - curl -s "http://search:8983/solr/drupal/select?q=*:*&rows=0&wt=json" | grep response diff --git a/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 9fd3befa4f..d52bba592e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/provision_database_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -193,7 +193,7 @@ } /** -@@ -387,6 +575,268 @@ +@@ -457,6 +645,324 @@ $settings['trusted_host_patterns'] = [ '^localhost$', '^127\.0\.0\.1$', @@ -240,12 +240,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PREVIEW; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -306,12 +320,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_DEV; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -356,7 +384,7 @@ + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['robotstxt.settings']['content'] = "User-agent: *\nDisallow: /"; -+ $config['reroute_email.settings']['enable'] = FALSE; ++ $config['reroute_email.settings']['enable'] = TRUE; + $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; + $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; + $config['shield.settings']['shield_enable'] = TRUE; @@ -372,12 +400,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_STAGE; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; @@ -436,12 +478,26 @@ + $settings['config_exclude_modules'] = [ + 'devel', + 'generated_content', ++ 'reroute_email', ++ 'sdc_devel', + 'testmode', + ]; + $settings['config_sync_directory'] = '../config/default'; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = self::ENVIRONMENT_PROD; ++ $settings['fast404_allow_anon_imagecache'] = TRUE; ++ $settings['fast404_exts'] = '/^(?!\/robots)^(?!\/system\/files).*\.(txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; ++ $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; ++ $settings['fast404_path_check'] = FALSE; ++ $settings['fast404_respect_redirect'] = FALSE; ++ $settings['fast404_url_whitelisting'] = TRUE; ++ $settings['fast404_whitelist'] = [ ++ 'index.php', ++ 'rss.xml', ++ 'cron.php', ++ 'xmlrpc.php', ++ ]; + $settings['file_public_path'] = 'sites/default/files'; + $settings['file_private_path'] = 'sites/default/files/private'; + $settings['file_temp_path'] = '/tmp'; diff --git a/.vortex/cli/tests/Fixtures/handler_process/provision_profile/.env b/.vortex/cli/tests/Fixtures/handler_process/provision_profile/.env index ee483cf4b0..81726a4010 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/provision_profile/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/provision_profile/.env @@ -21,9 +21,9 @@ # Verify that configuration was not changed by database updates. # If enabled and config files are present, the provision will fail if # database update hooks modify active configuration, preventing -@@ -125,19 +118,6 @@ - # drush config:import from silently overwriting those changes. - VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_UPDATE=0 +@@ -131,19 +124,6 @@ + # configuration imports, deployment hooks and deploy steps have run. + VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION=0 -# Skip database sanitization. -# @@ -41,7 +41,7 @@ # Put the site into a maintenance mode during site provisioning. VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 -@@ -163,14 +143,6 @@ +@@ -169,14 +149,6 @@ # The file is used to import the database into an empty database container. VORTEX_DB_FILE=db.sql @@ -56,7 +56,7 @@ ################################################################################ # RELEASE VERSIONING # ################################################################################ -@@ -214,17 +186,3 @@ +@@ -220,17 +192,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/provision_profile/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/provision_profile/.github/workflows/build-test-deploy.yml index 58df31b129..b97f0f9284 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/provision_profile/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/provision_profile/.github/workflows/build-test-deploy.yml @@ -98,7 +98,7 @@ - name: Install development dependencies run: | docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c " \ -@@ -518,7 +452,6 @@ +@@ -523,7 +457,6 @@ deploy: runs-on: ubuntu-latest needs: [test, lint, build] diff --git a/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/.circleci/config.yml index 9e0a31e6bb..d32fce45d6 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/.circleci/config.yml @@ -117,9 +117,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -180,10 +185,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -348,6 +358,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/.env b/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/.env index ee483cf4b0..81726a4010 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/.env @@ -21,9 +21,9 @@ # Verify that configuration was not changed by database updates. # If enabled and config files are present, the provision will fail if # database update hooks modify active configuration, preventing -@@ -125,19 +118,6 @@ - # drush config:import from silently overwriting those changes. - VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_UPDATE=0 +@@ -131,19 +124,6 @@ + # configuration imports, deployment hooks and deploy steps have run. + VORTEX_PROVISION_VERIFY_CONFIG_UNCHANGED_AFTER_PROVISION=0 -# Skip database sanitization. -# @@ -41,7 +41,7 @@ # Put the site into a maintenance mode during site provisioning. VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 -@@ -163,14 +143,6 @@ +@@ -169,14 +149,6 @@ # The file is used to import the database into an empty database container. VORTEX_DB_FILE=db.sql @@ -56,7 +56,7 @@ ################################################################################ # RELEASE VERSIONING # ################################################################################ -@@ -214,17 +186,3 @@ +@@ -220,17 +192,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/provision_profile_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_no_clamav/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/services_no_clamav/docker-compose.yml index e517520d18..2beee1553e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_no_clamav/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/services_no_clamav/docker-compose.yml @@ -1,4 +1,4 @@ -@@ -168,17 +168,6 @@ +@@ -169,17 +169,6 @@ ports: - '8983' # Solr port in a container. Find port on host with `ahoy info` or `docker compose port search 8983`. @@ -16,7 +16,7 @@ # Browser container, used for browser testing. browser: image: selenium/standalone-chromium:__VERSION__ -@@ -195,12 +184,10 @@ +@@ -196,12 +185,10 @@ wait-for-dependencies: image: drevops/docker-wait-for-dependencies:__VERSION__ depends_on: diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_no_clamav/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/services_no_clamav/tests/phpunit/Drupal/SwitchableSettingsTest.php index b474a63ae0..a9d7116019 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_no_clamav/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/services_no_clamav/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,60 +1,85 @@ -@@ -20,62 +20,6 @@ - class SwitchableSettingsTest extends SettingsTestCase { +@@ -38,87 +38,6 @@ + } /** -- * Test ClamAV configs in Daemon mode with defaults. +- * Test ClamAV config. - */ -- public function testClamavDaemonCustom(): void { -- $this->setEnvVars([ -- 'DRUPAL_CLAMAV_ENABLED' => TRUE, -- 'DRUPAL_CLAMAV_MODE' => 'daemon', -- 'CLAMAV_HOST' => 'custom_clamav_host', -- 'CLAMAV_PORT' => 3333, -- ]); +- #[DataProvider('dataProviderClamav')] +- public function testClamav(array $vars, array $expected_present, array $expected_absent = []): void { +- $this->setEnvVars($vars); - - $this->requireSettingsFile(); - -- $config['clamav.settings']['scan_mode'] = 0; -- $config['clamav.settings']['mode_daemon_tcpip']['hostname'] = 'custom_clamav_host'; -- $config['clamav.settings']['mode_daemon_tcpip']['port'] = 3333; -- -- $this->assertConfigContains($config); +- $this->assertConfigContains($expected_present); +- $this->assertConfigNotContains($expected_absent); - } - - /** -- * Test ClamAV configs in Executable mode. +- * Data provider for testClamav(). - */ -- public function testClamavExecutable(): void { -- $this->setEnvVars([ -- 'DRUPAL_CLAMAV_ENABLED' => TRUE, -- 'CLAMAV_HOST' => 'custom_clamav_host', -- 'CLAMAV_PORT' => 3333, -- ]); +- public static function dataProviderClamav(): \Iterator { +- yield 'daemon mode with custom host and port' => [ +- [ +- 'DRUPAL_CLAMAV_ENABLED' => 1, +- 'DRUPAL_CLAMAV_MODE' => 'daemon', +- 'CLAMAV_HOST' => 'custom_clamav_host', +- 'CLAMAV_PORT' => 3333, +- ], +- [ +- 'clamav.settings' => [ +- 'scan_mode' => 0, +- 'mode_daemon_tcpip' => ['hostname' => 'custom_clamav_host', 'port' => 3333], +- ], +- ], +- ]; - -- $this->requireSettingsFile(); +- yield 'daemon mode with defaults' => [ +- [ +- 'DRUPAL_CLAMAV_ENABLED' => 1, +- 'DRUPAL_CLAMAV_MODE' => 'daemon', +- ], +- [ +- 'clamav.settings' => [ +- 'scan_mode' => 0, +- 'mode_daemon_tcpip' => ['hostname' => 'antivirus', 'port' => 3310], +- ], +- ], +- ]; - -- $config['clamav.settings']['scan_mode'] = 1; -- $config['clamav.settings']['executable_path'] = '/usr/bin/clamscan'; +- yield 'executable mode' => [ +- [ +- 'DRUPAL_CLAMAV_ENABLED' => 1, +- 'CLAMAV_HOST' => 'custom_clamav_host', +- 'CLAMAV_PORT' => 3333, +- ], +- [ +- 'clamav.settings' => ['scan_mode' => 1, 'executable_path' => '/usr/bin/clamscan'], +- ], +- ]; - -- $this->assertConfigContains($config); -- } +- yield 'variable not set' => [ +- [], +- [], +- ['clamav.settings' => ['scan_mode' => NULL]], +- ]; - -- /** -- * Test ClamAV configs in Daemon mode with defaults. -- */ -- public function testClamavDaemonDefaults(): void { -- $this->setEnvVars([ -- 'DRUPAL_CLAMAV_ENABLED' => TRUE, -- 'DRUPAL_CLAMAV_MODE' => 'daemon', -- ]); -- -- $this->requireSettingsFile(); +- yield 'variable set to an empty value' => [ +- ['DRUPAL_CLAMAV_ENABLED' => ''], +- [], +- ['clamav.settings' => ['scan_mode' => NULL]], +- ]; - -- $config['clamav.settings']['scan_mode'] = 0; -- $config['clamav.settings']['mode_daemon_tcpip']['hostname'] = 'antivirus'; -- $config['clamav.settings']['mode_daemon_tcpip']['port'] = 3310; +- yield 'variable set to zero' => [ +- ['DRUPAL_CLAMAV_ENABLED' => '0'], +- [], +- ['clamav.settings' => ['scan_mode' => NULL]], +- ]; - -- $this->assertConfigContains($config); +- yield 'variable set to a non-numeric truthy value' => [ +- ['DRUPAL_CLAMAV_ENABLED' => 'true'], +- [], +- ['clamav.settings' => ['scan_mode' => NULL]], +- ]; - } - - /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_no_clamav/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/services_no_clamav/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 0cfb943dba..eb7ac8eb35 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_no_clamav/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/services_no_clamav/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,4 +1,4 @@ -@@ -95,9 +95,6 @@ +@@ -94,9 +94,6 @@ $this->moduleInstaller->install(['redis']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/composer.json b/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/composer.json index cf7dd08e0a..8b6e9f1d74 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/composer.json @@ -1,4 +1,4 @@ -@@ -23,7 +23,6 @@ +@@ -24,7 +24,6 @@ "drupal/navigation_extra_tools": "__VERSION__", "drupal/pathauto": "__VERSION__", "drupal/redirect": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/docker-compose.yml index 9b37b1cb0e..757d8b7587 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/docker-compose.yml @@ -7,7 +7,7 @@ # The default user under which the containers should run. x-user: &default-user -@@ -154,9 +152,6 @@ +@@ -155,9 +153,6 @@ ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -17,7 +17,7 @@ search: build: context: . -@@ -197,12 +192,10 @@ +@@ -198,12 +193,10 @@ depends_on: - antivirus - database diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/tests/phpunit/Drupal/SwitchableSettingsTest.php index c4572cfd53..575be64ae1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,77 +1,83 @@ -@@ -224,79 +224,6 @@ +@@ -370,85 +370,6 @@ } /** - * Test Redis settings. - */ -- public function testRedis(): void { -- $this->setEnvVars([ -- 'DRUPAL_REDIS_ENABLED' => 1, -- 'REDIS_HOST' => 'redis_host', -- 'REDIS_SERVICE_PORT' => 1234, -- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, -- ]); +- #[DataProvider('dataProviderRedis')] +- public function testRedis(array $vars, bool $expected_enabled, array $expected_settings): void { +- $this->setEnvVars($vars); - - $this->requireSettingsFile(); - -- $settings['redis.connection']['interface'] = 'PhpRedis'; -- $settings['redis.connection']['host'] = 'redis_host'; -- $settings['redis.connection']['port'] = 1234; -- $settings['cache']['default'] = 'cache.backend.redis'; -- -- $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); +- $this->assertSame($expected_enabled, array_key_exists('bootstrap_container_definition', $this->settings), 'Bootstrap container definition'); - unset($this->settings['bootstrap_container_definition']); - -- $this->assertSettingsContains($settings); -- } -- -- /** -- * Test Redis settings with REDIS_* environment variables. -- */ -- public function testRedisVariables(): void { -- $this->setEnvVars([ -- 'DRUPAL_REDIS_ENABLED' => 1, -- 'REDIS_HOST' => 'redis_host', -- 'REDIS_SERVICE_PORT' => 6380, -- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, -- ]); -- -- $this->requireSettingsFile(); +- if ($expected_enabled) { +- $this->assertSettingsContains($expected_settings); - -- $settings['redis.connection']['interface'] = 'PhpRedis'; -- $settings['redis.connection']['host'] = 'redis_host'; -- $settings['redis.connection']['port'] = 6380; -- $settings['cache']['default'] = 'cache.backend.redis'; +- return; +- } - -- $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); -- unset($this->settings['bootstrap_container_definition']); -- -- $this->assertSettingsContains($settings); +- $this->assertSettingsNotContains($expected_settings); - } - - /** -- * Test Redis settings with custom port. +- * Data provider for testRedis(). - */ -- public function testRedisCustomPort(): void { -- $this->setEnvVars([ -- 'DRUPAL_REDIS_ENABLED' => 1, -- 'REDIS_HOST' => 'custom_redis_host', -- 'REDIS_SERVICE_PORT' => 6380, -- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, -- ]); +- public static function dataProviderRedis(): \Iterator { +- $disabled_settings = ['redis.connection' => ['interface' => NULL], 'cache' => ['default' => NULL]]; - -- $this->requireSettingsFile(); +- yield 'default port' => [ +- [ +- 'DRUPAL_REDIS_ENABLED' => 1, +- 'REDIS_HOST' => 'redis_host', +- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, +- ], +- TRUE, +- [ +- 'redis.connection' => ['interface' => 'PhpRedis', 'host' => 'redis_host', 'port' => '6379'], +- 'cache' => ['default' => 'cache.backend.redis'], +- ], +- ]; - -- // Test custom Redis configuration. -- $settings['redis.connection']['interface'] = 'PhpRedis'; -- $settings['redis.connection']['host'] = 'custom_redis_host'; -- $settings['redis.connection']['port'] = 6380; -- $settings['cache']['default'] = 'cache.backend.redis'; +- yield 'custom host and port' => [ +- [ +- 'DRUPAL_REDIS_ENABLED' => 1, +- 'REDIS_HOST' => 'custom_redis_host', +- 'REDIS_SERVICE_PORT' => 6380, +- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, +- ], +- TRUE, +- [ +- 'redis.connection' => ['interface' => 'PhpRedis', 'host' => 'custom_redis_host', 'port' => 6380], +- 'cache' => ['default' => 'cache.backend.redis'], +- ], +- ]; - -- $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); -- unset($this->settings['bootstrap_container_definition']); +- yield 'variable not set' => [ +- ['VORTEX_REDIS_EXTENSION_LOADED' => 1], +- FALSE, +- $disabled_settings, +- ]; +- +- yield 'variable set to an empty value' => [ +- ['DRUPAL_REDIS_ENABLED' => '', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], +- FALSE, +- $disabled_settings, +- ]; +- +- yield 'variable set to zero' => [ +- ['DRUPAL_REDIS_ENABLED' => '0', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], +- FALSE, +- $disabled_settings, +- ]; - -- $this->assertSettingsContains($settings); +- yield 'variable set to a non-numeric truthy value' => [ +- ['DRUPAL_REDIS_ENABLED' => 'true', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], +- FALSE, +- $disabled_settings, +- ]; - } - - /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 306b51a3a4..29aeac80b2 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/services_no_redis/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,4 +1,4 @@ -@@ -93,8 +93,6 @@ +@@ -92,8 +92,6 @@ 'xmlsitemap', ]); diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/composer.json b/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/composer.json index d32ead2887..6a172fc24e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/composer.json @@ -1,4 +1,4 @@ -@@ -28,7 +28,6 @@ +@@ -29,7 +29,6 @@ "drupal/robotstxt": "__VERSION__", "drupal/sdc_devel": "__VERSION__", "drupal/search_api": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/docker-compose.yml index b698489a59..b6bf68a1aa 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/docker-compose.yml @@ -1,4 +1,4 @@ -@@ -157,17 +157,6 @@ +@@ -158,17 +158,6 @@ cache: image: uselagoon/valkey-8:__VERSION__ @@ -16,7 +16,7 @@ antivirus: build: context: . -@@ -198,13 +187,10 @@ +@@ -199,13 +188,10 @@ - antivirus - database - cache @@ -30,7 +30,7 @@ networks: ### Use external networks locally. Automatically removed in CI. amazeeio-network: ### Automatically removed in CI. -@@ -213,7 +199,6 @@ +@@ -214,7 +200,6 @@ volumes: app: {} files: {} diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/tests/phpunit/Drupal/EnvironmentSettingsTest.php index f1c691cba5..251d3ff43c 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -7,7 +7,7 @@ $this->assertConfig($config); $settings['auto_create_htaccess'] = FALSE; -@@ -177,8 +175,6 @@ +@@ -191,8 +189,6 @@ $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; $config['system.performance']['cache']['page']['max_age'] = 1800; @@ -16,7 +16,7 @@ $this->assertConfig($config); // Verify settings overrides. -@@ -238,8 +234,6 @@ +@@ -266,8 +262,6 @@ $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; @@ -25,7 +25,7 @@ $this->assertConfig($config); $settings['auto_create_htaccess'] = FALSE; -@@ -298,8 +292,6 @@ +@@ -340,8 +334,6 @@ $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; @@ -34,7 +34,7 @@ $this->assertConfig($config); $settings['auto_create_htaccess'] = FALSE; -@@ -360,8 +352,6 @@ +@@ -416,8 +408,6 @@ $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/tests/phpunit/Drupal/SwitchableSettingsTest.php index a4ca21fffd..ef42d4b7bb 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,4 +1,4 @@ -@@ -297,35 +297,6 @@ +@@ -449,35 +449,6 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index a212e6cfa7..ceaa4e8bff 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/services_no_solr/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,4 +1,4 @@ -@@ -98,13 +98,9 @@ +@@ -97,15 +97,11 @@ $this->moduleInstaller->install(['clamav']); $this->configFactory->getEditable('clamav.settings')->set('mode_daemon_tcpip.hostname', 'clamav')->save(); @@ -7,6 +7,8 @@ $this->moduleInstaller->install(['sdc_devel']); $this->moduleInstaller->install(['devel']); + + $this->moduleInstaller->install(['reroute_email']); - - $this->moduleInstaller->install(['sw_search']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_none/composer.json b/.vortex/cli/tests/Fixtures/handler_process/services_none/composer.json index 382e5017f9..22516eb543 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_none/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/services_none/composer.json @@ -6,7 +6,7 @@ "drupal/coffee": "__VERSION__", "drupal/config_split": "__VERSION__", "drupal/config_update": "__VERSION__", -@@ -23,12 +22,10 @@ +@@ -24,12 +23,10 @@ "drupal/navigation_extra_tools": "__VERSION__", "drupal/pathauto": "__VERSION__", "drupal/redirect": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_none/docker-compose.yml b/.vortex/cli/tests/Fixtures/handler_process/services_none/docker-compose.yml index 61a5c7432b..fbae3a3682 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_none/docker-compose.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/services_none/docker-compose.yml @@ -7,7 +7,7 @@ # The default user under which the containers should run. x-user: &default-user -@@ -154,31 +152,6 @@ +@@ -155,31 +153,6 @@ ports: - '3306' # Database port in a container. Find port on host with `ahoy info` or `docker compose port database 3306`. @@ -39,7 +39,7 @@ # Browser container, used for browser testing. browser: image: selenium/standalone-chromium:__VERSION__ -@@ -195,16 +168,9 @@ +@@ -196,16 +169,9 @@ wait-for-dependencies: image: drevops/docker-wait-for-dependencies:__VERSION__ depends_on: @@ -56,7 +56,7 @@ networks: ### Use external networks locally. Automatically removed in CI. amazeeio-network: ### Automatically removed in CI. -@@ -213,7 +179,6 @@ +@@ -214,7 +180,6 @@ volumes: app: {} files: {} diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_none/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/services_none/tests/phpunit/Drupal/EnvironmentSettingsTest.php index f1c691cba5..251d3ff43c 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_none/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/services_none/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -7,7 +7,7 @@ $this->assertConfig($config); $settings['auto_create_htaccess'] = FALSE; -@@ -177,8 +175,6 @@ +@@ -191,8 +189,6 @@ $config['reroute_email.settings']['address'] = 'webmaster@star-wars.com'; $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; $config['system.performance']['cache']['page']['max_age'] = 1800; @@ -16,7 +16,7 @@ $this->assertConfig($config); // Verify settings overrides. -@@ -238,8 +234,6 @@ +@@ -266,8 +262,6 @@ $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; @@ -25,7 +25,7 @@ $this->assertConfig($config); $settings['auto_create_htaccess'] = FALSE; -@@ -298,8 +292,6 @@ +@@ -340,8 +334,6 @@ $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; @@ -34,7 +34,7 @@ $this->assertConfig($config); $settings['auto_create_htaccess'] = FALSE; -@@ -360,8 +352,6 @@ +@@ -416,8 +408,6 @@ $config['reroute_email.settings']['allowed'] = '*@star-wars.com'; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_none/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/services_none/tests/phpunit/Drupal/SwitchableSettingsTest.php index 22018c4f39..f8dff5656e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_none/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/services_none/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -1,143 +1,174 @@ -@@ -20,62 +20,6 @@ - class SwitchableSettingsTest extends SettingsTestCase { +@@ -38,87 +38,6 @@ + } /** -- * Test ClamAV configs in Daemon mode with defaults. +- * Test ClamAV config. - */ -- public function testClamavDaemonCustom(): void { -- $this->setEnvVars([ -- 'DRUPAL_CLAMAV_ENABLED' => TRUE, -- 'DRUPAL_CLAMAV_MODE' => 'daemon', -- 'CLAMAV_HOST' => 'custom_clamav_host', -- 'CLAMAV_PORT' => 3333, -- ]); +- #[DataProvider('dataProviderClamav')] +- public function testClamav(array $vars, array $expected_present, array $expected_absent = []): void { +- $this->setEnvVars($vars); - - $this->requireSettingsFile(); - -- $config['clamav.settings']['scan_mode'] = 0; -- $config['clamav.settings']['mode_daemon_tcpip']['hostname'] = 'custom_clamav_host'; -- $config['clamav.settings']['mode_daemon_tcpip']['port'] = 3333; -- -- $this->assertConfigContains($config); +- $this->assertConfigContains($expected_present); +- $this->assertConfigNotContains($expected_absent); - } - - /** -- * Test ClamAV configs in Executable mode. +- * Data provider for testClamav(). - */ -- public function testClamavExecutable(): void { -- $this->setEnvVars([ -- 'DRUPAL_CLAMAV_ENABLED' => TRUE, -- 'CLAMAV_HOST' => 'custom_clamav_host', -- 'CLAMAV_PORT' => 3333, -- ]); -- -- $this->requireSettingsFile(); -- -- $config['clamav.settings']['scan_mode'] = 1; -- $config['clamav.settings']['executable_path'] = '/usr/bin/clamscan'; -- -- $this->assertConfigContains($config); -- } -- -- /** -- * Test ClamAV configs in Daemon mode with defaults. -- */ -- public function testClamavDaemonDefaults(): void { -- $this->setEnvVars([ -- 'DRUPAL_CLAMAV_ENABLED' => TRUE, -- 'DRUPAL_CLAMAV_MODE' => 'daemon', -- ]); -- -- $this->requireSettingsFile(); -- -- $config['clamav.settings']['scan_mode'] = 0; -- $config['clamav.settings']['mode_daemon_tcpip']['hostname'] = 'antivirus'; -- $config['clamav.settings']['mode_daemon_tcpip']['port'] = 3310; -- -- $this->assertConfigContains($config); +- public static function dataProviderClamav(): \Iterator { +- yield 'daemon mode with custom host and port' => [ +- [ +- 'DRUPAL_CLAMAV_ENABLED' => 1, +- 'DRUPAL_CLAMAV_MODE' => 'daemon', +- 'CLAMAV_HOST' => 'custom_clamav_host', +- 'CLAMAV_PORT' => 3333, +- ], +- [ +- 'clamav.settings' => [ +- 'scan_mode' => 0, +- 'mode_daemon_tcpip' => ['hostname' => 'custom_clamav_host', 'port' => 3333], +- ], +- ], +- ]; +- +- yield 'daemon mode with defaults' => [ +- [ +- 'DRUPAL_CLAMAV_ENABLED' => 1, +- 'DRUPAL_CLAMAV_MODE' => 'daemon', +- ], +- [ +- 'clamav.settings' => [ +- 'scan_mode' => 0, +- 'mode_daemon_tcpip' => ['hostname' => 'antivirus', 'port' => 3310], +- ], +- ], +- ]; +- +- yield 'executable mode' => [ +- [ +- 'DRUPAL_CLAMAV_ENABLED' => 1, +- 'CLAMAV_HOST' => 'custom_clamav_host', +- 'CLAMAV_PORT' => 3333, +- ], +- [ +- 'clamav.settings' => ['scan_mode' => 1, 'executable_path' => '/usr/bin/clamscan'], +- ], +- ]; +- +- yield 'variable not set' => [ +- [], +- [], +- ['clamav.settings' => ['scan_mode' => NULL]], +- ]; +- +- yield 'variable set to an empty value' => [ +- ['DRUPAL_CLAMAV_ENABLED' => ''], +- [], +- ['clamav.settings' => ['scan_mode' => NULL]], +- ]; +- +- yield 'variable set to zero' => [ +- ['DRUPAL_CLAMAV_ENABLED' => '0'], +- [], +- ['clamav.settings' => ['scan_mode' => NULL]], +- ]; +- +- yield 'variable set to a non-numeric truthy value' => [ +- ['DRUPAL_CLAMAV_ENABLED' => 'true'], +- [], +- ['clamav.settings' => ['scan_mode' => NULL]], +- ]; - } - - /** * Test Config Split config. */ #[DataProvider('dataProviderConfigSplit')] -@@ -221,108 +165,6 @@ - 'environment_indicator.settings' => ['toolbar_integration' => [TRUE], 'favicon' => TRUE], - ], - ]; +@@ -367,114 +286,6 @@ + } + + rmdir($path); - } - - /** - * Test Redis settings. - */ -- public function testRedis(): void { -- $this->setEnvVars([ -- 'DRUPAL_REDIS_ENABLED' => 1, -- 'REDIS_HOST' => 'redis_host', -- 'REDIS_SERVICE_PORT' => 1234, -- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, -- ]); +- #[DataProvider('dataProviderRedis')] +- public function testRedis(array $vars, bool $expected_enabled, array $expected_settings): void { +- $this->setEnvVars($vars); - - $this->requireSettingsFile(); - -- $settings['redis.connection']['interface'] = 'PhpRedis'; -- $settings['redis.connection']['host'] = 'redis_host'; -- $settings['redis.connection']['port'] = 1234; -- $settings['cache']['default'] = 'cache.backend.redis'; -- -- $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); +- $this->assertSame($expected_enabled, array_key_exists('bootstrap_container_definition', $this->settings), 'Bootstrap container definition'); - unset($this->settings['bootstrap_container_definition']); - -- $this->assertSettingsContains($settings); -- } -- -- /** -- * Test Redis settings with REDIS_* environment variables. -- */ -- public function testRedisVariables(): void { -- $this->setEnvVars([ -- 'DRUPAL_REDIS_ENABLED' => 1, -- 'REDIS_HOST' => 'redis_host', -- 'REDIS_SERVICE_PORT' => 6380, -- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, -- ]); -- -- $this->requireSettingsFile(); -- -- $settings['redis.connection']['interface'] = 'PhpRedis'; -- $settings['redis.connection']['host'] = 'redis_host'; -- $settings['redis.connection']['port'] = 6380; -- $settings['cache']['default'] = 'cache.backend.redis'; +- if ($expected_enabled) { +- $this->assertSettingsContains($expected_settings); - -- $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); -- unset($this->settings['bootstrap_container_definition']); +- return; +- } - -- $this->assertSettingsContains($settings); +- $this->assertSettingsNotContains($expected_settings); - } - - /** -- * Test Redis settings with custom port. +- * Data provider for testRedis(). - */ -- public function testRedisCustomPort(): void { -- $this->setEnvVars([ -- 'DRUPAL_REDIS_ENABLED' => 1, -- 'REDIS_HOST' => 'custom_redis_host', -- 'REDIS_SERVICE_PORT' => 6380, -- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, -- ]); -- -- $this->requireSettingsFile(); -- -- // Test custom Redis configuration. -- $settings['redis.connection']['interface'] = 'PhpRedis'; -- $settings['redis.connection']['host'] = 'custom_redis_host'; -- $settings['redis.connection']['port'] = 6380; -- $settings['cache']['default'] = 'cache.backend.redis'; -- -- $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); -- unset($this->settings['bootstrap_container_definition']); -- -- $this->assertSettingsContains($settings); +- public static function dataProviderRedis(): \Iterator { +- $disabled_settings = ['redis.connection' => ['interface' => NULL], 'cache' => ['default' => NULL]]; +- +- yield 'default port' => [ +- [ +- 'DRUPAL_REDIS_ENABLED' => 1, +- 'REDIS_HOST' => 'redis_host', +- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, +- ], +- TRUE, +- [ +- 'redis.connection' => ['interface' => 'PhpRedis', 'host' => 'redis_host', 'port' => '6379'], +- 'cache' => ['default' => 'cache.backend.redis'], +- ], +- ]; +- +- yield 'custom host and port' => [ +- [ +- 'DRUPAL_REDIS_ENABLED' => 1, +- 'REDIS_HOST' => 'custom_redis_host', +- 'REDIS_SERVICE_PORT' => 6380, +- 'VORTEX_REDIS_EXTENSION_LOADED' => 1, +- ], +- TRUE, +- [ +- 'redis.connection' => ['interface' => 'PhpRedis', 'host' => 'custom_redis_host', 'port' => 6380], +- 'cache' => ['default' => 'cache.backend.redis'], +- ], +- ]; +- +- yield 'variable not set' => [ +- ['VORTEX_REDIS_EXTENSION_LOADED' => 1], +- FALSE, +- $disabled_settings, +- ]; +- +- yield 'variable set to an empty value' => [ +- ['DRUPAL_REDIS_ENABLED' => '', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], +- FALSE, +- $disabled_settings, +- ]; +- +- yield 'variable set to zero' => [ +- ['DRUPAL_REDIS_ENABLED' => '0', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], +- FALSE, +- $disabled_settings, +- ]; +- +- yield 'variable set to a non-numeric truthy value' => [ +- ['DRUPAL_REDIS_ENABLED' => 'true', 'VORTEX_REDIS_EXTENSION_LOADED' => 1], +- FALSE, +- $disabled_settings, +- ]; - } - - /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/services_none/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php b/.vortex/cli/tests/Fixtures/handler_process/services_none/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php index 03dae7040e..a014d0e30f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/services_none/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php +++ b/.vortex/cli/tests/Fixtures/handler_process/services_none/web/modules/custom/sw_base/src/Plugin/DeployStep/EnableDevelopmentModulesDeployStep.php @@ -1,4 +1,4 @@ -@@ -93,18 +93,9 @@ +@@ -92,20 +92,11 @@ 'xmlsitemap', ]); @@ -12,6 +12,8 @@ $this->moduleInstaller->install(['sdc_devel']); $this->moduleInstaller->install(['devel']); + + $this->moduleInstaller->install(['reroute_email']); - - $this->moduleInstaller->install(['sw_search']); diff --git a/.vortex/cli/tests/Fixtures/handler_process/starter_drupal_cms_profile/.env b/.vortex/cli/tests/Fixtures/handler_process/starter_drupal_cms_profile/.env index dee75aa857..e48547dc4f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/starter_drupal_cms_profile/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/starter_drupal_cms_profile/.env @@ -7,7 +7,7 @@ # Drupal configuration directory. # -@@ -214,17 +214,3 @@ +@@ -220,17 +220,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/starter_drupal_cms_profile/composer.json b/.vortex/cli/tests/Fixtures/handler_process/starter_drupal_cms_profile/composer.json index 15dce94a34..384180e92f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/starter_drupal_cms_profile/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/starter_drupal_cms_profile/composer.json @@ -7,17 +7,17 @@ "drupal/config_split": "__VERSION__", "drupal/config_update": "__VERSION__", @@ -35,7 +36,9 @@ + "drupal/stage_file_proxy": "__VERSION__", "drupal/testmode": "__VERSION__", "drupal/xmlsitemap": "__VERSION__", - "drush/drush": "__VERSION__", -- "webflo/drupal-finder": "__VERSION__" +- "drush/drush": "__VERSION__" ++ "drush/drush": "__VERSION__", + "symfony/http-client": "^6.4 || ^7.0", -+ "webflo/drupal-finder": "__VERSION__", + "wikimedia/composer-merge-plugin": "__VERSION__" }, "require-dev": { "behat/behat": "__VERSION__", -@@ -72,7 +75,7 @@ +@@ -67,7 +70,7 @@ "url": "https://packages.drupal.org/8" } ], @@ -26,7 +26,7 @@ "prefer-stable": true, "autoload-dev": { "classmap": [ -@@ -90,7 +93,11 @@ +@@ -85,7 +88,11 @@ "phpstan/extension-installer": true, "pyrech/composer-changelogs": true, "symfony/runtime": true, @@ -39,7 +39,7 @@ }, "bump-after-update": true, "discard-changes": true, -@@ -165,6 +172,19 @@ +@@ -160,6 +167,19 @@ "patchLevel": { "drupal/core": "-p2" }, diff --git a/.vortex/cli/tests/Fixtures/handler_process/starter_drupal_profile/.env b/.vortex/cli/tests/Fixtures/handler_process/starter_drupal_profile/.env index 552bc2a974..fe5120e2a1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/starter_drupal_profile/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/starter_drupal_profile/.env @@ -1,4 +1,4 @@ -@@ -214,17 +214,3 @@ +@@ -220,17 +220,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com|Webmaster" diff --git a/.vortex/cli/tests/Fixtures/handler_process/theme_claro/.docker/cli.dockerfile b/.vortex/cli/tests/Fixtures/handler_process/theme_claro/.docker/cli.dockerfile index 573ef6b35d..870dcccc9d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/theme_claro/.docker/cli.dockerfile +++ b/.vortex/cli/tests/Fixtures/handler_process/theme_claro/.docker/cli.dockerfile @@ -7,7 +7,7 @@ ENV DRUPAL_THEME=${DRUPAL_THEME} ARG VORTEX_FRONTEND_BUILD_SKIP="0" -@@ -94,13 +94,5 @@ +@@ -95,13 +95,5 @@ # Create file directories and set correct permissions. # hadolint ignore=SC2174 # only the leaf directory needs the mode RUN mkdir -p -m 2775 "/app/${WEBROOT}/${DRUPAL_PUBLIC_FILES}" "/app/${WEBROOT}/${DRUPAL_PRIVATE_FILES}" "${DRUPAL_TEMPORARY_FILES}" diff --git a/.vortex/cli/tests/Fixtures/handler_process/theme_claro/rector.php b/.vortex/cli/tests/Fixtures/handler_process/theme_claro/rector.php index 2d3912fefc..be61deb99e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/theme_claro/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/theme_claro/rector.php @@ -1,4 +1,4 @@ -@@ -48,7 +48,6 @@ +@@ -47,7 +47,6 @@ return RectorConfig::configure() ->withPaths([ __DIR__ . '/web/modules/custom', diff --git a/.vortex/cli/tests/Fixtures/handler_process/theme_custom_non_vortex/.env b/.vortex/cli/tests/Fixtures/handler_process/theme_custom_non_vortex/.env index e72da40ec8..6257c561cc 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/theme_custom_non_vortex/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/theme_custom_non_vortex/.env @@ -1,4 +1,4 @@ -@@ -169,7 +169,7 @@ +@@ -175,7 +175,7 @@ # Database dump file sourced from a URL. # # HTTP Basic Authentication credentials should be embedded into the value. diff --git a/.vortex/cli/tests/Fixtures/handler_process/theme_olivero/.docker/cli.dockerfile b/.vortex/cli/tests/Fixtures/handler_process/theme_olivero/.docker/cli.dockerfile index 573ef6b35d..870dcccc9d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/theme_olivero/.docker/cli.dockerfile +++ b/.vortex/cli/tests/Fixtures/handler_process/theme_olivero/.docker/cli.dockerfile @@ -7,7 +7,7 @@ ENV DRUPAL_THEME=${DRUPAL_THEME} ARG VORTEX_FRONTEND_BUILD_SKIP="0" -@@ -94,13 +94,5 @@ +@@ -95,13 +95,5 @@ # Create file directories and set correct permissions. # hadolint ignore=SC2174 # only the leaf directory needs the mode RUN mkdir -p -m 2775 "/app/${WEBROOT}/${DRUPAL_PUBLIC_FILES}" "/app/${WEBROOT}/${DRUPAL_PRIVATE_FILES}" "${DRUPAL_TEMPORARY_FILES}" diff --git a/.vortex/cli/tests/Fixtures/handler_process/theme_olivero/rector.php b/.vortex/cli/tests/Fixtures/handler_process/theme_olivero/rector.php index 2d3912fefc..be61deb99e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/theme_olivero/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/theme_olivero/rector.php @@ -1,4 +1,4 @@ -@@ -48,7 +48,6 @@ +@@ -47,7 +47,6 @@ return RectorConfig::configure() ->withPaths([ __DIR__ . '/web/modules/custom', diff --git a/.vortex/cli/tests/Fixtures/handler_process/theme_stark/.docker/cli.dockerfile b/.vortex/cli/tests/Fixtures/handler_process/theme_stark/.docker/cli.dockerfile index 573ef6b35d..870dcccc9d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/theme_stark/.docker/cli.dockerfile +++ b/.vortex/cli/tests/Fixtures/handler_process/theme_stark/.docker/cli.dockerfile @@ -7,7 +7,7 @@ ENV DRUPAL_THEME=${DRUPAL_THEME} ARG VORTEX_FRONTEND_BUILD_SKIP="0" -@@ -94,13 +94,5 @@ +@@ -95,13 +95,5 @@ # Create file directories and set correct permissions. # hadolint ignore=SC2174 # only the leaf directory needs the mode RUN mkdir -p -m 2775 "/app/${WEBROOT}/${DRUPAL_PUBLIC_FILES}" "/app/${WEBROOT}/${DRUPAL_PRIVATE_FILES}" "${DRUPAL_TEMPORARY_FILES}" diff --git a/.vortex/cli/tests/Fixtures/handler_process/theme_stark/rector.php b/.vortex/cli/tests/Fixtures/handler_process/theme_stark/rector.php index 2d3912fefc..be61deb99e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/theme_stark/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/theme_stark/rector.php @@ -1,4 +1,4 @@ -@@ -48,7 +48,6 @@ +@@ -47,7 +47,6 @@ return RectorConfig::configure() ->withPaths([ __DIR__ . '/web/modules/custom', diff --git a/.vortex/cli/tests/Fixtures/handler_process/timezone_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/timezone_circleci/.circleci/config.yml index 4acc6eb0fc..3029359759 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/timezone_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/timezone_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -188,10 +193,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -428,6 +438,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/timezone_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/timezone_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/timezone_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/timezone_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/timezone_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/timezone_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/timezone_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/timezone_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint/composer.json index a3e4281367..08d40d0516 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint/composer.json @@ -1,17 +1,11 @@ -@@ -40,26 +40,17 @@ - "require-dev": { - "behat/behat": "__VERSION__", +@@ -42,17 +42,10 @@ "dantleech/gherkin-lint": "__VERSION__", -- "dealerdirect/phpcodesniffer-composer-installer": "__VERSION__", - "drevops/behat-format-progress-fail": "__VERSION__", "drevops/behat-screenshot": "__VERSION__", "drevops/behat-steps": "__VERSION__", - "drevops/phpcs-standard": "__VERSION__", - "drupal/coder": "__VERSION__", "drupal/drupal-extension": "__VERSION__", "ergebnis/composer-normalize": "__VERSION__", - "lullabot/mink-selenium2-driver": "__VERSION__", - "lullabot/php-webdriver": "__VERSION__", - "mglaman/phpstan-drupal": "__VERSION__", "mikey179/vfsstream": "__VERSION__", - "palantirnet/drupal-rector": "__VERSION__", @@ -21,11 +15,8 @@ - "phpstan/phpstan": "__VERSION__", "phpunit/phpunit": "__VERSION__", "pyrech/composer-changelogs": "__VERSION__", -- "rector/rector": "__VERSION__", "softcreatr/jsonpath": "^0.10 || ^1.0", - "vincentlanglet/twig-cs-fixer": "__VERSION__" - }, -@@ -83,11 +74,9 @@ +@@ -78,11 +71,9 @@ "allow-plugins": { "composer/installers": true, "cweagans/composer-patches": true, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint/web/sites/default/includes/modules/settings.fast404.php b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint/web/sites/default/includes/modules/settings.fast404.php deleted file mode 100644 index 74b826db06..0000000000 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint/web/sites/default/includes/modules/settings.fast404.php +++ /dev/null @@ -1,8 +0,0 @@ -@@ -22,7 +22,6 @@ - $settings['fast404_string_whitelisting'] = ['/advagg_']; - $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; - include_once $contrib_path . '/fast404/fast404.inc'; -- // @phpstan-ignore-next-line - fast404_preboot($settings); - // @codeCoverageIgnoreEnd - } diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint/web/sites/default/includes/modules/settings.fast_404.php b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint/web/sites/default/includes/modules/settings.fast_404.php new file mode 100644 index 0000000000..f9c4ae6d15 --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint/web/sites/default/includes/modules/settings.fast_404.php @@ -0,0 +1,7 @@ +@@ -56,6 +56,5 @@ + // the module passes an array where an exception is expected. Patch it with + // https://www.drupal.org/files/issues/2023-08-24/fast_404_3x-3194034-10.patch + // @see https://www.drupal.org/project/fast_404/issues/3194034 +- // @phpstan-ignore-next-line + fast404_preboot($settings); + } diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.circleci/config.yml index 7b15fcd952..3211271395 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -176,10 +181,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -416,6 +426,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/composer.json index a3e4281367..08d40d0516 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/composer.json @@ -1,17 +1,11 @@ -@@ -40,26 +40,17 @@ - "require-dev": { - "behat/behat": "__VERSION__", +@@ -42,17 +42,10 @@ "dantleech/gherkin-lint": "__VERSION__", -- "dealerdirect/phpcodesniffer-composer-installer": "__VERSION__", - "drevops/behat-format-progress-fail": "__VERSION__", "drevops/behat-screenshot": "__VERSION__", "drevops/behat-steps": "__VERSION__", - "drevops/phpcs-standard": "__VERSION__", - "drupal/coder": "__VERSION__", "drupal/drupal-extension": "__VERSION__", "ergebnis/composer-normalize": "__VERSION__", - "lullabot/mink-selenium2-driver": "__VERSION__", - "lullabot/php-webdriver": "__VERSION__", - "mglaman/phpstan-drupal": "__VERSION__", "mikey179/vfsstream": "__VERSION__", - "palantirnet/drupal-rector": "__VERSION__", @@ -21,11 +15,8 @@ - "phpstan/phpstan": "__VERSION__", "phpunit/phpunit": "__VERSION__", "pyrech/composer-changelogs": "__VERSION__", -- "rector/rector": "__VERSION__", "softcreatr/jsonpath": "^0.10 || ^1.0", - "vincentlanglet/twig-cs-fixer": "__VERSION__" - }, -@@ -83,11 +74,9 @@ +@@ -78,11 +71,9 @@ "allow-plugins": { "composer/installers": true, "cweagans/composer-patches": true, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 8f47fef2dc..1babe66629 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -9,7 +9,7 @@ */ #[Group('drupal_settings')] class EnvironmentSettingsTest extends SettingsTestCase { -@@ -332,9 +328,9 @@ +@@ -388,9 +384,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/web/sites/default/includes/modules/settings.fast404.php b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/web/sites/default/includes/modules/settings.fast404.php deleted file mode 100644 index 74b826db06..0000000000 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/web/sites/default/includes/modules/settings.fast404.php +++ /dev/null @@ -1,8 +0,0 @@ -@@ -22,7 +22,6 @@ - $settings['fast404_string_whitelisting'] = ['/advagg_']; - $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; - include_once $contrib_path . '/fast404/fast404.inc'; -- // @phpstan-ignore-next-line - fast404_preboot($settings); - // @codeCoverageIgnoreEnd - } diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/web/sites/default/includes/modules/settings.fast_404.php b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/web/sites/default/includes/modules/settings.fast_404.php new file mode 100644 index 0000000000..f9c4ae6d15 --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/web/sites/default/includes/modules/settings.fast_404.php @@ -0,0 +1,7 @@ +@@ -56,6 +56,5 @@ + // the module passes an array where an exception is expected. Patch it with + // https://www.drupal.org/files/issues/2023-08-24/fast_404_3x-3194034-10.patch + // @see https://www.drupal.org/project/fast_404/issues/3194034 +- // @phpstan-ignore-next-line + fast404_preboot($settings); + } diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/.dockerignore index 978d823173..65d1dcd4f7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/.dockerignore @@ -1,4 +1,4 @@ -@@ -39,7 +39,6 @@ +@@ -42,7 +42,6 @@ **/.artifacts **/.data **/.logs diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/.github/workflows/build-test-deploy.yml index 68fc2aef31..bac926ab36 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/.github/workflows/build-test-deploy.yml @@ -126,5 +126,5 @@ - files: | - .logs/test_results/**/*.xml - - name: Setup tmate session - if: ${{ !cancelled() && github.event.inputs.enable_terminal }} + # Placed after the test steps so a dirty tree never suppresses them. + - name: Check that the build left a clean working tree diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/composer.json index 7c5d2045b8..4ca103152c 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/composer.json @@ -1,20 +1,16 @@ -@@ -38,15 +38,9 @@ - "webflo/drupal-finder": "__VERSION__" +@@ -38,22 +38,15 @@ + "drush/drush": "__VERSION__" }, "require-dev": { - "behat/behat": "__VERSION__", - "dantleech/gherkin-lint": "__VERSION__", - "dealerdirect/phpcodesniffer-composer-installer": "__VERSION__", -- "drevops/behat-format-progress-fail": "__VERSION__", - "drevops/behat-screenshot": "__VERSION__", - "drevops/behat-steps": "__VERSION__", "drevops/phpcs-standard": "__VERSION__", "drupal/coder": "__VERSION__", - "drupal/drupal-extension": "__VERSION__", "ergebnis/composer-normalize": "__VERSION__", - "lullabot/mink-selenium2-driver": "__VERSION__", - "lullabot/php-webdriver": "__VERSION__", -@@ -54,10 +48,8 @@ + "mglaman/phpstan-drupal": "__VERSION__", "mikey179/vfsstream": "__VERSION__", "palantirnet/drupal-rector": "__VERSION__", "phpcompatibility/php-compatibility": "__VERSION__", @@ -23,9 +19,9 @@ "phpstan/phpstan": "__VERSION__", - "phpunit/phpunit": "__VERSION__", "pyrech/composer-changelogs": "__VERSION__", - "rector/rector": "__VERSION__", "softcreatr/jsonpath": "^0.10 || ^1.0", -@@ -74,11 +66,6 @@ + "vincentlanglet/twig-cs-fixer": "__VERSION__" +@@ -69,11 +62,6 @@ ], "minimum-stability": "stable", "prefer-stable": true, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/rector.php b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/rector.php index 58cc304ac4..36c82c5a27 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests/rector.php @@ -1,4 +1,4 @@ -@@ -37,7 +37,6 @@ +@@ -36,7 +36,6 @@ use Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector; use Rector\Php81\Rector\Array_\ArrayToFirstClassCallableRector; use Rector\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector; @@ -6,20 +6,20 @@ use Rector\Privatization\Rector\ClassConst\PrivatizeFinalClassConstantRector; use Rector\Privatization\Rector\ClassMethod\PrivatizeFinalClassMethodRector; use Rector\Privatization\Rector\MethodCall\PrivatizeLocalGetterToPropertyRector; -@@ -87,8 +86,6 @@ - // PHP version upgrade sets - modernizes syntax to PHP 8.4. - // Includes all rules from PHP 5.3 through 8.4. - ->withPhpSets(php84: TRUE) +@@ -86,8 +85,6 @@ + // PHP version upgrade sets. Called without an argument, the target version + // comes from `composer.json`, so the sets follow the project's PHP version. + ->withPhpSets() - // Behat attribute sets - converts annotations to PHP 8 attributes. - ->withAttributesSets(behat: TRUE) // Code quality improvement sets. ->withPreparedSets( codeQuality: TRUE, -@@ -108,7 +105,6 @@ +@@ -106,7 +103,6 @@ // Additional rules. ->withRules([ DeclareStrictTypesRector::class, - YieldDataProviderRector::class, ]) - // Configure Drupal autoloading. - ->withAutoloadPaths((function (): array { + // Import configuration. + ->withImportNames(importNames: FALSE, importDocBlockNames: FALSE); diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.circleci/config.yml index 82a632b93d..35fe764101 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -184,10 +189,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -365,6 +375,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.dockerignore index 24012fd267..863172d3c0 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -39,11 +39,7 @@ +@@ -42,11 +42,7 @@ **/.artifacts **/.data **/.logs diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/composer.json index 7c5d2045b8..4ca103152c 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/composer.json @@ -1,20 +1,16 @@ -@@ -38,15 +38,9 @@ - "webflo/drupal-finder": "__VERSION__" +@@ -38,22 +38,15 @@ + "drush/drush": "__VERSION__" }, "require-dev": { - "behat/behat": "__VERSION__", - "dantleech/gherkin-lint": "__VERSION__", - "dealerdirect/phpcodesniffer-composer-installer": "__VERSION__", -- "drevops/behat-format-progress-fail": "__VERSION__", - "drevops/behat-screenshot": "__VERSION__", - "drevops/behat-steps": "__VERSION__", "drevops/phpcs-standard": "__VERSION__", "drupal/coder": "__VERSION__", - "drupal/drupal-extension": "__VERSION__", "ergebnis/composer-normalize": "__VERSION__", - "lullabot/mink-selenium2-driver": "__VERSION__", - "lullabot/php-webdriver": "__VERSION__", -@@ -54,10 +48,8 @@ + "mglaman/phpstan-drupal": "__VERSION__", "mikey179/vfsstream": "__VERSION__", "palantirnet/drupal-rector": "__VERSION__", "phpcompatibility/php-compatibility": "__VERSION__", @@ -23,9 +19,9 @@ "phpstan/phpstan": "__VERSION__", - "phpunit/phpunit": "__VERSION__", "pyrech/composer-changelogs": "__VERSION__", - "rector/rector": "__VERSION__", "softcreatr/jsonpath": "^0.10 || ^1.0", -@@ -74,11 +66,6 @@ + "vincentlanglet/twig-cs-fixer": "__VERSION__" +@@ -69,11 +62,6 @@ ], "minimum-stability": "stable", "prefer-stable": true, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/rector.php b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/rector.php index 58cc304ac4..36c82c5a27 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/rector.php @@ -1,4 +1,4 @@ -@@ -37,7 +37,6 @@ +@@ -36,7 +36,6 @@ use Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector; use Rector\Php81\Rector\Array_\ArrayToFirstClassCallableRector; use Rector\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector; @@ -6,20 +6,20 @@ use Rector\Privatization\Rector\ClassConst\PrivatizeFinalClassConstantRector; use Rector\Privatization\Rector\ClassMethod\PrivatizeFinalClassMethodRector; use Rector\Privatization\Rector\MethodCall\PrivatizeLocalGetterToPropertyRector; -@@ -87,8 +86,6 @@ - // PHP version upgrade sets - modernizes syntax to PHP 8.4. - // Includes all rules from PHP 5.3 through 8.4. - ->withPhpSets(php84: TRUE) +@@ -86,8 +85,6 @@ + // PHP version upgrade sets. Called without an argument, the target version + // comes from `composer.json`, so the sets follow the project's PHP version. + ->withPhpSets() - // Behat attribute sets - converts annotations to PHP 8 attributes. - ->withAttributesSets(behat: TRUE) // Code quality improvement sets. ->withPreparedSets( codeQuality: TRUE, -@@ -108,7 +105,6 @@ +@@ -106,7 +103,6 @@ // Additional rules. ->withRules([ DeclareStrictTypesRector::class, - YieldDataProviderRector::class, ]) - // Configure Drupal autoloading. - ->withAutoloadPaths((function (): array { + // Import configuration. + ->withImportNames(importNames: FALSE, importDocBlockNames: FALSE); diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.circleci/config.yml index 5b97ab3cd4..ee87a84d8f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -177,10 +182,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -409,6 +419,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme/.docker/cli.dockerfile b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme/.docker/cli.dockerfile index 573ef6b35d..870dcccc9d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme/.docker/cli.dockerfile +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme/.docker/cli.dockerfile @@ -7,7 +7,7 @@ ENV DRUPAL_THEME=${DRUPAL_THEME} ARG VORTEX_FRONTEND_BUILD_SKIP="0" -@@ -94,13 +94,5 @@ +@@ -95,13 +95,5 @@ # Create file directories and set correct permissions. # hadolint ignore=SC2174 # only the leaf directory needs the mode RUN mkdir -p -m 2775 "/app/${WEBROOT}/${DRUPAL_PUBLIC_FILES}" "/app/${WEBROOT}/${DRUPAL_PRIVATE_FILES}" "${DRUPAL_TEMPORARY_FILES}" diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme/rector.php b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme/rector.php index 2d3912fefc..be61deb99e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme/rector.php @@ -1,4 +1,4 @@ -@@ -48,7 +48,6 @@ +@@ -47,7 +47,6 @@ return RectorConfig::configure() ->withPaths([ __DIR__ . '/web/modules/custom', diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.circleci/config.yml index fbe4970945..872c0c51d6 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -177,10 +182,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -396,6 +406,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.docker/cli.dockerfile b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.docker/cli.dockerfile index 573ef6b35d..870dcccc9d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.docker/cli.dockerfile +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.docker/cli.dockerfile @@ -7,7 +7,7 @@ ENV DRUPAL_THEME=${DRUPAL_THEME} ARG VORTEX_FRONTEND_BUILD_SKIP="0" -@@ -94,13 +94,5 @@ +@@ -95,13 +95,5 @@ # Create file directories and set correct permissions. # hadolint ignore=SC2174 # only the leaf directory needs the mode RUN mkdir -p -m 2775 "/app/${WEBROOT}/${DRUPAL_PUBLIC_FILES}" "/app/${WEBROOT}/${DRUPAL_PRIVATE_FILES}" "${DRUPAL_TEMPORARY_FILES}" diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/rector.php b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/rector.php index 2d3912fefc..be61deb99e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/rector.php @@ -1,4 +1,4 @@ -@@ -48,7 +48,6 @@ +@@ -47,7 +47,6 @@ return RectorConfig::configure() ->withPaths([ __DIR__ . '/web/modules/custom', diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat/composer.json index a3b7b1e265..06ac39f951 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat/composer.json @@ -1,16 +1,14 @@ -@@ -38,15 +38,9 @@ - "webflo/drupal-finder": "__VERSION__" +@@ -38,13 +38,8 @@ + "drush/drush": "__VERSION__" }, "require-dev": { - "behat/behat": "__VERSION__", - "dantleech/gherkin-lint": "__VERSION__", - "dealerdirect/phpcodesniffer-composer-installer": "__VERSION__", -- "drevops/behat-format-progress-fail": "__VERSION__", - "drevops/behat-screenshot": "__VERSION__", - "drevops/behat-steps": "__VERSION__", "drevops/phpcs-standard": "__VERSION__", "drupal/coder": "__VERSION__", - "drupal/drupal-extension": "__VERSION__", "ergebnis/composer-normalize": "__VERSION__", - "lullabot/mink-selenium2-driver": "__VERSION__", - "lullabot/php-webdriver": "__VERSION__", + "mglaman/phpstan-drupal": "__VERSION__", + "mikey179/vfsstream": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat/rector.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat/rector.php index cefd5a83df..d5ff61e947 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat/rector.php @@ -1,7 +1,7 @@ -@@ -87,8 +87,6 @@ - // PHP version upgrade sets - modernizes syntax to PHP 8.4. - // Includes all rules from PHP 5.3 through 8.4. - ->withPhpSets(php84: TRUE) +@@ -86,8 +86,6 @@ + // PHP version upgrade sets. Called without an argument, the target version + // comes from `composer.json`, so the sets follow the project's PHP version. + ->withPhpSets() - // Behat attribute sets - converts annotations to PHP 8 attributes. - ->withAttributesSets(behat: TRUE) // Code quality improvement sets. diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/.circleci/config.yml index 7574fbb61c..bdc2027a29 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -184,10 +189,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -406,6 +416,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/composer.json index a3b7b1e265..06ac39f951 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/composer.json @@ -1,16 +1,14 @@ -@@ -38,15 +38,9 @@ - "webflo/drupal-finder": "__VERSION__" +@@ -38,13 +38,8 @@ + "drush/drush": "__VERSION__" }, "require-dev": { - "behat/behat": "__VERSION__", - "dantleech/gherkin-lint": "__VERSION__", - "dealerdirect/phpcodesniffer-composer-installer": "__VERSION__", -- "drevops/behat-format-progress-fail": "__VERSION__", - "drevops/behat-screenshot": "__VERSION__", - "drevops/behat-steps": "__VERSION__", "drevops/phpcs-standard": "__VERSION__", "drupal/coder": "__VERSION__", - "drupal/drupal-extension": "__VERSION__", "ergebnis/composer-normalize": "__VERSION__", - "lullabot/mink-selenium2-driver": "__VERSION__", - "lullabot/php-webdriver": "__VERSION__", + "mglaman/phpstan-drupal": "__VERSION__", + "mikey179/vfsstream": "__VERSION__", diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/rector.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/rector.php index cefd5a83df..d5ff61e947 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/rector.php @@ -1,7 +1,7 @@ -@@ -87,8 +87,6 @@ - // PHP version upgrade sets - modernizes syntax to PHP 8.4. - // Includes all rules from PHP 5.3 through 8.4. - ->withPhpSets(php84: TRUE) +@@ -86,8 +86,6 @@ + // PHP version upgrade sets. Called without an argument, the target version + // comes from `composer.json`, so the sets follow the project's PHP version. + ->withPhpSets() - // Behat attribute sets - converts annotations to PHP 8 attributes. - ->withAttributesSets(behat: TRUE) // Code quality improvement sets. diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_behat_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_dclint_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_dclint_circleci/.circleci/config.yml index 54ec866461..c9255704e0 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_dclint_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_dclint_circleci/.circleci/config.yml @@ -184,10 +184,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -424,6 +429,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_dclint_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_dclint_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_dclint_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_dclint_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_dclint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_dclint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_dclint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_dclint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.circleci/config.yml index 69241f3714..51ebf3f335 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.circleci/config.yml @@ -177,10 +177,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -417,6 +422,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_circleci/.circleci/config.yml index 908c0584df..e52c69280a 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -177,10 +182,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -417,6 +427,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_no_theme/.docker/cli.dockerfile b/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_no_theme/.docker/cli.dockerfile index 573ef6b35d..870dcccc9d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_no_theme/.docker/cli.dockerfile +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_no_theme/.docker/cli.dockerfile @@ -7,7 +7,7 @@ ENV DRUPAL_THEME=${DRUPAL_THEME} ARG VORTEX_FRONTEND_BUILD_SKIP="0" -@@ -94,13 +94,5 @@ +@@ -95,13 +95,5 @@ # Create file directories and set correct permissions. # hadolint ignore=SC2174 # only the leaf directory needs the mode RUN mkdir -p -m 2775 "/app/${WEBROOT}/${DRUPAL_PUBLIC_FILES}" "/app/${WEBROOT}/${DRUPAL_PRIVATE_FILES}" "${DRUPAL_TEMPORARY_FILES}" diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_no_theme/rector.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_no_theme/rector.php index 2d3912fefc..be61deb99e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_no_theme/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_eslint_no_theme/rector.php @@ -1,4 +1,4 @@ -@@ -48,7 +48,6 @@ +@@ -47,7 +47,6 @@ return RectorConfig::configure() ->withPaths([ __DIR__ . '/web/modules/custom', diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.circleci/config.yml index 1333e53b05..66f783c8ce 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.circleci/config.yml @@ -118,9 +118,14 @@ jobs: name: Login to container registry command: ./vendor/bin/vortex-login-container-registry + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -181,10 +186,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -421,6 +431,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_hadolint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_hadolint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_hadolint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_hadolint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_jest_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_jest_circleci/.circleci/config.yml index bc01a31f2f..f3e719607d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_jest_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_jest_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -188,10 +193,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -420,6 +430,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_jest_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_jest_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_jest_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_jest_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_jest_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_jest_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_jest_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_jest_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs/composer.json index a4a41875da..39fce487f9 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs/composer.json @@ -1,17 +1,11 @@ -@@ -40,12 +40,9 @@ - "require-dev": { - "behat/behat": "__VERSION__", +@@ -42,14 +42,11 @@ "dantleech/gherkin-lint": "__VERSION__", -- "dealerdirect/phpcodesniffer-composer-installer": "__VERSION__", - "drevops/behat-format-progress-fail": "__VERSION__", "drevops/behat-screenshot": "__VERSION__", "drevops/behat-steps": "__VERSION__", - "drevops/phpcs-standard": "__VERSION__", - "drupal/coder": "__VERSION__", "drupal/drupal-extension": "__VERSION__", "ergebnis/composer-normalize": "__VERSION__", - "lullabot/mink-selenium2-driver": "__VERSION__", -@@ -53,7 +50,6 @@ "mglaman/phpstan-drupal": "__VERSION__", "mikey179/vfsstream": "__VERSION__", "palantirnet/drupal-rector": "__VERSION__", @@ -19,7 +13,7 @@ "phpspec/prophecy-phpunit": "__VERSION__", "phpstan/extension-installer": "__VERSION__", "phpstan/phpstan": "__VERSION__", -@@ -83,7 +79,6 @@ +@@ -78,7 +75,6 @@ "allow-plugins": { "composer/installers": true, "cweagans/composer-patches": true, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.circleci/config.yml index 8c66b4dec0..6bfa896575 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -184,10 +189,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -424,6 +434,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/composer.json index a4a41875da..39fce487f9 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/composer.json @@ -1,17 +1,11 @@ -@@ -40,12 +40,9 @@ - "require-dev": { - "behat/behat": "__VERSION__", +@@ -42,14 +42,11 @@ "dantleech/gherkin-lint": "__VERSION__", -- "dealerdirect/phpcodesniffer-composer-installer": "__VERSION__", - "drevops/behat-format-progress-fail": "__VERSION__", "drevops/behat-screenshot": "__VERSION__", "drevops/behat-steps": "__VERSION__", - "drevops/phpcs-standard": "__VERSION__", - "drupal/coder": "__VERSION__", "drupal/drupal-extension": "__VERSION__", "ergebnis/composer-normalize": "__VERSION__", - "lullabot/mink-selenium2-driver": "__VERSION__", -@@ -53,7 +50,6 @@ "mglaman/phpstan-drupal": "__VERSION__", "mikey179/vfsstream": "__VERSION__", "palantirnet/drupal-rector": "__VERSION__", @@ -19,7 +13,7 @@ "phpspec/prophecy-phpunit": "__VERSION__", "phpstan/extension-installer": "__VERSION__", "phpstan/phpstan": "__VERSION__", -@@ -83,7 +79,6 @@ +@@ -78,7 +75,6 @@ "allow-plugins": { "composer/installers": true, "cweagans/composer-patches": true, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 8f47fef2dc..1babe66629 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpcs_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -9,7 +9,7 @@ */ #[Group('drupal_settings')] class EnvironmentSettingsTest extends SettingsTestCase { -@@ -332,9 +328,9 @@ +@@ -388,9 +384,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan/composer.json index b0295c969a..f9dccd2494 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan/composer.json @@ -1,7 +1,7 @@ -@@ -50,13 +50,10 @@ +@@ -46,13 +46,10 @@ + "drupal/coder": "__VERSION__", + "drupal/drupal-extension": "__VERSION__", "ergebnis/composer-normalize": "__VERSION__", - "lullabot/mink-selenium2-driver": "__VERSION__", - "lullabot/php-webdriver": "__VERSION__", - "mglaman/phpstan-drupal": "__VERSION__", "mikey179/vfsstream": "__VERSION__", "palantirnet/drupal-rector": "__VERSION__", @@ -11,8 +11,8 @@ - "phpstan/phpstan": "__VERSION__", "phpunit/phpunit": "__VERSION__", "pyrech/composer-changelogs": "__VERSION__", - "rector/rector": "__VERSION__", -@@ -87,7 +84,6 @@ + "softcreatr/jsonpath": "^0.10 || ^1.0", +@@ -82,7 +79,6 @@ "drupal/core-composer-scaffold": true, "ergebnis/composer-normalize": true, "php-http/discovery": true, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan/web/sites/default/includes/modules/settings.fast404.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan/web/sites/default/includes/modules/settings.fast404.php deleted file mode 100644 index 74b826db06..0000000000 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan/web/sites/default/includes/modules/settings.fast404.php +++ /dev/null @@ -1,8 +0,0 @@ -@@ -22,7 +22,6 @@ - $settings['fast404_string_whitelisting'] = ['/advagg_']; - $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; - include_once $contrib_path . '/fast404/fast404.inc'; -- // @phpstan-ignore-next-line - fast404_preboot($settings); - // @codeCoverageIgnoreEnd - } diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan/web/sites/default/includes/modules/settings.fast_404.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan/web/sites/default/includes/modules/settings.fast_404.php new file mode 100644 index 0000000000..f9c4ae6d15 --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan/web/sites/default/includes/modules/settings.fast_404.php @@ -0,0 +1,7 @@ +@@ -56,6 +56,5 @@ + // the module passes an array where an exception is expected. Patch it with + // https://www.drupal.org/files/issues/2023-08-24/fast_404_3x-3194034-10.patch + // @see https://www.drupal.org/project/fast_404/issues/3194034 +- // @phpstan-ignore-next-line + fast404_preboot($settings); + } diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.circleci/config.yml index bd2832283b..57d364a7fb 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -184,10 +189,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -424,6 +434,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/composer.json index b0295c969a..f9dccd2494 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/composer.json @@ -1,7 +1,7 @@ -@@ -50,13 +50,10 @@ +@@ -46,13 +46,10 @@ + "drupal/coder": "__VERSION__", + "drupal/drupal-extension": "__VERSION__", "ergebnis/composer-normalize": "__VERSION__", - "lullabot/mink-selenium2-driver": "__VERSION__", - "lullabot/php-webdriver": "__VERSION__", - "mglaman/phpstan-drupal": "__VERSION__", "mikey179/vfsstream": "__VERSION__", "palantirnet/drupal-rector": "__VERSION__", @@ -11,8 +11,8 @@ - "phpstan/phpstan": "__VERSION__", "phpunit/phpunit": "__VERSION__", "pyrech/composer-changelogs": "__VERSION__", - "rector/rector": "__VERSION__", -@@ -87,7 +84,6 @@ + "softcreatr/jsonpath": "^0.10 || ^1.0", +@@ -82,7 +79,6 @@ "drupal/core-composer-scaffold": true, "ergebnis/composer-normalize": true, "php-http/discovery": true, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/web/sites/default/includes/modules/settings.fast404.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/web/sites/default/includes/modules/settings.fast404.php deleted file mode 100644 index 74b826db06..0000000000 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/web/sites/default/includes/modules/settings.fast404.php +++ /dev/null @@ -1,8 +0,0 @@ -@@ -22,7 +22,6 @@ - $settings['fast404_string_whitelisting'] = ['/advagg_']; - $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; - include_once $contrib_path . '/fast404/fast404.inc'; -- // @phpstan-ignore-next-line - fast404_preboot($settings); - // @codeCoverageIgnoreEnd - } diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/web/sites/default/includes/modules/settings.fast_404.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/web/sites/default/includes/modules/settings.fast_404.php new file mode 100644 index 0000000000..f9c4ae6d15 --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpstan_circleci/web/sites/default/includes/modules/settings.fast_404.php @@ -0,0 +1,7 @@ +@@ -56,6 +56,5 @@ + // the module passes an array where an exception is expected. Patch it with + // https://www.drupal.org/files/issues/2023-08-24/fast_404_3x-3194034-10.patch + // @see https://www.drupal.org/project/fast_404/issues/3194034 +- // @phpstan-ignore-next-line + fast404_preboot($settings); + } diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/.dockerignore index 978d823173..65d1dcd4f7 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/.dockerignore @@ -1,4 +1,4 @@ -@@ -39,7 +39,6 @@ +@@ -42,7 +42,6 @@ **/.artifacts **/.data **/.logs diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/.github/workflows/build-test-deploy.yml index 8ada07b194..55075e1fe3 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/.github/workflows/build-test-deploy.yml @@ -88,5 +88,5 @@ - files: | - .logs/test_results/**/*.xml - - name: Setup tmate session - if: ${{ !cancelled() && github.event.inputs.enable_terminal }} + # Placed after the test steps so a dirty tree never suppresses them. + - name: Check that the build left a clean working tree diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/composer.json index 6d922172e8..43d26b85fe 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/composer.json @@ -1,4 +1,4 @@ -@@ -54,10 +54,8 @@ +@@ -50,10 +50,8 @@ "mikey179/vfsstream": "__VERSION__", "palantirnet/drupal-rector": "__VERSION__", "phpcompatibility/php-compatibility": "__VERSION__", @@ -7,9 +7,9 @@ "phpstan/phpstan": "__VERSION__", - "phpunit/phpunit": "__VERSION__", "pyrech/composer-changelogs": "__VERSION__", - "rector/rector": "__VERSION__", "softcreatr/jsonpath": "^0.10 || ^1.0", -@@ -74,11 +72,6 @@ + "vincentlanglet/twig-cs-fixer": "__VERSION__" +@@ -69,11 +67,6 @@ ], "minimum-stability": "stable", "prefer-stable": true, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/rector.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/rector.php index f4c6993b28..6b17bb244f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit/rector.php @@ -1,4 +1,4 @@ -@@ -37,7 +37,6 @@ +@@ -36,7 +36,6 @@ use Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector; use Rector\Php81\Rector\Array_\ArrayToFirstClassCallableRector; use Rector\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector; @@ -6,11 +6,11 @@ use Rector\Privatization\Rector\ClassConst\PrivatizeFinalClassConstantRector; use Rector\Privatization\Rector\ClassMethod\PrivatizeFinalClassMethodRector; use Rector\Privatization\Rector\MethodCall\PrivatizeLocalGetterToPropertyRector; -@@ -108,7 +107,6 @@ +@@ -106,7 +105,6 @@ // Additional rules. ->withRules([ DeclareStrictTypesRector::class, - YieldDataProviderRector::class, ]) - // Configure Drupal autoloading. - ->withAutoloadPaths((function (): array { + // Import configuration. + ->withImportNames(importNames: FALSE, importDocBlockNames: FALSE); diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.circleci/config.yml index b4a49a9399..18d12fb243 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -188,10 +193,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -387,6 +397,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.dockerignore index 24012fd267..863172d3c0 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -39,11 +39,7 @@ +@@ -42,11 +42,7 @@ **/.artifacts **/.data **/.logs diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/composer.json index 6d922172e8..43d26b85fe 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/composer.json @@ -1,4 +1,4 @@ -@@ -54,10 +54,8 @@ +@@ -50,10 +50,8 @@ "mikey179/vfsstream": "__VERSION__", "palantirnet/drupal-rector": "__VERSION__", "phpcompatibility/php-compatibility": "__VERSION__", @@ -7,9 +7,9 @@ "phpstan/phpstan": "__VERSION__", - "phpunit/phpunit": "__VERSION__", "pyrech/composer-changelogs": "__VERSION__", - "rector/rector": "__VERSION__", "softcreatr/jsonpath": "^0.10 || ^1.0", -@@ -74,11 +72,6 @@ + "vincentlanglet/twig-cs-fixer": "__VERSION__" +@@ -69,11 +67,6 @@ ], "minimum-stability": "stable", "prefer-stable": true, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/rector.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/rector.php index f4c6993b28..6b17bb244f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_phpunit_circleci/rector.php @@ -1,4 +1,4 @@ -@@ -37,7 +37,6 @@ +@@ -36,7 +36,6 @@ use Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector; use Rector\Php81\Rector\Array_\ArrayToFirstClassCallableRector; use Rector\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector; @@ -6,11 +6,11 @@ use Rector\Privatization\Rector\ClassConst\PrivatizeFinalClassConstantRector; use Rector\Privatization\Rector\ClassMethod\PrivatizeFinalClassMethodRector; use Rector\Privatization\Rector\MethodCall\PrivatizeLocalGetterToPropertyRector; -@@ -108,7 +107,6 @@ +@@ -106,7 +105,6 @@ // Additional rules. ->withRules([ DeclareStrictTypesRector::class, - YieldDataProviderRector::class, ]) - // Configure Drupal autoloading. - ->withAutoloadPaths((function (): array { + // Import configuration. + ->withImportNames(importNames: FALSE, importDocBlockNames: FALSE); diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector/composer.json index dc290842a1..b0b5c2bd56 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector/composer.json @@ -1,16 +1,8 @@ -@@ -52,7 +52,6 @@ - "lullabot/php-webdriver": "__VERSION__", +@@ -48,7 +48,6 @@ + "ergebnis/composer-normalize": "__VERSION__", "mglaman/phpstan-drupal": "__VERSION__", "mikey179/vfsstream": "__VERSION__", - "palantirnet/drupal-rector": "__VERSION__", "phpcompatibility/php-compatibility": "__VERSION__", "phpspec/prophecy-phpunit": "__VERSION__", "phpstan/extension-installer": "__VERSION__", -@@ -59,7 +58,6 @@ - "phpstan/phpstan": "__VERSION__", - "phpunit/phpunit": "__VERSION__", - "pyrech/composer-changelogs": "__VERSION__", -- "rector/rector": "__VERSION__", - "softcreatr/jsonpath": "^0.10 || ^1.0", - "vincentlanglet/twig-cs-fixer": "__VERSION__" - }, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/.circleci/config.yml index 8780bddd36..dbaa9655bd 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -184,10 +189,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -424,6 +434,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/composer.json index dc290842a1..b0b5c2bd56 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/composer.json @@ -1,16 +1,8 @@ -@@ -52,7 +52,6 @@ - "lullabot/php-webdriver": "__VERSION__", +@@ -48,7 +48,6 @@ + "ergebnis/composer-normalize": "__VERSION__", "mglaman/phpstan-drupal": "__VERSION__", "mikey179/vfsstream": "__VERSION__", - "palantirnet/drupal-rector": "__VERSION__", "phpcompatibility/php-compatibility": "__VERSION__", "phpspec/prophecy-phpunit": "__VERSION__", "phpstan/extension-installer": "__VERSION__", -@@ -59,7 +58,6 @@ - "phpstan/phpstan": "__VERSION__", - "phpunit/phpunit": "__VERSION__", - "pyrech/composer-changelogs": "__VERSION__", -- "rector/rector": "__VERSION__", - "softcreatr/jsonpath": "^0.10 || ^1.0", - "vincentlanglet/twig-cs-fixer": "__VERSION__" - }, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_rector_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.circleci/config.yml index 4acc6eb0fc..3029359759 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -188,10 +193,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -428,6 +438,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.dockerignore index e0fa230b82..56497d2e80 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -42,9 +42,6 @@ +@@ -45,9 +45,6 @@ **/.phpunit.cache **/.twig-cs-fixer.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_no_theme/.docker/cli.dockerfile b/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_no_theme/.docker/cli.dockerfile index 573ef6b35d..870dcccc9d 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_no_theme/.docker/cli.dockerfile +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_no_theme/.docker/cli.dockerfile @@ -7,7 +7,7 @@ ENV DRUPAL_THEME=${DRUPAL_THEME} ARG VORTEX_FRONTEND_BUILD_SKIP="0" -@@ -94,13 +94,5 @@ +@@ -95,13 +95,5 @@ # Create file directories and set correct permissions. # hadolint ignore=SC2174 # only the leaf directory needs the mode RUN mkdir -p -m 2775 "/app/${WEBROOT}/${DRUPAL_PUBLIC_FILES}" "/app/${WEBROOT}/${DRUPAL_PRIVATE_FILES}" "${DRUPAL_TEMPORARY_FILES}" diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_no_theme/rector.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_no_theme/rector.php index 2d3912fefc..be61deb99e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_no_theme/rector.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_stylelint_no_theme/rector.php @@ -1,4 +1,4 @@ -@@ -48,7 +48,6 @@ +@@ -47,7 +47,6 @@ return RectorConfig::configure() ->withPaths([ __DIR__ . '/web/modules/custom', diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig/.dockerignore index ccae92dfb7..19b4091ee3 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig/.dockerignore @@ -1,4 +1,4 @@ -@@ -40,7 +40,6 @@ +@@ -43,7 +43,6 @@ **/.data **/.logs **/.phpunit.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig/composer.json index c049863d83..61e6b652f1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig/composer.json @@ -1,7 +1,7 @@ -@@ -60,8 +60,7 @@ +@@ -55,8 +55,7 @@ + "phpstan/phpstan": "__VERSION__", "phpunit/phpunit": "__VERSION__", "pyrech/composer-changelogs": "__VERSION__", - "rector/rector": "__VERSION__", - "softcreatr/jsonpath": "^0.10 || ^1.0", - "vincentlanglet/twig-cs-fixer": "__VERSION__" + "softcreatr/jsonpath": "^0.10 || ^1.0" diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/.circleci/config.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/.circleci/config.yml index 0521c41e9b..e6868ed95a 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/.circleci/config.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/.circleci/config.yml @@ -125,9 +125,14 @@ jobs: echo "Linting ${file}" && cat "${file}" | docker run --rm -i hadolint/hadolint:__VERSION__ || [ "${VORTEX_CI_HADOLINT_IGNORE_FAILURE:-0}" -eq 1 ] done + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Lint Docker Compose files with DCLint - command: docker run --rm -v "${PWD}":/app zavoloklom/dclint:__VERSION__ . || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm zavoloklom/dclint:__VERSION__ .)" + docker cp ./. "${container}:/app" + docker start --attach "${container}" || [ "${VORTEX_CI_DCLINT_IGNORE_FAILURE:-0}" -eq 1 ] - run: name: Build stack @@ -184,10 +189,15 @@ jobs: name: Audit Composer packages command: composer audit --locked || [ "${VORTEX_CI_COMPOSER_AUDIT_IGNORE_FAILURE:-0}" -eq 1 ] + # The remote Docker engine has no access to the checkout, so the files + # are copied into the container. - run: name: Scan for committed secrets with Gitleaks when: always - command: docker run --rm -v "${PWD}":/repo -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] + command: | + container="$(docker create --rm -w /repo ghcr.io/gitleaks/gitleaks:__VERSION__ dir . --no-banner)" + docker cp ./. "${container}:/repo" + docker start --attach "${container}" || [ "${VORTEX_CI_GITLEAKS_IGNORE_FAILURE:-0}" -eq 1 ] # Test the provisioned site. Runs in parallel with the lint and build jobs. # Provisioning and testing happen within the same job to save time on @@ -424,6 +434,11 @@ jobs: - store_artifacts: path: *artifacts + # Placed after the test steps so a dirty tree never suppresses them. + - run: + name: Check that the build left a clean working tree + command: ./vendor/bin/vortex-check-worktree-changes || [ "${VORTEX_CI_WORKTREE_CHANGES_IGNORE_FAILURE:-0}" -eq 1 ] + # Build the deployable in parallel with the lint and test jobs. For artifact # deployments, it exports the built codebase for the deploy job; for # image-based hosting, a successful build validates that the production images diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/.dockerignore index 91caaf5401..cec6b01cb5 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/.dockerignore @@ -1,4 +1,4 @@ -@@ -40,10 +40,6 @@ +@@ -43,10 +43,6 @@ **/.data **/.logs **/.phpunit.cache diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/composer.json index c049863d83..61e6b652f1 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/composer.json @@ -1,7 +1,7 @@ -@@ -60,8 +60,7 @@ +@@ -55,8 +55,7 @@ + "phpstan/phpstan": "__VERSION__", "phpunit/phpunit": "__VERSION__", "pyrech/composer-changelogs": "__VERSION__", - "rector/rector": "__VERSION__", - "softcreatr/jsonpath": "^0.10 || ^1.0", - "vincentlanglet/twig-cs-fixer": "__VERSION__" + "softcreatr/jsonpath": "^0.10 || ^1.0" diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php index aa01270496..98c10f5602 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_no_twig_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,4 +1,4 @@ -@@ -332,9 +332,9 @@ +@@ -388,9 +388,9 @@ } /** diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_none/.dockerignore b/.vortex/cli/tests/Fixtures/handler_process/tools_none/.dockerignore index aa8e7069e8..41dc02d87e 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_none/.dockerignore +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_none/.dockerignore @@ -1,4 +1,4 @@ -@@ -39,8 +39,6 @@ +@@ -42,8 +42,6 @@ **/.artifacts **/.data **/.logs diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_none/.github/workflows/build-test-deploy.yml b/.vortex/cli/tests/Fixtures/handler_process/tools_none/.github/workflows/build-test-deploy.yml index 716b80a76f..9bb83976bc 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_none/.github/workflows/build-test-deploy.yml +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_none/.github/workflows/build-test-deploy.yml @@ -189,5 +189,5 @@ - files: | - .logs/test_results/**/*.xml - - name: Setup tmate session - if: ${{ !cancelled() && github.event.inputs.enable_terminal }} + # Placed after the test steps so a dirty tree never suppresses them. + - name: Check that the build left a clean working tree diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_none/composer.json b/.vortex/cli/tests/Fixtures/handler_process/tools_none/composer.json index dd3b4bce9e..4f6bb8c93b 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_none/composer.json +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_none/composer.json @@ -1,19 +1,15 @@ -@@ -38,30 +38,12 @@ - "webflo/drupal-finder": "__VERSION__" +@@ -38,25 +38,10 @@ + "drush/drush": "__VERSION__" }, "require-dev": { - "behat/behat": "__VERSION__", - "dantleech/gherkin-lint": "__VERSION__", -- "dealerdirect/phpcodesniffer-composer-installer": "__VERSION__", -- "drevops/behat-format-progress-fail": "__VERSION__", - "drevops/behat-screenshot": "__VERSION__", - "drevops/behat-steps": "__VERSION__", - "drevops/phpcs-standard": "__VERSION__", - "drupal/coder": "__VERSION__", - "drupal/drupal-extension": "__VERSION__", "ergebnis/composer-normalize": "__VERSION__", - "lullabot/mink-selenium2-driver": "__VERSION__", - "lullabot/php-webdriver": "__VERSION__", - "mglaman/phpstan-drupal": "__VERSION__", "mikey179/vfsstream": "__VERSION__", - "palantirnet/drupal-rector": "__VERSION__", @@ -23,14 +19,13 @@ - "phpstan/phpstan": "__VERSION__", - "phpunit/phpunit": "__VERSION__", "pyrech/composer-changelogs": "__VERSION__", -- "rector/rector": "__VERSION__", - "softcreatr/jsonpath": "^0.10 || ^1.0", - "vincentlanglet/twig-cs-fixer": "__VERSION__" + "softcreatr/jsonpath": "^0.10 || ^1.0" }, "conflict": { "drupal/drupal": "*" -@@ -74,20 +56,13 @@ +@@ -69,20 +54,13 @@ ], "minimum-stability": "stable", "prefer-stable": true, diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_none/web/sites/default/includes/modules/settings.fast404.php b/.vortex/cli/tests/Fixtures/handler_process/tools_none/web/sites/default/includes/modules/settings.fast404.php deleted file mode 100644 index 74b826db06..0000000000 --- a/.vortex/cli/tests/Fixtures/handler_process/tools_none/web/sites/default/includes/modules/settings.fast404.php +++ /dev/null @@ -1,8 +0,0 @@ -@@ -22,7 +22,6 @@ - $settings['fast404_string_whitelisting'] = ['/advagg_']; - $settings['fast404_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; - include_once $contrib_path . '/fast404/fast404.inc'; -- // @phpstan-ignore-next-line - fast404_preboot($settings); - // @codeCoverageIgnoreEnd - } diff --git a/.vortex/cli/tests/Fixtures/handler_process/tools_none/web/sites/default/includes/modules/settings.fast_404.php b/.vortex/cli/tests/Fixtures/handler_process/tools_none/web/sites/default/includes/modules/settings.fast_404.php new file mode 100644 index 0000000000..f9c4ae6d15 --- /dev/null +++ b/.vortex/cli/tests/Fixtures/handler_process/tools_none/web/sites/default/includes/modules/settings.fast_404.php @@ -0,0 +1,7 @@ +@@ -56,6 +56,5 @@ + // the module passes an array where an exception is expected. Patch it with + // https://www.drupal.org/files/issues/2023-08-24/fast_404_3x-3194034-10.patch + // @see https://www.drupal.org/project/fast_404/issues/3194034 +- // @phpstan-ignore-next-line + fast404_preboot($settings); + } diff --git a/.vortex/cli/tests/Fixtures/handler_process/version_scheme_other/.env b/.vortex/cli/tests/Fixtures/handler_process/version_scheme_other/.env index 7f0958f876..34e512768f 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/version_scheme_other/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/version_scheme_other/.env @@ -1,4 +1,4 @@ -@@ -179,7 +179,7 @@ +@@ -185,7 +185,7 @@ # # Can be one of: calver, semver, other # @see https://www.vortextemplate.com/docs/releasing diff --git a/.vortex/cli/tests/Fixtures/handler_process/version_scheme_semver/.env b/.vortex/cli/tests/Fixtures/handler_process/version_scheme_semver/.env index 94bd93bd56..84827d1607 100644 --- a/.vortex/cli/tests/Fixtures/handler_process/version_scheme_semver/.env +++ b/.vortex/cli/tests/Fixtures/handler_process/version_scheme_semver/.env @@ -1,4 +1,4 @@ -@@ -179,7 +179,7 @@ +@@ -185,7 +185,7 @@ # # Can be one of: calver, semver, other # @see https://www.vortextemplate.com/docs/releasing