diff --git a/.circleci/config.yml b/.circleci/config.yml index 0a5ac6706c..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. @@ -561,6 +571,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/update-dependencies.yml b/.circleci/update-dependencies.yml index 8bea21f03f..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:40.36.8 + - image: renovate/renovate:44.176.2 environment: RENOVATE_PLATFORM: 'github' RENOVATE_AUTODISCOVER: false diff --git a/.circleci/vortex-test-common.yml b/.circleci/vortex-test-common.yml index 8bc3c6f2ae..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 @@ -481,9 +486,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/.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/.docker/clamav.dockerfile b/.docker/clamav.dockerfile index d706b5d51a..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.8.1 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 59087b65dc..4cf78f5d70 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.10.0 # Add missing variables. # @todo Remove once https://github.com/uselagoon/lagoon/issues/3121 is resolved. @@ -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/ #;< VORTEX_DEV # Copy the in-tree drevops/vortex-tooling package so the path repository 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/database.dockerfile b/.docker/database.dockerfile index 652ce1bc73..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.8.1 +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 0ed0c8a8e4..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.8.1 +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 3b51c48b36..4b9644a2f6 100644 --- a/.docker/php.dockerfile +++ b/.docker/php.dockerfile @@ -9,9 +9,11 @@ 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.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/.docker/solr.dockerfile b/.docker/solr.dockerfile index a27eae0b6a..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.8.1 +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/.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/.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/.env b/.env index 4ffa8e6158..9c19836bd8 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 @@ -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/.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 45ce63d12a..5b7df80a71 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 @@ -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@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7 if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' && env.CODECOV_TOKEN != '' }} continue-on-error: true with: @@ -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 }} @@ -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 @@ -617,7 +622,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 @@ -651,7 +656,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 @@ -705,7 +710,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 @@ -720,7 +725,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 f0f2958371..d965d22c2d 100644 --- a/.github/workflows/draft-release-notes.yml +++ b/.github/workflows/draft-release-notes.yml @@ -41,8 +41,13 @@ jobs: echo "Version set to ${VERSION}" - name: Draft release notes - uses: release-drafter/release-drafter@34d80673e067bdc0c24568d3af899c216adcfaa9 # v7.7.0 + uses: release-drafter/release-drafter@978bb0b30c5ee8cdd332ced253758157150d43f0 # v7.10.0 with: 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 diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index d7eac08903..e4eaa2e8b8 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -58,16 +58,16 @@ 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 - name: Validate Renovate configuration - uses: suzuki-shunsuke/github-action-renovate-config-validator@ee9f69e1f683ed0d08225086482b34fc9abe9300 # v2.1.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@e09d604f8f803bb527bd8321ed5be06c460b8682 # v46.2.2 + uses: renovatebot/github-action@f0f41e5f2e706165f6814b1d0f0d0e319de7d1d9 # v46.3.8 with: configurationFile: renovate.json token: ${{ secrets.RENOVATE_TOKEN }} diff --git a/.github/workflows/vortex-release.yml b/.github/workflows/vortex-release.yml index ec07ea0f05..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 @@ -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 @@ -163,23 +163,23 @@ 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 - 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 @@ -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 diff --git a/.github/workflows/vortex-test-cli.yml b/.github/workflows/vortex-test-cli.yml index 22de486753..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 @@ -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 @@ -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@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7 continue-on-error: true with: files: .vortex/cli/.logs/cobertura.xml @@ -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 982706b9e1..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 @@ -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@1e1604219a6b38ae9a10aff42a28a3656322c31a # v2.4.1 vortex-test-workflow: runs-on: ubuntu-latest @@ -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 @@ -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 @@ -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@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7 continue-on-error: true with: directory: /tmp/.vortex-coverage-html @@ -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 @@ -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@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 diff --git a/.github/workflows/vortex-test-docs.yml b/.github/workflows/vortex-test-docs.yml index 07bd6fec64..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 @@ -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@eab87c9830c39eff17e5a6eadb20bfb4bc880477 # v27 with: run_id: ${{ github.event.workflow_run.id }} name: ${{ env.BINARY_ARTIFACT }} @@ -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 @@ -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@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 b5f8848479..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 @@ -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 @@ -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@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7 continue-on-error: true with: files: .vortex/tooling/.logs/cobertura.xml 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] 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/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/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/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/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/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 3238007d1b..1d241a9426 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)); @@ -95,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._\/+-]+(?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/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/.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 diff --git a/.vortex/cli/tests/Functional/Command/BuildCommandTest.php b/.vortex/cli/tests/Functional/Command/BuildCommandTest.php index 159ff2345b..1f706cd476 100644 --- a/.vortex/cli/tests/Functional/Command/BuildCommandTest.php +++ b/.vortex/cli/tests/Functional/Command/BuildCommandTest.php @@ -146,7 +146,7 @@ public function testBuildCommand( } /** - * Data provider for testBuildWithMockedRunner. + * Data provider for testBuildCommand. * * @return \Iterator, 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/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/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/.vortex/cli/tests/Functional/Handlers/ModulesHandlerProcessTest.php b/.vortex/cli/tests/Functional/Handlers/ModulesHandlerProcessTest.php index cd84923af9..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'); @@ -79,7 +85,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/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/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/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} */ 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/.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); +} 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/.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/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 diff --git a/.vortex/docs/content/deployment/artifact.mdx b/.vortex/docs/content/deployment/artifact.mdx index 352e20688e..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.7.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/docs/content/development/composer.mdx b/.vortex/docs/content/development/composer.mdx index b0b17b2be5..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) | @@ -572,7 +573,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,26 +586,21 @@ 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) | | [`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) | | [`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/.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..49029a1806 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/). @@ -248,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/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/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 b6d3f07f50..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 @@ -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, 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 [Generated content](https://www.drupal.org/project/generated_content) generates deterministic placeholder content from declarative definitions for development and testing. @@ -153,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 @@ -166,9 +176,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 +191,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:** @@ -198,8 +210,9 @@ 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. +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.
Example of the `Reroute Email` module `settings.reroute_email.php` file @@ -224,7 +237,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 @@ -277,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/provision.mdx b/.vortex/docs/content/development/provision.mdx index 9b231fbef7..cbeac035ac 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 @@ -177,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/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/content/development/settings.mdx b/.vortex/docs/content/development/settings.mdx index 708e3affd1..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'; @@ -373,11 +372,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:** @@ -388,8 +390,9 @@ 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. +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'; @@ -448,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/.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/.vortex/docs/content/development/variables.mdx b/.vortex/docs/content/development/variables.mdx index ee7e937ae4..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 @@ -185,6 +188,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` | @@ -225,6 +229,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` | @@ -244,6 +249,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/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/.vortex/docs/cspell.json b/.vortex/docs/cspell.json index 1964b6de88..352acfba6b 100644 --- a/.vortex/docs/cspell.json +++ b/.vortex/docs/cspell.json @@ -56,6 +56,7 @@ "hadolint", "hotfixes", "htpasswd", + "itok", "jsonpath", "lagooncli", "lando", @@ -72,11 +73,13 @@ "oomphinc", "palantirnet", "pathauto", + "pathspec", "phpcbf", "phpcodesniffer", "phpcompatibility", "phpspec", "phpstorm", + "preboot", "pyrech", "redis", "renovatebot", @@ -96,6 +99,7 @@ "testmode", "toml", "updatedb", + "uploadprogress", "uselagoon", "Valkey", "vfsstream", @@ -104,6 +108,7 @@ "vortextemplate", "webflo", "webroot", + "worktree", "xmlsitemap", "yourorg", "yoursite" 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 94% rename from .claude/skills/prepare-vortex-release/SKILL.md rename to .vortex/skills/prepare-vortex-release/SKILL.md index ca9e4e3006..82ea7431bf 100644 --- a/.claude/skills/prepare-vortex-release/SKILL.md +++ b/.vortex/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). 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/.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', diff --git a/.vortex/tests/lint.ci.sh b/.vortex/tests/lint.ci.sh index 4e3f743578..6b95d265cd 100755 --- a/.vortex/tests/lint.ci.sh +++ b/.vortex/tests/lint.ci.sh @@ -23,3 +23,15 @@ else echo "Checking that .circleci/vortex-test-common.yml is up to date." 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 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 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/tests/phpunit/Functional/AhoyWorkflowTest.php b/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php index 212ae8eeb9..35b2f417aa 100644 --- a/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php +++ b/.vortex/tests/phpunit/Functional/AhoyWorkflowTest.php @@ -62,12 +62,16 @@ public function testAhoyWorkflowStateless(): void { $this->subtestAhoyLintBe(); + $this->subtestAhoyLintBeRector(); + $this->subtestAhoyLintFe(); $this->subtestAhoyLintSdc(); $this->subtestAhoyLintTests(); + $this->subtestAhoyFast404(); + $this->subtestAhoyReset(); $this->subtestAhoyResetHard(); diff --git a/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php b/.vortex/tests/phpunit/Functional/DockerComposeWorkflowTest.php index 1e3788724f..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'); @@ -128,11 +130,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/Subtests/SubtestAhoyTrait.php b/.vortex/tests/phpunit/Traits/Subtests/SubtestAhoyTrait.php index 4f5b8eaa6b..10053e2c38 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'); @@ -297,6 +311,25 @@ 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'); + + // 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' + ); + + $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.'); @@ -458,6 +491,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(); @@ -965,6 +1040,59 @@ protected function subtestAhoyRedis(): void { $this->logStepFinish(); } + protected function subtestAhoyFast404(): void { + $this->logStepStart(); + + // 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. + $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 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'); + $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->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(); + } + protected function substepWarmCaches(): void { $this->logNote('Warming up caches'); $this->cmd('ahoy drush cr'); @@ -981,6 +1109,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/.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(); 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)); } 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'; 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/src/vortex-deploy-artifact b/.vortex/tooling/src/vortex-deploy-artifact index 6b8176580d..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.7.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', 'bff9d061fb757051366d650c35e367d9b024b7146e22fbd831c734ff88f4af4d'); +$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. @@ -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/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/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/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/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/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))); + } + } + } + +} diff --git a/.vortex/tooling/tests/Unit/DeployArtifactTest.php b/.vortex/tooling/tests/Unit/DeployArtifactTest.php index 781ea2dc81..3896625dbf 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.9.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.9.0/git-artifact', ['method' => 'GET'], ['ok' => TRUE, 'status' => 200, 'body' => ''], ); 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/.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, + ]; + } + } 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' => '', 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(); 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) 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 0b33586f37..0131c9e4ce 100644 --- a/composer.json +++ b/composer.json @@ -13,13 +13,14 @@ "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.11", + "drupal/core-recommended": "~11.4.11", "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/fast_404": "^3.7", + "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", @@ -29,41 +30,35 @@ "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", + "drupal/shield": "^1.10", "drupal/stage_file_proxy": "^4.0.0", - "drupal/testmode": "^2.7.1", + "drupal/testmode": "^2.8.0", "drupal/xmlsitemap": "^2.0", - "drush/drush": "^13.7.6", - "webflo/drupal-finder": "^1.3.1" + "drush/drush": "^13.8.0" }, "require-dev": { - "behat/behat": "^3.32.0", + "behat/behat": "^3.34.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.1", + "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.52.0", - "lullabot/mink-selenium2-driver": "^1.7.4", - "lullabot/php-webdriver": "^2.0.7", - "mglaman/phpstan-drupal": "^2.1.1", + "ergebnis/composer-normalize": "^2.54.0", + "mglaman/phpstan-drupal": "^2.2.2", "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", + "phpstan/phpstan": "^2.3.1", + "phpunit/phpunit": "^11.5.57", "pyrech/composer-changelogs": "^2.2", - "rector/rector": "^2.6.4", "softcreatr/jsonpath": "^0.10 || ^1.0", - "vincentlanglet/twig-cs-fixer": "^4.1.0" + "vincentlanglet/twig-cs-fixer": "^4.1.1" }, "conflict": { "drupal/drupal": "*" @@ -106,7 +101,7 @@ "bump-after-update": true, "discard-changes": true, "platform": { - "php": "8.4.21" + "php": "8.4.27" }, "policy": { "advisories": { diff --git a/docker-compose.yml b/docker-compose.yml index 4af6c63025..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. @@ -191,7 +192,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.10.0}" # Use custom database image (if defined) or fallback to standard database image. environment: <<: *default-environment <<: *default-user @@ -204,7 +205,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.10.0}" # Use custom database image (if defined) or fallback to standard database image. environment: <<: *default-environment MYSQL_DATABASE: drupal @@ -219,7 +220,7 @@ services: #;< SERVICE_CACHE cache: - image: uselagoon/valkey-8:26.8.1 + 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 +265,7 @@ services: # Browser container, used for browser testing. browser: - image: selenium/standalone-chromium:151.0 + image: selenium/standalone-chromium:155.0 environment: <<: *default-environment <<: *default-volumes @@ -280,7 +281,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 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 diff --git a/phpstan.neon b/phpstan.neon index be76d74cd3..19a015deef 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -11,7 +11,7 @@ parameters: level: 7 - phpVersion: 80421 + phpVersion: 80427 paths: - web/modules/custom 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); 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/**" ], diff --git a/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 40ce6a863c..49b6ed24e9 100644 --- a/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -342,6 +342,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -349,6 +355,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -445,6 +465,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -453,6 +479,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -513,6 +553,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -520,6 +566,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -582,6 +642,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -589,6 +655,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -654,6 +734,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -661,6 +747,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -725,6 +825,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -732,6 +838,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -792,6 +912,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -799,6 +925,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -856,6 +996,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -863,6 +1009,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -899,7 +1059,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; @@ -920,6 +1080,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -927,6 +1093,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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 +1161,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -988,6 +1174,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -1046,6 +1246,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -1054,6 +1260,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -1118,6 +1338,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -1127,6 +1353,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -1190,6 +1430,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -1198,6 +1444,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -1264,6 +1524,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -1272,6 +1538,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -1316,7 +1596,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; @@ -1338,6 +1618,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -1346,6 +1632,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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'; @@ -1410,6 +1710,12 @@ 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 // phpcs:ignore #;< MODULE_TESTMODE 'testmode', // phpcs:ignore #;> MODULE_TESTMODE @@ -1418,6 +1724,20 @@ 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_path_check'] = FALSE; + $settings['fast404_respect_redirect'] = FALSE; + $settings['fast404_url_whitelisting'] = TRUE; + $settings['fast404_whitelist'] = [ + 'index.php', + 'rss.xml', + 'cron.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 74ff0512e1..5e009e7e7f 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_', @@ -236,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 9e5bfe6edd..9a7b7211b2 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,62 +23,106 @@ #[Group('drupal_settings')] class SwitchableSettingsTest extends SettingsTestCase { - // phpcs:ignore #;< SERVICE_ANTIVIRUS + // phpcs:ignore #;< MODULE_FAST_404 /** - * 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(); } + // phpcs:ignore #;> MODULE_FAST_404 + // phpcs:ignore #;< SERVICE_ANTIVIRUS + /** - * 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]], + ]; } // phpcs:ignore #;> SERVICE_ANTIVIRUS @@ -232,79 +280,191 @@ public static function dataProviderEnvironmentIndicator(): \Iterator { } // phpcs:ignore #;> MODULE_ENVIRONMENT_INDICATOR - // phpcs:ignore #;< SERVICE_CACHE + // phpcs:ignore #;< MODULE_FAST_404 /** - * 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); - $this->assertSettingsContains($settings); + if ($with_fast404) { + $stub = <<<'PHP' + 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); + } + + // phpcs:ignore #;> MODULE_FAST_404 + // phpcs:ignore #;< SERVICE_CACHE - $settings['redis.connection']['interface'] = 'PhpRedis'; - $settings['redis.connection']['host'] = 'redis_host'; - $settings['redis.connection']['port'] = 6380; - $settings['cache']['default'] = 'cache.backend.redis'; + /** + * Test Redis settings. + */ + #[DataProvider('dataProviderRedis')] + public function testRedis(array $vars, bool $expected_enabled, array $expected_settings): void { + $this->setEnvVars($vars); - $this->assertArrayHasKey('bootstrap_container_definition', $this->settings); + $this->requireSettingsFile(); + + $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, + ]; - $this->assertSettingsContains($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, + ]; } // phpcs:ignore #;> SERVICE_CACHE @@ -529,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 [ @@ -541,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'], ], ]; @@ -656,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, @@ -769,12 +959,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 +999,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, @@ -853,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 @@ -1037,7 +1250,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/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.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.fast404.php b/web/sites/default/includes/modules/settings.fast404.php deleted file mode 100644 index 148f7d255f..0000000000 --- a/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/web/sites/default/includes/modules/settings.fast_404.php b/web/sites/default/includes/modules/settings.fast_404.php new file mode 100644 index 0000000000..4af6f182ea --- /dev/null +++ b/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/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 d50c66a338..6d5f5a8de4 100644 --- a/web/sites/default/includes/modules/settings.reroute_email.php +++ b/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@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'))) { +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.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 @@ +