diff --git a/.circleci/config.yml b/.circleci/config.yml index 190ba12fc6..087a0fa39a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -344,9 +344,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.circleci/vortex-test-common.yml b/.circleci/vortex-test-common.yml index a22ac05b4f..b51a4059bf 100644 --- a/.circleci/vortex-test-common.yml +++ b/.circleci/vortex-test-common.yml @@ -174,9 +174,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.claude/skills/prepare-vortex-release/SKILL.md b/.claude/skills/prepare-vortex-release/SKILL.md index f41ffe4da0..218cc78928 100644 --- a/.claude/skills/prepare-vortex-release/SKILL.md +++ b/.claude/skills/prepare-vortex-release/SKILL.md @@ -96,8 +96,7 @@ Work through each checklist item from the release process doc: Use npm, NOT yarn. 6. **CI runner** - Check if `drevops/ci-runner` is at the latest version. 7. **Cache version** - The cache key has the form `v..` (CalVer). - Update it in `.circleci/config.yml`, - `.circleci/vortex-test-common.yml`, and `.github/workflows/build-test-deploy.yml`: + Update it in `.circleci/config.yml` and `.github/workflows/build-test-deploy.yml`, then run `ahoy lint-ci-fix` from `.vortex/` to regenerate `.circleci/vortex-test-common.yml` and `.github/workflows/vortex-test-didi.yml`: - The `v..` prefix tracks the latest `uselagoon/*` container image tag (e.g. `v26.4.0` for `uselagoon/mysql-8.4:26.4.0`). Lagoon versions encode `YY.M.minor` (year, calendar month, minor), so this part diff --git a/.github/workflows/build-test-deploy.yml b/.github/workflows/build-test-deploy.yml index 654b005472..ac0ae1534f 100644 --- a/.github/workflows/build-test-deploy.yml +++ b/.github/workflows/build-test-deploy.yml @@ -263,14 +263,23 @@ jobs: - name: Process the codebase to run in CI run: find . -name "docker-compose.yml" -print0 | xargs -0 -I {} sh -c "sed -i -e '/###/d' {} && sed -i -e 's/##//' {}" + - name: Load environment variables from .env + run: t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && set +a && . "${t}" && env >> "$GITHUB_ENV" + - name: Install Vortex tooling run: ./scripts/vortex-tooling.sh - name: Adjust variables for a scheduled run if: github.event_name == 'schedule' run: | - echo "VORTEX_CI_DB_CACHE_FALLBACK=no" >> "$GITHUB_ENV" - echo "VORTEX_FRONTEND_BUILD_SKIP=1" >> "$GITHUB_ENV" + { + echo "VORTEX_CI_DB_CACHE_FALLBACK=no" + echo "VORTEX_FRONTEND_BUILD_SKIP=1" + # Import the fetched dump into a clean base image (if database-in-image storage is used). + echo "VORTEX_DB_IMAGE_BASE=drevops/mariadb-drupal-data:26.10.0" + # Deploy container image (if database-in-image storage is used). + echo "VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED=1" + } >> "$GITHUB_ENV" - name: Create cache keys files for database caching run: | @@ -313,11 +322,37 @@ jobs: run: | if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi ./vendor/bin/vortex-login-container-registry + # A database built from the base image is empty, so it is + # provisioned from the dump file without the image. + if [ -n "${VORTEX_DB_IMAGE:-}" ] && [ -n "${VORTEX_DB_IMAGE_BASE:-}" ] && [ "${VORTEX_FETCH_DB_SOURCE:-url}" != "container_registry" ]; then + VORTEX_FETCH_DB_SOURCE=container_registry VORTEX_FETCH_DB_CONTAINER_REGISTRY_IMAGE_BASE="${VORTEX_DB_IMAGE_BASE}" ./vendor/bin/vortex-fetch-db + provision_opts="VORTEX_DB_IMAGE=" + fi docker compose up --detach && sleep 15 - docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql - docker compose exec cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ./vendor/bin/vortex-provision" + # The 'container_registry' source fetches an image without a dump file. + if [ -f .data/db.sql ]; then + docker compose exec cli mkdir -p .data + docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql + fi + docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" + # Database-in-image storage caches the exported image archive instead of the dump. + if [ -n "${VORTEX_DB_IMAGE:-}" ]; then rm -f .data/db.sql; fi ./vendor/bin/vortex-export-db db.sql - docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql + if [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql; then docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql; fi + # 'hashFiles()' runs as the runner user outside the container, so the + # root-owned files in '.data' must be readable by others. + chmod -R a+rX .data + timeout-minutes: 30 + + # Deploy the freshly-exported database image to the container registry. + # No-op unless a fresh DB was fetched (the fetch semaphore), the project + # uses database-in-image storage (VORTEX_DB_IMAGE), and deployment was + # requested (VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED, in the script). + - name: Deploy DB image + run: | + if [ -z "${VORTEX_DB_IMAGE:-}" ]; then echo "==> Database-in-image storage is not used. DB image deployment will not proceed."; exit 0; fi + if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> No freshly fetched database. DB image deployment will not proceed."; exit 0; fi + ./vendor/bin/vortex-push-db-image timeout-minutes: 30 # Save cache per default branch and the timestamp. diff --git a/.github/workflows/vortex-test-didi.yml b/.github/workflows/vortex-test-didi.yml new file mode 100644 index 0000000000..76f323e0db --- /dev/null +++ b/.github/workflows/vortex-test-didi.yml @@ -0,0 +1,1063 @@ +# Auto-generated by .vortex/tests/generate-vortex-dev-gha +# Source: .github/workflows/build-test-deploy.yml +# Do not edit directly. +# +# This action is used for Vortex maintenance. It will not be used in the scaffolded project. +name: Vortex - Test DIDI + +on: + push: + branches: + - main + - release/** + - project/** + - '*.x' + pull_request: + branches: + - main + - feature/** + - bugfix/** + - release/** + - project/** + - '*.x' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +# Workaround for the Actions runner creating /root/.docker/config.json +# with permissions that prevent the container from reading it. +# https://github.com/actions/runner/issues/863 +env: + DOCKER_CONFIG: /tmp/.docker + +permissions: + contents: read + +jobs: + # DIDI-FI variant jobs + vortex-dev-didi-database-fi: + runs-on: ubuntu-latest + if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }} + + container: + # https://hub.docker.com/r/drevops/ci-runner + image: drevops/ci-runner:26.10.0@sha256:36db4ee12da3372c86966fccd543e49c9470bca12e86eb5d4aad7904dd84a0dd + env: + PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }} + VORTEX_CONTAINER_REGISTRY_USER: ${{ secrets.VORTEX_CONTAINER_REGISTRY_USER }} + VORTEX_CONTAINER_REGISTRY_PASS: ${{ secrets.VORTEX_CONTAINER_REGISTRY_PASS }} + TZ: ${{ vars.TZ || 'UTC' }} + TERM: xterm-256color + VORTEX_SSH_DISABLE_STRICT_HOST_KEY_CHECKING: "1" + VORTEX_SSH_REMOVE_ALL_KEYS: "1" + VORTEX_DEBUG: ${{ vars.VORTEX_DEBUG }} + # How often to refresh the cache of the DB dump. Refer to `date` command. + VORTEX_CI_DB_CACHE_TIMESTAMP: +%Y%m%d + # Use previous database caches on this branch as a fallback if the above cache + # does not match (for example, the cache is available only from the previous + # day). If "no" is set, the cache will be rebuilt from scratch. + VORTEX_CI_DB_CACHE_FALLBACK: "yes" + # Which branch to use as a source of DB caches. + VORTEX_CI_DB_CACHE_BRANCH: vortex-dev-didi-fi + VORTEX_FETCH_DB_SOURCE: url + VORTEX_FETCH_DB_FORCE: 1 + VORTEX_DB_IMAGE: drevops/vortex-dev-mariadb-drupal-data-demo-destination-11.x + VORTEX_DB_IMAGE_BASE: drevops/mariadb-drupal-data:26.10.0 + COMPOSE_PROGRESS: plain + VORTEX_PUSH_CONTAINER_REGISTRY_IMAGE_TAG: vortex-dev-didi-database-fi-gha + VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED: 1 + + steps: + # Frees disk space by removing preinstalled toolchains unused by this project. Steps run in a container, so the host is reached via the Docker socket. + - name: Free up disk space on the runner + if: ${{ vars.VORTEX_CI_FREE_DISK_SPACE == '1' }} + run: | + set -- /host/usr/local/.ghcup /host/usr/share/swift /host/usr/local/share/powershell /host/usr/share/dotnet /host/opt/hostedtoolcache/CodeQL + # set -- "$@" /host/usr/local/lib/android # Removes about 10GB more, but takes about 50s. Uncomment to enable. + job_image=$(docker inspect --format '{{.Config.Image}}' "${HOSTNAME}" 2>/dev/null || echo alpine:3) + docker run --rm -v /:/host "${job_image}" rm -rf "$@" || true + + - name: Report disk usage + run: df -h + + - name: Preserve $HOME set in the container + run: echo HOME=/root >> "$GITHUB_ENV" # https://github.com/actions/runner/issues/863 + + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + # Do not keep SSH credentials after checkout to allow adding custom SSH keys. + persist-credentials: false + + - name: Fix Git ownership permissions + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + + - name: Add SSH private key used to fetch database + if: ${{ env.VORTEX_FETCH_DB_SSH_PRIVATE_KEY != '' }} + uses: shimataro/ssh-key-action@87a8f067114a8ce263df83e9ed5c849953548bc3 # v2.8.1 + with: + key: ${{ secrets.VORTEX_FETCH_DB_SSH_PRIVATE_KEY }} + known_hosts: ${{ vars.VORTEX_FETCH_DB_SSH_KNOWN_HOSTS || 'unnecessary' }} + env: + VORTEX_FETCH_DB_SSH_PRIVATE_KEY: ${{ secrets.VORTEX_FETCH_DB_SSH_PRIVATE_KEY }} + + - name: Process the codebase to run in CI + run: find . -name "docker-compose.yml" -print0 | xargs -0 -I {} sh -c "sed -i -e '/###/d' {} && sed -i -e 's/##//' {}" + + - name: Load environment variables from .env + run: t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && set +a && . "${t}" && env >> "$GITHUB_ENV" + + - name: Install Vortex tooling + run: ./scripts/vortex-tooling.sh + + - name: Adjust variables for a scheduled run + if: github.event_name == 'schedule' + run: | + { + echo "VORTEX_CI_DB_CACHE_FALLBACK=no" + echo "VORTEX_FRONTEND_BUILD_SKIP=1" + # Import the fetched dump into a clean base image (if database-in-image storage is used). + echo "VORTEX_DB_IMAGE_BASE=drevops/mariadb-drupal-data:26.10.0" + # Deploy container image (if database-in-image storage is used). + echo "VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED=1" + } >> "$GITHUB_ENV" + + - name: Create cache keys files for database caching + run: | + echo "${VORTEX_CI_DB_CACHE_BRANCH}" | tee db_cache_branch + echo "${VORTEX_CI_DB_CACHE_FALLBACK/no/"${GITHUB_RUN_NUMBER}"}" | tee db_cache_fallback + date "${VORTEX_CI_DB_CACHE_TIMESTAMP}" | tee db_cache_timestamp + echo "yes" | tee db_cache_fallback_yes + + # Restore DB cache based on the cache strategy set by the cache keys below. + # Bump the last segment of the version prefix below to force a cache reset. + # Lookup cache based on the default branch and a timestamp. Allows + # to use cache from the very first build on the day (sanitized database dump, for example). + - name: Restore DB cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 + with: + path: .data + key: v26.8.1-${{ hashFiles('db_cache_branch') }}-${{ hashFiles('db_cache_fallback') }}-${{ hashFiles('db_cache_timestamp') }} + # Fallback to caching by default branch name only. Allows to use + # cache from the branch build on the previous day. + restore-keys: | + v26.8.1-${{ hashFiles('db_cache_branch') }}-${{ hashFiles('db_cache_fallback') }}- + + - name: Fetch DB + run: | + VORTEX_FETCH_DB_SEMAPHORE=/tmp/fetch-db-fresh ./vendor/bin/vortex-fetch-db + echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" + timeout-minutes: 30 + #;< DB_FETCH_SOURCE_ACQUIA + env: + VORTEX_ACQUIA_KEY: ${{ secrets.VORTEX_ACQUIA_KEY }} + VORTEX_ACQUIA_SECRET: ${{ secrets.VORTEX_ACQUIA_SECRET }} + #;> DB_FETCH_SOURCE_ACQUIA + + #;< MIGRATION + - name: Fetch migration DB + run: VORTEX_DB_INDEX=2 ./vendor/bin/vortex-fetch-db + #;> MIGRATION + + - name: Export DB + run: | + if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi + ./vendor/bin/vortex-login-container-registry + # A database built from the base image is empty, so it is + # provisioned from the dump file without the image. + if [ -n "${VORTEX_DB_IMAGE:-}" ] && [ -n "${VORTEX_DB_IMAGE_BASE:-}" ] && [ "${VORTEX_FETCH_DB_SOURCE:-url}" != "container_registry" ]; then + VORTEX_FETCH_DB_SOURCE=container_registry VORTEX_FETCH_DB_CONTAINER_REGISTRY_IMAGE_BASE="${VORTEX_DB_IMAGE_BASE}" ./vendor/bin/vortex-fetch-db + provision_opts="VORTEX_DB_IMAGE=" + fi + docker compose up --detach && sleep 15 + # The 'container_registry' source fetches an image without a dump file. + if [ -f .data/db.sql ]; then + docker compose exec cli mkdir -p .data + docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql + fi + docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" + # Database-in-image storage caches the exported image archive instead of the dump. + if [ -n "${VORTEX_DB_IMAGE:-}" ]; then rm -f .data/db.sql; fi + ./vendor/bin/vortex-export-db db.sql + if [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql; then docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql; fi + # 'hashFiles()' runs as the runner user outside the container, so the + # root-owned files in '.data' must be readable by others. + chmod -R a+rX .data + timeout-minutes: 30 + + # Deploy the freshly-exported database image to the container registry. + # No-op unless a fresh DB was fetched (the fetch semaphore), the project + # uses database-in-image storage (VORTEX_DB_IMAGE), and deployment was + # requested (VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED, in the script). + - name: Deploy DB image + run: | + if [ -z "${VORTEX_DB_IMAGE:-}" ]; then echo "==> Database-in-image storage is not used. DB image deployment will not proceed."; exit 0; fi + if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> No freshly fetched database. DB image deployment will not proceed."; exit 0; fi + ./vendor/bin/vortex-push-db-image + timeout-minutes: 30 + + # Save cache per default branch and the timestamp. + # The cache will not be saved if it already exists. + # Note that the cache fallback flag is enabled for this case in order + # to save cache even if the fallback is not used when restoring it. + - name: Save DB cache + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 + if: env.db_hash != hashFiles('.data') + with: + path: .data + key: v26.8.1-${{ hashFiles('db_cache_branch') }}-${{ hashFiles('db_cache_fallback_yes') }}-${{ hashFiles('db_cache_timestamp') }} + + vortex-dev-didi-build-fi: + runs-on: ubuntu-latest + #;< !PROVISION_TYPE_PROFILE + needs: vortex-dev-didi-database-fi + if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }} + #;> !PROVISION_TYPE_PROFILE + + permissions: + contents: read + checks: write + pull-requests: write + + strategy: + # A matrix to run multiple jobs in parallel. + matrix: + instance: [0, 1] + fail-fast: false + + env: + # Which tools run on this instance. Tools that only need to run once are + # pinned to the first instance. Add a line for every additional tool and + # reference it in that tool's step. + # https://www.vortextemplate.com/docs/continuous-integration#test-parallelism + VORTEX_CI_RUNNER_INDEX: ${{ strategy.job-index }} + VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} + #;< TOOL_JEST + VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} + #;> TOOL_JEST + #;< TOOL_PHPUNIT + VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} + #;> TOOL_PHPUNIT + #;< DRUPAL_THEME + #;< MODULE_SDC_DEVEL + VORTEX_CI_IS_SDC_DEVEL_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} + #;> MODULE_SDC_DEVEL + #;> DRUPAL_THEME + #;< TOOL_BEHAT + # Runs on every instance, using the `p` profile. + VORTEX_CI_IS_BEHAT_RUNNER: true + # Subtracted from the instance index to derive the profile number. Raise + # it by one for every leading instance that does not run Behat, so the + # first Behat instance still selects the `p0` catch-all profile. + VORTEX_CI_BEHAT_PROFILE_OFFSET: 0 + #;> TOOL_BEHAT + + container: + # https://hub.docker.com/r/drevops/ci-runner + image: drevops/ci-runner:26.10.0@sha256:36db4ee12da3372c86966fccd543e49c9470bca12e86eb5d4aad7904dd84a0dd + env: + PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }} + VORTEX_CONTAINER_REGISTRY_USER: ${{ secrets.VORTEX_CONTAINER_REGISTRY_USER }} + VORTEX_CONTAINER_REGISTRY_PASS: ${{ secrets.VORTEX_CONTAINER_REGISTRY_PASS }} + TZ: ${{ vars.TZ || 'UTC' }} + TERM: xterm-256color + # Disable strict host key checking for SSH connections. + VORTEX_SSH_DISABLE_STRICT_HOST_KEY_CHECKING: "1" + VORTEX_SSH_REMOVE_ALL_KEYS: "1" + VORTEX_DEBUG: ${{ vars.VORTEX_DEBUG }} + #;< !PROVISION_TYPE_PROFILE + # How often to refresh the cache of the DB dump. Refer to `date` command. + VORTEX_CI_DB_CACHE_TIMESTAMP: +%Y%m%d + # Use previous database caches on this branch as a fallback if the above cache + # does not match (for example, the cache is available only from the previous + # day). If "no" is set, the cache will be rebuilt from scratch. + VORTEX_CI_DB_CACHE_FALLBACK: "yes" + # Which branch to use as a source of DB caches. + VORTEX_CI_DB_CACHE_BRANCH: vortex-dev-didi-fi + #;> !PROVISION_TYPE_PROFILE + VORTEX_DB_IMAGE: drevops/vortex-dev-mariadb-drupal-data-demo-destination-11.x:vortex-dev-didi-database-fi-gha + DRUPAL_MIGRATION_SKIP: 1 + + steps: + # Frees disk space by removing preinstalled toolchains unused by this project. Steps run in a container, so the host is reached via the Docker socket. + - name: Free up disk space on the runner + if: ${{ vars.VORTEX_CI_FREE_DISK_SPACE == '1' }} + run: | + set -- /host/usr/local/.ghcup /host/usr/share/swift /host/usr/local/share/powershell /host/usr/share/dotnet /host/opt/hostedtoolcache/CodeQL + # set -- "$@" /host/usr/local/lib/android # Removes about 10GB more, but takes about 50s. Uncomment to enable. + job_image=$(docker inspect --format '{{.Config.Image}}' "${HOSTNAME}" 2>/dev/null || echo alpine:3) + docker run --rm -v /:/host "${job_image}" rm -rf "$@" || true + + - name: Report disk usage + run: df -h + + - name: Preserve $HOME set in the container + run: echo HOME=/root >> "$GITHUB_ENV" # https://github.com/actions/runner/issues/863 + + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + persist-credentials: false + + - name: Fix Git ownership permissions + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + + - name: Process the codebase to run in CI + run: find . -name "docker-compose.yml" -print0 | xargs -0 -I {} sh -c "sed -i -e '/###/d' {} && sed -i -e 's/##//' {}" + + - name: Load environment variables from .env + run: t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && set +a && . "${t}" && env >> "$GITHUB_ENV" + + - name: Validate Composer configuration + run: composer validate --strict + continue-on-error: ${{ vars.VORTEX_CI_COMPOSER_VALIDATE_IGNORE_FAILURE == '1' }} + + - name: Install Vortex tooling + run: ./scripts/vortex-tooling.sh + + #;< !PROVISION_TYPE_PROFILE + - name: Create cache keys files for database caching + run: | + echo "${VORTEX_CI_DB_CACHE_BRANCH}" | tee db_cache_branch + echo "yes" | tee db_cache_fallback_yes + date "${VORTEX_CI_DB_CACHE_TIMESTAMP}" | tee db_cache_timestamp + + - name: Show cache key for database caching + run: echo 'v26.8.1-${{ hashFiles('db_cache_branch') }}-${{ hashFiles('db_cache_fallback_yes') }}-${{ hashFiles('db_cache_timestamp') }}' + + # Restore DB cache based on the cache strategy set by the cache keys below. + # Bump the last segment of the version prefix below to force a cache reset. + # Lookup cache based on the default branch and a timestamp. Allows + # to use cache from the very first build on the day (sanitized database dump, for example). + - name: Restore DB cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 + with: + path: .data + fail-on-cache-miss: true + # Use cached database from previous builds of this branch. + key: v26.8.1-${{ hashFiles('db_cache_branch') }}-${{ hashFiles('db_cache_fallback_yes') }}-${{ hashFiles('db_cache_timestamp') }} + restore-keys: | + v26.8.1-${{ hashFiles('db_cache_branch') }}-${{ hashFiles('db_cache_fallback_yes') }}- + #;> !PROVISION_TYPE_PROFILE + + - name: Login to container registry + run: ./vendor/bin/vortex-login-container-registry + + - name: Build stack + run: docker compose up --detach && docker builder prune --all --force && docker image prune --force + + - name: Export built codebase + if: ${{ matrix.instance == 0 && !startsWith(github.head_ref || github.ref_name, 'deps/') && contains(env.VORTEX_DEPLOY_TYPES, 'artifact') }} + run: | + mkdir -p "/tmp/workspace/code" "/tmp/artifacts" + docker compose --progress quiet cp -L cli:"/app/." "/tmp/workspace/code" + tar -C /tmp/workspace -cpf /tmp/artifacts/code.tar code + du -sh "/tmp/artifacts" + + - name: Install development dependencies + run: | + docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c " \ + if [ -n \"\${PACKAGE_TOKEN:-}\" ]; then composer config --global --auth github-oauth.github.com \"\${PACKAGE_TOKEN}\"; fi && \ + COMPOSER_MEMORY_LIMIT=-1 composer --ansi install --prefer-dist" + #;< TOOL_JEST + docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "npm ci" + #;> TOOL_JEST + + - name: Provision site + run: | + # Database dumps are removed from the runner once they are inside the + # container to avoid holding two copies for the rest of the job. + if [ -f .data/db.sql ]; then + docker compose exec cli mkdir -p .data + docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql + rm -f .data/db.sql + fi + #;< MIGRATION + if [ -f ".data/${VORTEX_FETCH_DB2_FILE:-db2.sql}" ]; then + docker compose exec -T cli mkdir -p .data + docker compose --progress quiet cp -L ".data/${VORTEX_FETCH_DB2_FILE:-db2.sql}" cli:"/app/.data/${VORTEX_FETCH_DB2_FILE:-db2.sql}" + rm -f ".data/${VORTEX_FETCH_DB2_FILE:-db2.sql}" + fi + #;> MIGRATION + docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli ./vendor/bin/vortex-provision + timeout-minutes: 30 + + #;< TOOL_JEST + - name: Test with Jest + if: ${{ env.VORTEX_CI_IS_JEST_RUNNER == 'true' }} + run: docker compose exec -T cli bash -c "npm test" + continue-on-error: ${{ vars.VORTEX_CI_JEST_IGNORE_FAILURE == '1' }} + #;> TOOL_JEST + + #;< TOOL_PHPUNIT + - name: Test with PHPUnit + if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' }} + run: docker compose exec -T cli vendor/bin/phpunit + continue-on-error: ${{ vars.VORTEX_CI_PHPUNIT_IGNORE_FAILURE == '1' }} + + - name: Process PHPUnit logs and coverage + if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' }} + run: | + mkdir -p ".logs" + if docker compose ps --services --filter "status=running" | grep -q cli && docker compose exec cli test -d /app/.logs; then + docker compose --progress quiet cp cli:/app/.logs/. ".logs/" + fi + + - name: Extract code coverage + if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' }} + run: | + RATE=$(grep -om1 'line-rate="[0-9.]*"' .logs/coverage/phpunit/cobertura.xml | tr -cd '0-9.') + PERCENT=$(awk "BEGIN {printf \"%.2f\", $RATE*100}") + echo "Coverage: $PERCENT% (threshold: $VORTEX_CI_CODE_COVERAGE_THRESHOLD%)" | tee -a "$GITHUB_STEP_SUMMARY" + { + echo "COVERAGE_PERCENT=${PERCENT}" + echo "COVERAGE_SUMMARY<> "$GITHUB_ENV" + env: + VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} + + - name: Post coverage summary as PR comment + if: ${{ github.event_name == 'pull_request' && env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' && vars.VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP != '1' }} + uses: marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3.0.5 + with: + header: coverage-gha + message: | + **Code coverage** (threshold: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }}%) + ``` + ${{ env.COVERAGE_SUMMARY }} + ``` +
+ Per-class coverage + + ``` + ${{ env.COVERAGE_DETAILS }} + ``` +
+ hide_and_recreate: true + + #;< CODE_COVERAGE_PROVIDER_CODECOV + - name: Upload coverage report to Codecov + uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7 + if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' && env.CODECOV_TOKEN != '' }} + continue-on-error: true + with: + directory: .logs/coverage + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + #;> CODE_COVERAGE_PROVIDER_CODECOV + + - name: Check code coverage threshold + if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' }} + run: | + if [ "${COVERAGE_PERCENT//.}" -lt "$((VORTEX_CI_CODE_COVERAGE_THRESHOLD*100))" ]; then + echo "FAIL: coverage ${COVERAGE_PERCENT}% is below threshold ${VORTEX_CI_CODE_COVERAGE_THRESHOLD}%" + exit 1 + fi + env: + VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} + #;> TOOL_PHPUNIT + + #;< DRUPAL_THEME + #;< MODULE_SDC_DEVEL + - name: Validate Single Directory Components + if: ${{ env.VORTEX_CI_IS_SDC_DEVEL_RUNNER == 'true' }} + run: | + [ "${VORTEX_FRONTEND_BUILD_SKIP:-0}" -eq 1 ] && exit 0 + output=$(docker compose exec -T cli vendor/bin/drush sdc-devel:validate "${DRUPAL_THEME}" 2>&1) + echo "${output}" + if echo "${output}" | grep -qE 'Critical|Errors?|Warnings?'; then + echo "SDC validation reported problems." + exit 1 + fi + continue-on-error: ${{ vars.VORTEX_CI_SDC_DEVEL_IGNORE_FAILURE == '1' }} + #;> MODULE_SDC_DEVEL + #;> DRUPAL_THEME + + #;< TOOL_BEHAT + - name: Test with Behat + if: ${{ env.VORTEX_CI_IS_BEHAT_RUNNER == 'true' }} + run: | + # shellcheck disable=SC2170 + if [ "${VORTEX_CI_RUNNER_TOTAL}" -gt 1 ]; then export VORTEX_CI_BEHAT_PROFILE="${VORTEX_CI_BEHAT_PROFILE:-p$((VORTEX_CI_RUNNER_INDEX - VORTEX_CI_BEHAT_PROFILE_OFFSET))}"; fi + echo "Running with ${VORTEX_CI_BEHAT_PROFILE:-default} profile" + docker compose exec -T -e BEHAT_SCREENSHOT_ANIMATION_SKIP=1 cli php -d memory_limit=-1 vendor/bin/behat --colors --strict --profile="${VORTEX_CI_BEHAT_PROFILE:-default}" || \ + docker compose exec -T -e BEHAT_SCREENSHOT_ANIMATION_SKIP=1 cli php -d memory_limit=-1 vendor/bin/behat --colors --strict --rerun --profile="${VORTEX_CI_BEHAT_PROFILE:-default}" + env: + VORTEX_CI_BEHAT_PROFILE: ${{ vars.VORTEX_CI_BEHAT_PROFILE }} + continue-on-error: ${{ vars.VORTEX_CI_BEHAT_IGNORE_FAILURE == '1' }} + timeout-minutes: 30 + #;> TOOL_BEHAT + + - name: Process test logs and artifacts + if: always() + run: | + mkdir -p ".logs" + if docker compose ps --services --filter "status=running" | grep -q cli && docker compose exec cli test -d /app/.logs; then + docker compose --progress quiet cp cli:/app/.logs/. ".logs/" + fi + + - name: Upload test artifacts + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 + if: always() + with: + name: test-artifacts-vortex-dev-didi-build-fi-${{ matrix.instance }} + path: .logs + include-hidden-files: true + if-no-files-found: error + + #;< TOOL_PHPUNIT_BEHAT + - name: Publish test results to GitHub Checks + if: ${{ !cancelled() && vars.VORTEX_CI_TEST_RESULTS_SKIP != '1' }} + uses: EnricoMi/publish-unit-test-result-action@d0a4676d0e0b938bc201470d88276b7c74c712b3 # v2.24.0 + with: + check_name: Test results vortex-dev-didi-build-fi (${{ matrix.instance }}) + comment_mode: "off" + test_file_prefix: "-/app/" + files: | + .logs/test_results/**/*.xml + #;> TOOL_PHPUNIT_BEHAT + + - name: Upload exported codebase as an artifact + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 + if: ${{ matrix.instance == 0 && !startsWith(github.head_ref || github.ref_name, 'deps/') && contains(env.VORTEX_DEPLOY_TYPES, 'artifact') }} + with: + name: code-artifact-vortex-dev-didi-build-fi + path: "/tmp/artifacts/code.tar" + include-hidden-files: true + if-no-files-found: error + retention-days: 1 + + # 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 + timeout-minutes: 120 # Cancel the action after 120 minutes, regardless of whether a connection has been established. + with: + detached: true + + # DIDI-II variant jobs + vortex-dev-database-ii: + runs-on: ubuntu-latest + if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }} + + container: + # https://hub.docker.com/r/drevops/ci-runner + image: drevops/ci-runner:26.10.0@sha256:36db4ee12da3372c86966fccd543e49c9470bca12e86eb5d4aad7904dd84a0dd + env: + PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }} + VORTEX_CONTAINER_REGISTRY_USER: ${{ secrets.VORTEX_CONTAINER_REGISTRY_USER }} + VORTEX_CONTAINER_REGISTRY_PASS: ${{ secrets.VORTEX_CONTAINER_REGISTRY_PASS }} + TZ: ${{ vars.TZ || 'UTC' }} + TERM: xterm-256color + VORTEX_SSH_DISABLE_STRICT_HOST_KEY_CHECKING: "1" + VORTEX_SSH_REMOVE_ALL_KEYS: "1" + VORTEX_DEBUG: ${{ vars.VORTEX_DEBUG }} + # How often to refresh the cache of the DB dump. Refer to `date` command. + VORTEX_CI_DB_CACHE_TIMESTAMP: +%Y%m%d + # Use previous database caches on this branch as a fallback if the above cache + # does not match (for example, the cache is available only from the previous + # day). If "no" is set, the cache will be rebuilt from scratch. + VORTEX_CI_DB_CACHE_FALLBACK: "yes" + # Which branch to use as a source of DB caches. + VORTEX_CI_DB_CACHE_BRANCH: vortex-dev-didi-ii + 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-gha + VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED: 1 + + steps: + # Frees disk space by removing preinstalled toolchains unused by this project. Steps run in a container, so the host is reached via the Docker socket. + - name: Free up disk space on the runner + if: ${{ vars.VORTEX_CI_FREE_DISK_SPACE == '1' }} + run: | + set -- /host/usr/local/.ghcup /host/usr/share/swift /host/usr/local/share/powershell /host/usr/share/dotnet /host/opt/hostedtoolcache/CodeQL + # set -- "$@" /host/usr/local/lib/android # Removes about 10GB more, but takes about 50s. Uncomment to enable. + job_image=$(docker inspect --format '{{.Config.Image}}' "${HOSTNAME}" 2>/dev/null || echo alpine:3) + docker run --rm -v /:/host "${job_image}" rm -rf "$@" || true + + - name: Report disk usage + run: df -h + + - name: Preserve $HOME set in the container + run: echo HOME=/root >> "$GITHUB_ENV" # https://github.com/actions/runner/issues/863 + + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + # Do not keep SSH credentials after checkout to allow adding custom SSH keys. + persist-credentials: false + + - name: Fix Git ownership permissions + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + + - name: Add SSH private key used to fetch database + if: ${{ env.VORTEX_FETCH_DB_SSH_PRIVATE_KEY != '' }} + uses: shimataro/ssh-key-action@87a8f067114a8ce263df83e9ed5c849953548bc3 # v2.8.1 + with: + key: ${{ secrets.VORTEX_FETCH_DB_SSH_PRIVATE_KEY }} + known_hosts: ${{ vars.VORTEX_FETCH_DB_SSH_KNOWN_HOSTS || 'unnecessary' }} + env: + VORTEX_FETCH_DB_SSH_PRIVATE_KEY: ${{ secrets.VORTEX_FETCH_DB_SSH_PRIVATE_KEY }} + + - name: Process the codebase to run in CI + run: find . -name "docker-compose.yml" -print0 | xargs -0 -I {} sh -c "sed -i -e '/###/d' {} && sed -i -e 's/##//' {}" + + - name: Load environment variables from .env + run: t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && set +a && . "${t}" && env >> "$GITHUB_ENV" + + - name: Install Vortex tooling + run: ./scripts/vortex-tooling.sh + + - name: Adjust variables for a scheduled run + if: github.event_name == 'schedule' + run: | + { + echo "VORTEX_CI_DB_CACHE_FALLBACK=no" + echo "VORTEX_FRONTEND_BUILD_SKIP=1" + # Import the fetched dump into a clean base image (if database-in-image storage is used). + echo "VORTEX_DB_IMAGE_BASE=drevops/mariadb-drupal-data:26.10.0" + # Deploy container image (if database-in-image storage is used). + echo "VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED=1" + } >> "$GITHUB_ENV" + + - name: Create cache keys files for database caching + run: | + echo "${VORTEX_CI_DB_CACHE_BRANCH}" | tee db_cache_branch + echo "${VORTEX_CI_DB_CACHE_FALLBACK/no/"${GITHUB_RUN_NUMBER}"}" | tee db_cache_fallback + date "${VORTEX_CI_DB_CACHE_TIMESTAMP}" | tee db_cache_timestamp + echo "yes" | tee db_cache_fallback_yes + + # Restore DB cache based on the cache strategy set by the cache keys below. + # Bump the last segment of the version prefix below to force a cache reset. + # Lookup cache based on the default branch and a timestamp. Allows + # to use cache from the very first build on the day (sanitized database dump, for example). + - name: Restore DB cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 + with: + path: .data + key: v26.8.1-${{ hashFiles('db_cache_branch') }}-${{ hashFiles('db_cache_fallback') }}-${{ hashFiles('db_cache_timestamp') }} + # Fallback to caching by default branch name only. Allows to use + # cache from the branch build on the previous day. + restore-keys: | + v26.8.1-${{ hashFiles('db_cache_branch') }}-${{ hashFiles('db_cache_fallback') }}- + + - name: Fetch DB + run: | + VORTEX_FETCH_DB_SEMAPHORE=/tmp/fetch-db-fresh ./vendor/bin/vortex-fetch-db + echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" + timeout-minutes: 30 + #;< DB_FETCH_SOURCE_ACQUIA + env: + VORTEX_ACQUIA_KEY: ${{ secrets.VORTEX_ACQUIA_KEY }} + VORTEX_ACQUIA_SECRET: ${{ secrets.VORTEX_ACQUIA_SECRET }} + #;> DB_FETCH_SOURCE_ACQUIA + + #;< MIGRATION + - name: Fetch migration DB + run: VORTEX_DB_INDEX=2 ./vendor/bin/vortex-fetch-db + #;> MIGRATION + + - name: Export DB + run: | + if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi + ./vendor/bin/vortex-login-container-registry + # A database built from the base image is empty, so it is + # provisioned from the dump file without the image. + if [ -n "${VORTEX_DB_IMAGE:-}" ] && [ -n "${VORTEX_DB_IMAGE_BASE:-}" ] && [ "${VORTEX_FETCH_DB_SOURCE:-url}" != "container_registry" ]; then + VORTEX_FETCH_DB_SOURCE=container_registry VORTEX_FETCH_DB_CONTAINER_REGISTRY_IMAGE_BASE="${VORTEX_DB_IMAGE_BASE}" ./vendor/bin/vortex-fetch-db + provision_opts="VORTEX_DB_IMAGE=" + fi + docker compose up --detach && sleep 15 + # The 'container_registry' source fetches an image without a dump file. + if [ -f .data/db.sql ]; then + docker compose exec cli mkdir -p .data + docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql + fi + docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" + # Database-in-image storage caches the exported image archive instead of the dump. + if [ -n "${VORTEX_DB_IMAGE:-}" ]; then rm -f .data/db.sql; fi + ./vendor/bin/vortex-export-db db.sql + if [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql; then docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql; fi + # 'hashFiles()' runs as the runner user outside the container, so the + # root-owned files in '.data' must be readable by others. + chmod -R a+rX .data + timeout-minutes: 30 + + # Deploy the freshly-exported database image to the container registry. + # No-op unless a fresh DB was fetched (the fetch semaphore), the project + # uses database-in-image storage (VORTEX_DB_IMAGE), and deployment was + # requested (VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED, in the script). + - name: Deploy DB image + run: | + if [ -z "${VORTEX_DB_IMAGE:-}" ]; then echo "==> Database-in-image storage is not used. DB image deployment will not proceed."; exit 0; fi + if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> No freshly fetched database. DB image deployment will not proceed."; exit 0; fi + ./vendor/bin/vortex-push-db-image + timeout-minutes: 30 + + # Save cache per default branch and the timestamp. + # The cache will not be saved if it already exists. + # Note that the cache fallback flag is enabled for this case in order + # to save cache even if the fallback is not used when restoring it. + - name: Save DB cache + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 + if: env.db_hash != hashFiles('.data') + with: + path: .data + key: v26.8.1-${{ hashFiles('db_cache_branch') }}-${{ hashFiles('db_cache_fallback_yes') }}-${{ hashFiles('db_cache_timestamp') }} + + vortex-dev-didi-build-ii: + runs-on: ubuntu-latest + #;< !PROVISION_TYPE_PROFILE + needs: vortex-dev-database-ii + if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }} + #;> !PROVISION_TYPE_PROFILE + + permissions: + contents: read + checks: write + pull-requests: write + + strategy: + # A matrix to run multiple jobs in parallel. + matrix: + instance: [0, 1] + fail-fast: false + + env: + # Which tools run on this instance. Tools that only need to run once are + # pinned to the first instance. Add a line for every additional tool and + # reference it in that tool's step. + # https://www.vortextemplate.com/docs/continuous-integration#test-parallelism + VORTEX_CI_RUNNER_INDEX: ${{ strategy.job-index }} + VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} + #;< TOOL_JEST + VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} + #;> TOOL_JEST + #;< TOOL_PHPUNIT + VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} + #;> TOOL_PHPUNIT + #;< DRUPAL_THEME + #;< MODULE_SDC_DEVEL + VORTEX_CI_IS_SDC_DEVEL_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} + #;> MODULE_SDC_DEVEL + #;> DRUPAL_THEME + #;< TOOL_BEHAT + # Runs on every instance, using the `p` profile. + VORTEX_CI_IS_BEHAT_RUNNER: true + # Subtracted from the instance index to derive the profile number. Raise + # it by one for every leading instance that does not run Behat, so the + # first Behat instance still selects the `p0` catch-all profile. + VORTEX_CI_BEHAT_PROFILE_OFFSET: 0 + #;> TOOL_BEHAT + + container: + # https://hub.docker.com/r/drevops/ci-runner + image: drevops/ci-runner:26.10.0@sha256:36db4ee12da3372c86966fccd543e49c9470bca12e86eb5d4aad7904dd84a0dd + env: + PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }} + VORTEX_CONTAINER_REGISTRY_USER: ${{ secrets.VORTEX_CONTAINER_REGISTRY_USER }} + VORTEX_CONTAINER_REGISTRY_PASS: ${{ secrets.VORTEX_CONTAINER_REGISTRY_PASS }} + TZ: ${{ vars.TZ || 'UTC' }} + TERM: xterm-256color + # Disable strict host key checking for SSH connections. + VORTEX_SSH_DISABLE_STRICT_HOST_KEY_CHECKING: "1" + VORTEX_SSH_REMOVE_ALL_KEYS: "1" + VORTEX_DEBUG: ${{ vars.VORTEX_DEBUG }} + #;< !PROVISION_TYPE_PROFILE + # How often to refresh the cache of the DB dump. Refer to `date` command. + VORTEX_CI_DB_CACHE_TIMESTAMP: +%Y%m%d + # Use previous database caches on this branch as a fallback if the above cache + # does not match (for example, the cache is available only from the previous + # day). If "no" is set, the cache will be rebuilt from scratch. + VORTEX_CI_DB_CACHE_FALLBACK: "yes" + # Which branch to use as a source of DB caches. + VORTEX_CI_DB_CACHE_BRANCH: vortex-dev-didi-ii + #;> !PROVISION_TYPE_PROFILE + VORTEX_DB_IMAGE: drevops/vortex-dev-mariadb-drupal-data-demo-destination-11.x:vortex-dev-database-ii-gha + DRUPAL_MIGRATION_SKIP: 1 + + steps: + # Frees disk space by removing preinstalled toolchains unused by this project. Steps run in a container, so the host is reached via the Docker socket. + - name: Free up disk space on the runner + if: ${{ vars.VORTEX_CI_FREE_DISK_SPACE == '1' }} + run: | + set -- /host/usr/local/.ghcup /host/usr/share/swift /host/usr/local/share/powershell /host/usr/share/dotnet /host/opt/hostedtoolcache/CodeQL + # set -- "$@" /host/usr/local/lib/android # Removes about 10GB more, but takes about 50s. Uncomment to enable. + job_image=$(docker inspect --format '{{.Config.Image}}' "${HOSTNAME}" 2>/dev/null || echo alpine:3) + docker run --rm -v /:/host "${job_image}" rm -rf "$@" || true + + - name: Report disk usage + run: df -h + + - name: Preserve $HOME set in the container + run: echo HOME=/root >> "$GITHUB_ENV" # https://github.com/actions/runner/issues/863 + + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + persist-credentials: false + + - name: Fix Git ownership permissions + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + + - name: Process the codebase to run in CI + run: find . -name "docker-compose.yml" -print0 | xargs -0 -I {} sh -c "sed -i -e '/###/d' {} && sed -i -e 's/##//' {}" + + - name: Load environment variables from .env + run: t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && set +a && . "${t}" && env >> "$GITHUB_ENV" + + - name: Validate Composer configuration + run: composer validate --strict + continue-on-error: ${{ vars.VORTEX_CI_COMPOSER_VALIDATE_IGNORE_FAILURE == '1' }} + + - name: Install Vortex tooling + run: ./scripts/vortex-tooling.sh + + #;< !PROVISION_TYPE_PROFILE + - name: Create cache keys files for database caching + run: | + echo "${VORTEX_CI_DB_CACHE_BRANCH}" | tee db_cache_branch + echo "yes" | tee db_cache_fallback_yes + date "${VORTEX_CI_DB_CACHE_TIMESTAMP}" | tee db_cache_timestamp + + - name: Show cache key for database caching + run: echo 'v26.8.1-${{ hashFiles('db_cache_branch') }}-${{ hashFiles('db_cache_fallback_yes') }}-${{ hashFiles('db_cache_timestamp') }}' + + # Restore DB cache based on the cache strategy set by the cache keys below. + # Bump the last segment of the version prefix below to force a cache reset. + # Lookup cache based on the default branch and a timestamp. Allows + # to use cache from the very first build on the day (sanitized database dump, for example). + - name: Restore DB cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 + with: + path: .data + fail-on-cache-miss: true + # Use cached database from previous builds of this branch. + key: v26.8.1-${{ hashFiles('db_cache_branch') }}-${{ hashFiles('db_cache_fallback_yes') }}-${{ hashFiles('db_cache_timestamp') }} + restore-keys: | + v26.8.1-${{ hashFiles('db_cache_branch') }}-${{ hashFiles('db_cache_fallback_yes') }}- + #;> !PROVISION_TYPE_PROFILE + + - name: Login to container registry + run: ./vendor/bin/vortex-login-container-registry + + - name: Build stack + run: docker compose up --detach && docker builder prune --all --force && docker image prune --force + + - name: Export built codebase + if: ${{ matrix.instance == 0 && !startsWith(github.head_ref || github.ref_name, 'deps/') && contains(env.VORTEX_DEPLOY_TYPES, 'artifact') }} + run: | + mkdir -p "/tmp/workspace/code" "/tmp/artifacts" + docker compose --progress quiet cp -L cli:"/app/." "/tmp/workspace/code" + tar -C /tmp/workspace -cpf /tmp/artifacts/code.tar code + du -sh "/tmp/artifacts" + + - name: Install development dependencies + run: | + docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c " \ + if [ -n \"\${PACKAGE_TOKEN:-}\" ]; then composer config --global --auth github-oauth.github.com \"\${PACKAGE_TOKEN}\"; fi && \ + COMPOSER_MEMORY_LIMIT=-1 composer --ansi install --prefer-dist" + #;< TOOL_JEST + docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "npm ci" + #;> TOOL_JEST + + - name: Provision site + run: | + # Database dumps are removed from the runner once they are inside the + # container to avoid holding two copies for the rest of the job. + if [ -f .data/db.sql ]; then + docker compose exec cli mkdir -p .data + docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql + rm -f .data/db.sql + fi + #;< MIGRATION + if [ -f ".data/${VORTEX_FETCH_DB2_FILE:-db2.sql}" ]; then + docker compose exec -T cli mkdir -p .data + docker compose --progress quiet cp -L ".data/${VORTEX_FETCH_DB2_FILE:-db2.sql}" cli:"/app/.data/${VORTEX_FETCH_DB2_FILE:-db2.sql}" + rm -f ".data/${VORTEX_FETCH_DB2_FILE:-db2.sql}" + fi + #;> MIGRATION + docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli ./vendor/bin/vortex-provision + timeout-minutes: 30 + + #;< TOOL_JEST + - name: Test with Jest + if: ${{ env.VORTEX_CI_IS_JEST_RUNNER == 'true' }} + run: docker compose exec -T cli bash -c "npm test" + continue-on-error: ${{ vars.VORTEX_CI_JEST_IGNORE_FAILURE == '1' }} + #;> TOOL_JEST + + #;< TOOL_PHPUNIT + - name: Test with PHPUnit + if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' }} + run: docker compose exec -T cli vendor/bin/phpunit + continue-on-error: ${{ vars.VORTEX_CI_PHPUNIT_IGNORE_FAILURE == '1' }} + + - name: Process PHPUnit logs and coverage + if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' }} + run: | + mkdir -p ".logs" + if docker compose ps --services --filter "status=running" | grep -q cli && docker compose exec cli test -d /app/.logs; then + docker compose --progress quiet cp cli:/app/.logs/. ".logs/" + fi + + - name: Extract code coverage + if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' }} + run: | + RATE=$(grep -om1 'line-rate="[0-9.]*"' .logs/coverage/phpunit/cobertura.xml | tr -cd '0-9.') + PERCENT=$(awk "BEGIN {printf \"%.2f\", $RATE*100}") + echo "Coverage: $PERCENT% (threshold: $VORTEX_CI_CODE_COVERAGE_THRESHOLD%)" | tee -a "$GITHUB_STEP_SUMMARY" + { + echo "COVERAGE_PERCENT=${PERCENT}" + echo "COVERAGE_SUMMARY<> "$GITHUB_ENV" + env: + VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} + + - name: Post coverage summary as PR comment + if: ${{ github.event_name == 'pull_request' && env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' && vars.VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP != '1' }} + uses: marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3.0.5 + with: + header: coverage-gha + message: | + **Code coverage** (threshold: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }}%) + ``` + ${{ env.COVERAGE_SUMMARY }} + ``` +
+ Per-class coverage + + ``` + ${{ env.COVERAGE_DETAILS }} + ``` +
+ hide_and_recreate: true + + #;< CODE_COVERAGE_PROVIDER_CODECOV + - name: Upload coverage report to Codecov + uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7 + if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' && env.CODECOV_TOKEN != '' }} + continue-on-error: true + with: + directory: .logs/coverage + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + #;> CODE_COVERAGE_PROVIDER_CODECOV + + - name: Check code coverage threshold + if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' }} + run: | + if [ "${COVERAGE_PERCENT//.}" -lt "$((VORTEX_CI_CODE_COVERAGE_THRESHOLD*100))" ]; then + echo "FAIL: coverage ${COVERAGE_PERCENT}% is below threshold ${VORTEX_CI_CODE_COVERAGE_THRESHOLD}%" + exit 1 + fi + env: + VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} + #;> TOOL_PHPUNIT + + #;< DRUPAL_THEME + #;< MODULE_SDC_DEVEL + - name: Validate Single Directory Components + if: ${{ env.VORTEX_CI_IS_SDC_DEVEL_RUNNER == 'true' }} + run: | + [ "${VORTEX_FRONTEND_BUILD_SKIP:-0}" -eq 1 ] && exit 0 + output=$(docker compose exec -T cli vendor/bin/drush sdc-devel:validate "${DRUPAL_THEME}" 2>&1) + echo "${output}" + if echo "${output}" | grep -qE 'Critical|Errors?|Warnings?'; then + echo "SDC validation reported problems." + exit 1 + fi + continue-on-error: ${{ vars.VORTEX_CI_SDC_DEVEL_IGNORE_FAILURE == '1' }} + #;> MODULE_SDC_DEVEL + #;> DRUPAL_THEME + + #;< TOOL_BEHAT + - name: Test with Behat + if: ${{ env.VORTEX_CI_IS_BEHAT_RUNNER == 'true' }} + run: | + # shellcheck disable=SC2170 + if [ "${VORTEX_CI_RUNNER_TOTAL}" -gt 1 ]; then export VORTEX_CI_BEHAT_PROFILE="${VORTEX_CI_BEHAT_PROFILE:-p$((VORTEX_CI_RUNNER_INDEX - VORTEX_CI_BEHAT_PROFILE_OFFSET))}"; fi + echo "Running with ${VORTEX_CI_BEHAT_PROFILE:-default} profile" + docker compose exec -T -e BEHAT_SCREENSHOT_ANIMATION_SKIP=1 cli php -d memory_limit=-1 vendor/bin/behat --colors --strict --profile="${VORTEX_CI_BEHAT_PROFILE:-default}" || \ + docker compose exec -T -e BEHAT_SCREENSHOT_ANIMATION_SKIP=1 cli php -d memory_limit=-1 vendor/bin/behat --colors --strict --rerun --profile="${VORTEX_CI_BEHAT_PROFILE:-default}" + env: + VORTEX_CI_BEHAT_PROFILE: ${{ vars.VORTEX_CI_BEHAT_PROFILE }} + continue-on-error: ${{ vars.VORTEX_CI_BEHAT_IGNORE_FAILURE == '1' }} + timeout-minutes: 30 + #;> TOOL_BEHAT + + - name: Process test logs and artifacts + if: always() + run: | + mkdir -p ".logs" + if docker compose ps --services --filter "status=running" | grep -q cli && docker compose exec cli test -d /app/.logs; then + docker compose --progress quiet cp cli:/app/.logs/. ".logs/" + fi + + - name: Upload test artifacts + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 + if: always() + with: + name: test-artifacts-vortex-dev-didi-build-ii-${{ matrix.instance }} + path: .logs + include-hidden-files: true + if-no-files-found: error + + #;< TOOL_PHPUNIT_BEHAT + - name: Publish test results to GitHub Checks + if: ${{ !cancelled() && vars.VORTEX_CI_TEST_RESULTS_SKIP != '1' }} + uses: EnricoMi/publish-unit-test-result-action@d0a4676d0e0b938bc201470d88276b7c74c712b3 # v2.24.0 + with: + check_name: Test results vortex-dev-didi-build-ii (${{ matrix.instance }}) + comment_mode: "off" + test_file_prefix: "-/app/" + files: | + .logs/test_results/**/*.xml + #;> TOOL_PHPUNIT_BEHAT + + - name: Upload exported codebase as an artifact + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 + if: ${{ matrix.instance == 0 && !startsWith(github.head_ref || github.ref_name, 'deps/') && contains(env.VORTEX_DEPLOY_TYPES, 'artifact') }} + with: + name: code-artifact-vortex-dev-didi-build-ii + path: "/tmp/artifacts/code.tar" + include-hidden-files: true + if-no-files-found: error + retention-days: 1 + + # 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 + timeout-minutes: 120 # Cancel the action after 120 minutes, regardless of whether a connection has been established. + with: + detached: true diff --git a/.vortex/installer/tests/Fixtures/handler_process/_baseline/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/_baseline/.github/workflows/build-test-deploy.yml index 406b6e47ac..2fb1dd54a8 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/_baseline/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/_baseline/.github/workflows/build-test-deploy.yml @@ -229,14 +229,23 @@ jobs: - name: Process the codebase to run in CI run: find . -name "docker-compose.yml" -print0 | xargs -0 -I {} sh -c "sed -i -e '/###/d' {} && sed -i -e 's/##//' {}" + - name: Load environment variables from .env + run: t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && set +a && . "${t}" && env >> "$GITHUB_ENV" + - name: Install Vortex tooling run: ./scripts/vortex-tooling.sh - name: Adjust variables for a scheduled run if: github.event_name == 'schedule' run: | - echo "VORTEX_CI_DB_CACHE_FALLBACK=no" >> "$GITHUB_ENV" - echo "VORTEX_FRONTEND_BUILD_SKIP=1" >> "$GITHUB_ENV" + { + echo "VORTEX_CI_DB_CACHE_FALLBACK=no" + echo "VORTEX_FRONTEND_BUILD_SKIP=1" + # Import the fetched dump into a clean base image (if database-in-image storage is used). + echo "VORTEX_DB_IMAGE_BASE=drevops/mariadb-drupal-data:__VERSION__" + # Deploy container image (if database-in-image storage is used). + echo "VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED=1" + } >> "$GITHUB_ENV" - name: Create cache keys files for database caching run: | @@ -269,11 +278,37 @@ jobs: run: | if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi ./vendor/bin/vortex-login-container-registry + # A database built from the base image is empty, so it is + # provisioned from the dump file without the image. + if [ -n "${VORTEX_DB_IMAGE:-}" ] && [ -n "${VORTEX_DB_IMAGE_BASE:-}" ] && [ "${VORTEX_FETCH_DB_SOURCE:-url}" != "container_registry" ]; then + VORTEX_FETCH_DB_SOURCE=container_registry VORTEX_FETCH_DB_CONTAINER_REGISTRY_IMAGE_BASE="${VORTEX_DB_IMAGE_BASE}" ./vendor/bin/vortex-fetch-db + provision_opts="VORTEX_DB_IMAGE=" + fi docker compose up --detach && sleep 15 - docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql - docker compose exec cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ./vendor/bin/vortex-provision" + # The 'container_registry' source fetches an image without a dump file. + if [ -f .data/db.sql ]; then + docker compose exec cli mkdir -p .data + docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql + fi + docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" + # Database-in-image storage caches the exported image archive instead of the dump. + if [ -n "${VORTEX_DB_IMAGE:-}" ]; then rm -f .data/db.sql; fi ./vendor/bin/vortex-export-db db.sql - docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql + if [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql; then docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql; fi + # 'hashFiles()' runs as the runner user outside the container, so the + # root-owned files in '.data' must be readable by others. + chmod -R a+rX .data + timeout-minutes: 30 + + # Deploy the freshly-exported database image to the container registry. + # No-op unless a fresh DB was fetched (the fetch semaphore), the project + # uses database-in-image storage (VORTEX_DB_IMAGE), and deployment was + # requested (VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED, in the script). + - name: Deploy DB image + run: | + if [ -z "${VORTEX_DB_IMAGE:-}" ]; then echo "==> Database-in-image storage is not used. DB image deployment will not proceed."; exit 0; fi + if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> No freshly fetched database. DB image deployment will not proceed."; exit 0; fi + ./vendor/bin/vortex-push-db-image timeout-minutes: 30 # Save cache per default branch and the timestamp. diff --git a/.vortex/installer/tests/Fixtures/handler_process/ciprovider_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/ciprovider_circleci/.circleci/config.yml index bb5568f3e9..f42f37ebd6 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/ciprovider_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/ciprovider_circleci/.circleci/config.yml @@ -288,9 +288,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/code_coverage_provider_codecov/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/code_coverage_provider_codecov/.github/workflows/build-test-deploy.yml index 65a0cc3f96..f62063b248 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/code_coverage_provider_codecov/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/code_coverage_provider_codecov/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -490,6 +490,17 @@ +@@ -525,6 +525,17 @@ hide_and_recreate: true diff --git a/.vortex/installer/tests/Fixtures/handler_process/code_coverage_provider_codecov_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/code_coverage_provider_codecov_circleci/.circleci/config.yml index ca403c4fab..36afeb6a74 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/code_coverage_provider_codecov_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/code_coverage_provider_codecov_circleci/.circleci/config.yml @@ -288,9 +288,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/db_fetch_source_acquia/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/db_fetch_source_acquia/.github/workflows/build-test-deploy.yml index 65bea13f04..eca780a37f 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/db_fetch_source_acquia/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/db_fetch_source_acquia/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -264,6 +264,9 @@ +@@ -273,6 +273,9 @@ VORTEX_FETCH_DB_SEMAPHORE=/tmp/fetch-db-fresh ./vendor/bin/vortex-fetch-db echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" timeout-minutes: 30 diff --git a/.vortex/installer/tests/Fixtures/handler_process/deploy_types_all_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/deploy_types_all_circleci/.circleci/config.yml index bb5568f3e9..f42f37ebd6 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/deploy_types_all_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/deploy_types_all_circleci/.circleci/config.yml @@ -288,9 +288,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/deploy_types_none_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/deploy_types_none_circleci/.circleci/config.yml index be5b2d5bc8..2e74e1e1be 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/deploy_types_none_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/deploy_types_none_circleci/.circleci/config.yml @@ -288,9 +288,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/deploy_types_none_gha/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/deploy_types_none_gha/.github/workflows/build-test-deploy.yml index 24407e1e7d..2ac0562a78 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/deploy_types_none_gha/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/deploy_types_none_gha/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -573,104 +573,3 @@ +@@ -608,104 +608,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/installer/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.circleci/config.yml index bb5568f3e9..f42f37ebd6 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/deps_updates_provider_ci_circleci/.circleci/config.yml @@ -288,9 +288,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/hosting_acquia/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/hosting_acquia/.github/workflows/build-test-deploy.yml index 65bea13f04..eca780a37f 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/hosting_acquia/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/hosting_acquia/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -264,6 +264,9 @@ +@@ -273,6 +273,9 @@ VORTEX_FETCH_DB_SEMAPHORE=/tmp/fetch-db-fresh ./vendor/bin/vortex-fetch-db echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" timeout-minutes: 30 diff --git a/.vortex/installer/tests/Fixtures/handler_process/hosting_project_name___acquia/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/hosting_project_name___acquia/.github/workflows/build-test-deploy.yml index 65bea13f04..eca780a37f 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/hosting_project_name___acquia/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/hosting_project_name___acquia/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -264,6 +264,9 @@ +@@ -273,6 +273,9 @@ VORTEX_FETCH_DB_SEMAPHORE=/tmp/fetch-db-fresh ./vendor/bin/vortex-fetch-db echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" timeout-minutes: 30 diff --git a/.vortex/installer/tests/Fixtures/handler_process/migration_disabled_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/migration_disabled_circleci/.circleci/config.yml index bb5568f3e9..f42f37ebd6 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/migration_disabled_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/migration_disabled_circleci/.circleci/config.yml @@ -288,9 +288,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/migration_enabled/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/migration_enabled/.github/workflows/build-test-deploy.yml index 6b0198f141..99d706e50b 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/migration_enabled/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/migration_enabled/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -265,6 +265,9 @@ +@@ -274,6 +274,9 @@ echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" timeout-minutes: 30 @@ -8,7 +8,7 @@ - name: Export DB run: | if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi -@@ -431,6 +434,11 @@ +@@ -466,6 +469,11 @@ docker compose exec cli mkdir -p .data docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql rm -f .data/db.sql diff --git a/.vortex/installer/tests/Fixtures/handler_process/migration_enabled_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/migration_enabled_circleci/.circleci/config.yml index e15e70fb08..549657afb0 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/migration_enabled_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/migration_enabled_circleci/.circleci/config.yml @@ -293,9 +293,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/migration_enabled_lagoon/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/migration_enabled_lagoon/.github/workflows/build-test-deploy.yml index 6b0198f141..99d706e50b 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/migration_enabled_lagoon/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/migration_enabled_lagoon/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -265,6 +265,9 @@ +@@ -274,6 +274,9 @@ echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" timeout-minutes: 30 @@ -8,7 +8,7 @@ - name: Export DB run: | if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi -@@ -431,6 +434,11 @@ +@@ -466,6 +469,11 @@ docker compose exec cli mkdir -p .data docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql rm -f .data/db.sql diff --git a/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_acquia/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_acquia/.github/workflows/build-test-deploy.yml index 6b0198f141..99d706e50b 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_acquia/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_acquia/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -265,6 +265,9 @@ +@@ -274,6 +274,9 @@ echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" timeout-minutes: 30 @@ -8,7 +8,7 @@ - name: Export DB run: | if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi -@@ -431,6 +434,11 @@ +@@ -466,6 +469,11 @@ docker compose exec cli mkdir -p .data docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql rm -f .data/db.sql diff --git a/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_container_registry/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_container_registry/.github/workflows/build-test-deploy.yml index 6b0198f141..99d706e50b 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_container_registry/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_container_registry/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -265,6 +265,9 @@ +@@ -274,6 +274,9 @@ echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" timeout-minutes: 30 @@ -8,7 +8,7 @@ - name: Export DB run: | if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi -@@ -431,6 +434,11 @@ +@@ -466,6 +469,11 @@ docker compose exec cli mkdir -p .data docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql rm -f .data/db.sql diff --git a/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_ftp/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_ftp/.github/workflows/build-test-deploy.yml index 6b0198f141..99d706e50b 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_ftp/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_ftp/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -265,6 +265,9 @@ +@@ -274,6 +274,9 @@ echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" timeout-minutes: 30 @@ -8,7 +8,7 @@ - name: Export DB run: | if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi -@@ -431,6 +434,11 @@ +@@ -466,6 +469,11 @@ docker compose exec cli mkdir -p .data docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql rm -f .data/db.sql diff --git a/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_lagoon/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_lagoon/.github/workflows/build-test-deploy.yml index 6b0198f141..99d706e50b 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_lagoon/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_lagoon/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -265,6 +265,9 @@ +@@ -274,6 +274,9 @@ echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" timeout-minutes: 30 @@ -8,7 +8,7 @@ - name: Export DB run: | if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi -@@ -431,6 +434,11 @@ +@@ -466,6 +469,11 @@ docker compose exec cli mkdir -p .data docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql rm -f .data/db.sql diff --git a/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_s3/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_s3/.github/workflows/build-test-deploy.yml index 6b0198f141..99d706e50b 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_s3/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_s3/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -265,6 +265,9 @@ +@@ -274,6 +274,9 @@ echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" timeout-minutes: 30 @@ -8,7 +8,7 @@ - name: Export DB run: | if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi -@@ -431,6 +434,11 @@ +@@ -466,6 +469,11 @@ docker compose exec cli mkdir -p .data docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql rm -f .data/db.sql diff --git a/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_url/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_url/.github/workflows/build-test-deploy.yml index 6b0198f141..99d706e50b 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_url/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/migration_fetch_source_url/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -265,6 +265,9 @@ +@@ -274,6 +274,9 @@ echo "db_hash=${{ hashFiles('.data') }}" >> "$GITHUB_ENV" timeout-minutes: 30 @@ -8,7 +8,7 @@ - name: Export DB run: | if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi -@@ -431,6 +434,11 @@ +@@ -466,6 +469,11 @@ docker compose exec cli mkdir -p .data docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql rm -f .data/db.sql diff --git a/.vortex/installer/tests/Fixtures/handler_process/modules_no_dev_modules_storybook/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/modules_no_dev_modules_storybook/.github/workflows/build-test-deploy.yml index c0b7f62c2c..92b9ac668f 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/modules_no_dev_modules_storybook/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/modules_no_dev_modules_storybook/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -312,7 +312,6 @@ +@@ -347,7 +347,6 @@ VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -6,7 +6,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -499,18 +498,6 @@ +@@ -534,18 +533,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel/.github/workflows/build-test-deploy.yml index c0b7f62c2c..92b9ac668f 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -312,7 +312,6 @@ +@@ -347,7 +347,6 @@ VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -6,7 +6,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -499,18 +498,6 @@ +@@ -534,18 +533,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel_generated_content/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel_generated_content/.github/workflows/build-test-deploy.yml index c0b7f62c2c..92b9ac668f 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel_generated_content/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel_generated_content/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -312,7 +312,6 @@ +@@ -347,7 +347,6 @@ VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -6,7 +6,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -499,18 +498,6 @@ +@@ -534,18 +533,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel_generated_content_testmode/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel_generated_content_testmode/.github/workflows/build-test-deploy.yml index c0b7f62c2c..92b9ac668f 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel_generated_content_testmode/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel_generated_content_testmode/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -312,7 +312,6 @@ +@@ -347,7 +347,6 @@ VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -6,7 +6,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -499,18 +498,6 @@ +@@ -534,18 +533,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel_generated_content_testmode_reroute_email/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel_generated_content_testmode_reroute_email/.github/workflows/build-test-deploy.yml index c0b7f62c2c..92b9ac668f 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel_generated_content_testmode_reroute_email/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/modules_no_devel_sdc_devel_generated_content_testmode_reroute_email/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -312,7 +312,6 @@ +@@ -347,7 +347,6 @@ VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -6,7 +6,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -499,18 +498,6 @@ +@@ -534,18 +533,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/modules_no_sdc_devel/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/modules_no_sdc_devel/.github/workflows/build-test-deploy.yml index c0b7f62c2c..92b9ac668f 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/modules_no_sdc_devel/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/modules_no_sdc_devel/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -312,7 +312,6 @@ +@@ -347,7 +347,6 @@ VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -6,7 +6,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -499,18 +498,6 @@ +@@ -534,18 +533,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/modules_none/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/modules_none/.github/workflows/build-test-deploy.yml index c0b7f62c2c..92b9ac668f 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/modules_none/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/modules_none/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -312,7 +312,6 @@ +@@ -347,7 +347,6 @@ VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -6,7 +6,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -499,18 +498,6 @@ +@@ -534,18 +533,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/provision_profile/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/provision_profile/.github/workflows/build-test-deploy.yml index 194b1600d3..eb70975dc9 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/provision_profile/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/provision_profile/.github/workflows/build-test-deploy.yml @@ -15,7 +15,7 @@ container: # https://hub.docker.com/r/drevops/ci-runner -@@ -167,130 +164,8 @@ +@@ -167,165 +164,8 @@ run: docker compose exec -T cli bash -c "npm --prefix=\${WEBROOT}/themes/custom/\${DRUPAL_THEME} run lint" continue-on-error: ${{ vars.VORTEX_CI_NODEJS_LINT_IGNORE_FAILURE == '1' }} @@ -81,14 +81,23 @@ - - name: Process the codebase to run in CI - run: find . -name "docker-compose.yml" -print0 | xargs -0 -I {} sh -c "sed -i -e '/###/d' {} && sed -i -e 's/##//' {}" - +- - name: Load environment variables from .env +- run: t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && set +a && . "${t}" && env >> "$GITHUB_ENV" +- - - name: Install Vortex tooling - run: ./scripts/vortex-tooling.sh - - - name: Adjust variables for a scheduled run - if: github.event_name == 'schedule' - run: | -- echo "VORTEX_CI_DB_CACHE_FALLBACK=no" >> "$GITHUB_ENV" -- echo "VORTEX_FRONTEND_BUILD_SKIP=1" >> "$GITHUB_ENV" +- { +- echo "VORTEX_CI_DB_CACHE_FALLBACK=no" +- echo "VORTEX_FRONTEND_BUILD_SKIP=1" +- # Import the fetched dump into a clean base image (if database-in-image storage is used). +- echo "VORTEX_DB_IMAGE_BASE=drevops/mariadb-drupal-data:__VERSION__" +- # Deploy container image (if database-in-image storage is used). +- echo "VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED=1" +- } >> "$GITHUB_ENV" - - - name: Create cache keys files for database caching - run: | @@ -121,11 +130,37 @@ - run: | - if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> Database fetch semaphore file is missing. DB export will not proceed."; exit 0; fi - ./vendor/bin/vortex-login-container-registry +- # A database built from the base image is empty, so it is +- # provisioned from the dump file without the image. +- if [ -n "${VORTEX_DB_IMAGE:-}" ] && [ -n "${VORTEX_DB_IMAGE_BASE:-}" ] && [ "${VORTEX_FETCH_DB_SOURCE:-url}" != "container_registry" ]; then +- VORTEX_FETCH_DB_SOURCE=container_registry VORTEX_FETCH_DB_CONTAINER_REGISTRY_IMAGE_BASE="${VORTEX_DB_IMAGE_BASE}" ./vendor/bin/vortex-fetch-db +- provision_opts="VORTEX_DB_IMAGE=" +- fi - docker compose up --detach && sleep 15 -- docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql -- docker compose exec cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ./vendor/bin/vortex-provision" +- # The 'container_registry' source fetches an image without a dump file. +- if [ -f .data/db.sql ]; then +- docker compose exec cli mkdir -p .data +- docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql +- fi +- docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" +- # Database-in-image storage caches the exported image archive instead of the dump. +- if [ -n "${VORTEX_DB_IMAGE:-}" ]; then rm -f .data/db.sql; fi - ./vendor/bin/vortex-export-db db.sql -- docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql +- if [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql; then docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql; fi +- # 'hashFiles()' runs as the runner user outside the container, so the +- # root-owned files in '.data' must be readable by others. +- chmod -R a+rX .data +- timeout-minutes: 30 +- +- # Deploy the freshly-exported database image to the container registry. +- # No-op unless a fresh DB was fetched (the fetch semaphore), the project +- # uses database-in-image storage (VORTEX_DB_IMAGE), and deployment was +- # requested (VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED, in the script). +- - name: Deploy DB image +- run: | +- if [ -z "${VORTEX_DB_IMAGE:-}" ]; then echo "==> Database-in-image storage is not used. DB image deployment will not proceed."; exit 0; fi +- if [ ! -f /tmp/fetch-db-fresh ]; then echo "==> No freshly fetched database. DB image deployment will not proceed."; exit 0; fi +- ./vendor/bin/vortex-push-db-image - timeout-minutes: 30 - - # Save cache per default branch and the timestamp. @@ -146,7 +181,7 @@ permissions: contents: read -@@ -333,14 +208,6 @@ +@@ -368,14 +208,6 @@ VORTEX_SSH_DISABLE_STRICT_HOST_KEY_CHECKING: "1" VORTEX_SSH_REMOVE_ALL_KEYS: "1" VORTEX_DEBUG: ${{ vars.VORTEX_DEBUG }} @@ -161,7 +196,7 @@ steps: # Frees disk space by removing preinstalled toolchains unused by this project. Steps run in a container, so the host is reached via the Docker socket. -@@ -379,29 +246,6 @@ +@@ -414,29 +246,6 @@ - name: Install Vortex tooling run: ./scripts/vortex-tooling.sh @@ -191,7 +226,7 @@ - name: Login to container registry run: ./vendor/bin/vortex-login-container-registry -@@ -577,7 +421,6 @@ +@@ -612,7 +421,6 @@ deploy: runs-on: ubuntu-latest needs: [build, lint] diff --git a/.vortex/installer/tests/Fixtures/handler_process/theme_claro/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/theme_claro/.github/workflows/build-test-deploy.yml index da2e5188f3..f4af385e6a 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/theme_claro/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/theme_claro/.github/workflows/build-test-deploy.yml @@ -10,7 +10,7 @@ database: runs-on: ubuntu-latest if: ${{ !inputs.deploy_target && (github.event_name == 'push' || !startsWith(github.head_ref, 'project/')) }} -@@ -312,7 +307,6 @@ +@@ -347,7 +342,6 @@ VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -18,7 +18,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -499,18 +493,6 @@ +@@ -534,18 +528,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/theme_olivero/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/theme_olivero/.github/workflows/build-test-deploy.yml index da2e5188f3..f4af385e6a 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/theme_olivero/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/theme_olivero/.github/workflows/build-test-deploy.yml @@ -10,7 +10,7 @@ database: runs-on: ubuntu-latest if: ${{ !inputs.deploy_target && (github.event_name == 'push' || !startsWith(github.head_ref, 'project/')) }} -@@ -312,7 +307,6 @@ +@@ -347,7 +342,6 @@ VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -18,7 +18,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -499,18 +493,6 @@ +@@ -534,18 +528,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/theme_stark/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/theme_stark/.github/workflows/build-test-deploy.yml index da2e5188f3..f4af385e6a 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/theme_stark/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/theme_stark/.github/workflows/build-test-deploy.yml @@ -10,7 +10,7 @@ database: runs-on: ubuntu-latest if: ${{ !inputs.deploy_target && (github.event_name == 'push' || !startsWith(github.head_ref, 'project/')) }} -@@ -312,7 +307,6 @@ +@@ -347,7 +342,6 @@ VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -18,7 +18,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -499,18 +493,6 @@ +@@ -534,18 +528,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/timezone_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/timezone_circleci/.circleci/config.yml index bb5568f3e9..f42f37ebd6 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/timezone_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/timezone_circleci/.circleci/config.yml @@ -288,9 +288,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.circleci/config.yml index cb4ae70490..84bfb46065 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_lint_circleci/.circleci/config.yml @@ -276,9 +276,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_tests/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_tests/.github/workflows/build-test-deploy.yml index 2f4b0324b6..b4878ded43 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_tests/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_tests/.github/workflows/build-test-deploy.yml @@ -9,7 +9,7 @@ - name: Lint module code with NodeJS linters run: docker compose exec -T cli bash -c "npm run lint" continue-on-error: ${{ vars.VORTEX_CI_NODEJS_LINT_IGNORE_FAILURE == '1' }} -@@ -311,14 +307,7 @@ +@@ -346,14 +342,7 @@ VORTEX_CI_RUNNER_INDEX: ${{ strategy.job-index }} VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -24,7 +24,7 @@ container: # https://hub.docker.com/r/drevops/ci-runner -@@ -440,66 +429,6 @@ +@@ -475,66 +464,6 @@ run: docker compose exec -T cli bash -c "npm test" continue-on-error: ${{ vars.VORTEX_CI_JEST_IGNORE_FAILURE == '1' }} @@ -91,7 +91,7 @@ - name: Validate Single Directory Components if: ${{ env.VORTEX_CI_IS_SDC_DEVEL_RUNNER == 'true' }} run: | -@@ -512,19 +441,6 @@ +@@ -547,19 +476,6 @@ fi continue-on-error: ${{ vars.VORTEX_CI_SDC_DEVEL_IGNORE_FAILURE == '1' }} @@ -111,7 +111,7 @@ - name: Process test logs and artifacts if: always() run: | -@@ -541,16 +457,6 @@ +@@ -576,16 +492,6 @@ path: .logs include-hidden-files: true if-no-files-found: error diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.circleci/config.yml index 58e78d747b..e3d9af79d1 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_be_tests_circleci/.circleci/config.yml @@ -284,9 +284,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint/.github/workflows/build-test-deploy.yml index 452179b6d7..7ec67fee1c 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint/.github/workflows/build-test-deploy.yml @@ -22,7 +22,7 @@ database: runs-on: ubuntu-latest if: ${{ !inputs.deploy_target && (github.event_name == 'push' || !startsWith(github.head_ref, 'project/')) }} -@@ -310,7 +300,6 @@ +@@ -345,7 +335,6 @@ # https://www.vortextemplate.com/docs/continuous-integration#test-parallelism VORTEX_CI_RUNNER_INDEX: ${{ strategy.job-index }} VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} @@ -30,7 +30,7 @@ VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_SDC_DEVEL_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} # Runs on every instance, using the `p` profile. -@@ -421,7 +410,6 @@ +@@ -456,7 +445,6 @@ docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c " \ if [ -n \"\${PACKAGE_TOKEN:-}\" ]; then composer config --global --auth github-oauth.github.com \"\${PACKAGE_TOKEN}\"; fi && \ COMPOSER_MEMORY_LIMIT=-1 composer --ansi install --prefer-dist" @@ -38,7 +38,7 @@ - name: Provision site run: | -@@ -434,11 +422,6 @@ +@@ -469,11 +457,6 @@ fi docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli ./vendor/bin/vortex-provision timeout-minutes: 30 diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.circleci/config.yml index 0fba76983a..c820eeba01 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_circleci/.circleci/config.yml @@ -267,9 +267,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme/.github/workflows/build-test-deploy.yml index 8ffe668f17..3e4f83d427 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme/.github/workflows/build-test-deploy.yml @@ -22,7 +22,7 @@ database: runs-on: ubuntu-latest if: ${{ !inputs.deploy_target && (github.event_name == 'push' || !startsWith(github.head_ref, 'project/')) }} -@@ -310,9 +300,7 @@ +@@ -345,9 +335,7 @@ # https://www.vortextemplate.com/docs/continuous-integration#test-parallelism VORTEX_CI_RUNNER_INDEX: ${{ strategy.job-index }} VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} @@ -32,7 +32,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -421,7 +409,6 @@ +@@ -456,7 +444,6 @@ docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c " \ if [ -n \"\${PACKAGE_TOKEN:-}\" ]; then composer config --global --auth github-oauth.github.com \"\${PACKAGE_TOKEN}\"; fi && \ COMPOSER_MEMORY_LIMIT=-1 composer --ansi install --prefer-dist" @@ -40,7 +40,7 @@ - name: Provision site run: | -@@ -435,11 +422,6 @@ +@@ -470,11 +457,6 @@ docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli ./vendor/bin/vortex-provision timeout-minutes: 30 @@ -52,7 +52,7 @@ - name: Test with PHPUnit if: ${{ env.VORTEX_CI_IS_PHPUNIT_RUNNER == 'true' }} run: docker compose exec -T cli vendor/bin/phpunit -@@ -499,18 +481,6 @@ +@@ -534,18 +516,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.circleci/config.yml index b300ef7498..15f2bfb6d5 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_groups_no_fe_lint_no_theme_circleci/.circleci/config.yml @@ -258,9 +258,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_behat/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_behat/.github/workflows/build-test-deploy.yml index 0b32b5b70d..8acbb7c92c 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_behat/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_behat/.github/workflows/build-test-deploy.yml @@ -9,7 +9,7 @@ - name: Lint module code with NodeJS linters run: docker compose exec -T cli bash -c "npm run lint" continue-on-error: ${{ vars.VORTEX_CI_NODEJS_LINT_IGNORE_FAILURE == '1' }} -@@ -313,12 +309,6 @@ +@@ -348,12 +344,6 @@ VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_SDC_DEVEL_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -22,7 +22,7 @@ container: # https://hub.docker.com/r/drevops/ci-runner -@@ -511,19 +501,6 @@ +@@ -546,19 +536,6 @@ exit 1 fi continue-on-error: ${{ vars.VORTEX_CI_SDC_DEVEL_IGNORE_FAILURE == '1' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_behat_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_behat_circleci/.circleci/config.yml index e54b1c55a7..e4d578877d 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_behat_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_behat_circleci/.circleci/config.yml @@ -284,9 +284,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_circleci/.circleci/config.yml index d7090ba67d..e945b7013d 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_dclint_circleci/.circleci/config.yml @@ -284,9 +284,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.circleci/config.yml index 37f95ad1ee..5b5a387527 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_docker_linters_circleci/.circleci/config.yml @@ -277,9 +277,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_eslint_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_eslint_circleci/.circleci/config.yml index 00a5f937e9..fb4bc31dd5 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_eslint_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_eslint_circleci/.circleci/config.yml @@ -277,9 +277,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_eslint_no_theme/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_eslint_no_theme/.github/workflows/build-test-deploy.yml index a46c4f9ab9..ecf24d9a18 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_eslint_no_theme/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_eslint_no_theme/.github/workflows/build-test-deploy.yml @@ -22,7 +22,7 @@ database: runs-on: ubuntu-latest if: ${{ !inputs.deploy_target && (github.event_name == 'push' || !startsWith(github.head_ref, 'project/')) }} -@@ -312,7 +302,6 @@ +@@ -347,7 +337,6 @@ VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -30,7 +30,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -499,18 +488,6 @@ +@@ -534,18 +523,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.circleci/config.yml index 4d8c5cb1de..298ad9d1dc 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_hadolint_circleci/.circleci/config.yml @@ -281,9 +281,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_jest/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_jest/.github/workflows/build-test-deploy.yml index a4847a4654..0be154b19b 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_jest/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_jest/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -310,7 +310,6 @@ +@@ -345,7 +345,6 @@ # https://www.vortextemplate.com/docs/continuous-integration#test-parallelism VORTEX_CI_RUNNER_INDEX: ${{ strategy.job-index }} VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} @@ -6,7 +6,7 @@ VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_SDC_DEVEL_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} # Runs on every instance, using the `p` profile. -@@ -421,7 +420,6 @@ +@@ -456,7 +455,6 @@ docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c " \ if [ -n \"\${PACKAGE_TOKEN:-}\" ]; then composer config --global --auth github-oauth.github.com \"\${PACKAGE_TOKEN}\"; fi && \ COMPOSER_MEMORY_LIMIT=-1 composer --ansi install --prefer-dist" @@ -14,7 +14,7 @@ - name: Provision site run: | -@@ -434,11 +432,6 @@ +@@ -469,11 +467,6 @@ fi docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli ./vendor/bin/vortex-provision timeout-minutes: 30 diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_jest_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_jest_circleci/.circleci/config.yml index dad7a8215d..72df6286d9 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_jest_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_jest_circleci/.circleci/config.yml @@ -288,9 +288,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.circleci/config.yml index da3b323c76..a44c66c0de 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpcs_circleci/.circleci/config.yml @@ -284,9 +284,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.circleci/config.yml index cda6886ab4..950a9690cb 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpstan_circleci/.circleci/config.yml @@ -284,9 +284,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpunit/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpunit/.github/workflows/build-test-deploy.yml index 1046500b0a..f31360766a 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpunit/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpunit/.github/workflows/build-test-deploy.yml @@ -1,4 +1,4 @@ -@@ -311,7 +311,6 @@ +@@ -346,7 +346,6 @@ VORTEX_CI_RUNNER_INDEX: ${{ strategy.job-index }} VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -6,7 +6,7 @@ VORTEX_CI_IS_SDC_DEVEL_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true -@@ -440,66 +439,6 @@ +@@ -475,66 +474,6 @@ run: docker compose exec -T cli bash -c "npm test" continue-on-error: ${{ vars.VORTEX_CI_JEST_IGNORE_FAILURE == '1' }} @@ -73,7 +73,7 @@ - name: Validate Single Directory Components if: ${{ env.VORTEX_CI_IS_SDC_DEVEL_RUNNER == 'true' }} run: | -@@ -541,16 +480,6 @@ +@@ -576,16 +515,6 @@ path: .logs include-hidden-files: true if-no-files-found: error diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.circleci/config.yml index 0cd1dfcd77..6e02c4711e 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_phpunit_circleci/.circleci/config.yml @@ -288,9 +288,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_rector_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_rector_circleci/.circleci/config.yml index 6133b4aab4..1677012460 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_rector_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_rector_circleci/.circleci/config.yml @@ -284,9 +284,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.circleci/config.yml index bb5568f3e9..f42f37ebd6 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_stylelint_circleci/.circleci/config.yml @@ -288,9 +288,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_stylelint_no_theme/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_stylelint_no_theme/.github/workflows/build-test-deploy.yml index da2e5188f3..f4af385e6a 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_stylelint_no_theme/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_stylelint_no_theme/.github/workflows/build-test-deploy.yml @@ -10,7 +10,7 @@ database: runs-on: ubuntu-latest if: ${{ !inputs.deploy_target && (github.event_name == 'push' || !startsWith(github.head_ref, 'project/')) }} -@@ -312,7 +307,6 @@ +@@ -347,7 +342,6 @@ VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} VORTEX_CI_IS_JEST_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} VORTEX_CI_IS_PHPUNIT_RUNNER: ${{ matrix.instance == 0 || strategy.job-total == 1 }} @@ -18,7 +18,7 @@ # Runs on every instance, using the `p` profile. VORTEX_CI_IS_BEHAT_RUNNER: true # Subtracted from the instance index to derive the profile number. Raise -@@ -499,18 +493,6 @@ +@@ -534,18 +528,6 @@ fi env: VORTEX_CI_CODE_COVERAGE_THRESHOLD: ${{ vars.VORTEX_CI_CODE_COVERAGE_THRESHOLD || '90' }} diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_no_twig_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_no_twig_circleci/.circleci/config.yml index 8e1d9d0e85..5f5c299975 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_no_twig_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_no_twig_circleci/.circleci/config.yml @@ -284,9 +284,10 @@ jobs: docker compose up --detach && sleep 15 docker compose exec cli mkdir -p .data && docker compose --progress quiet cp -L .data/db.sql cli:/app/.data/db.sql || true docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c "VORTEX_PROVISION_POST_OPERATIONS_SKIP=1 ${provision_opts:-} ./vendor/bin/vortex-provision" - grep -q ^VORTEX_DB_IMAGE .env && rm .data/db.sql || true + # Database-in-image storage caches the exported image archive instead of the dump. + [ -n "${VORTEX_DB_IMAGE:-}" ] && rm -f .data/db.sql || true ./vendor/bin/vortex-export-db db.sql - docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true + [ -z "${VORTEX_DB_IMAGE:-}" ] && docker compose exec -T cli test -f /app/.data/db.sql && docker compose --progress quiet cp -L cli:/app/.data/db.sql .data/db.sql || true no_output_timeout: 30m # Deploy the freshly-exported database image to the container registry. diff --git a/.vortex/installer/tests/Fixtures/handler_process/tools_none/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/handler_process/tools_none/.github/workflows/build-test-deploy.yml index 4ab2193e11..3012555fcf 100644 --- a/.vortex/installer/tests/Fixtures/handler_process/tools_none/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/handler_process/tools_none/.github/workflows/build-test-deploy.yml @@ -58,7 +58,7 @@ database: runs-on: ubuntu-latest if: ${{ !inputs.deploy_target && (github.event_name == 'push' || !startsWith(github.head_ref, 'project/')) }} -@@ -310,15 +269,7 @@ +@@ -345,15 +304,7 @@ # https://www.vortextemplate.com/docs/continuous-integration#test-parallelism VORTEX_CI_RUNNER_INDEX: ${{ strategy.job-index }} VORTEX_CI_RUNNER_TOTAL: ${{ strategy.job-total }} @@ -74,7 +74,7 @@ container: # https://hub.docker.com/r/drevops/ci-runner -@@ -421,7 +372,6 @@ +@@ -456,7 +407,6 @@ docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli bash -c " \ if [ -n \"\${PACKAGE_TOKEN:-}\" ]; then composer config --global --auth github-oauth.github.com \"\${PACKAGE_TOKEN}\"; fi && \ COMPOSER_MEMORY_LIMIT=-1 composer --ansi install --prefer-dist" @@ -82,7 +82,7 @@ - name: Provision site run: | -@@ -435,71 +385,6 @@ +@@ -470,71 +420,6 @@ docker compose exec $(env | cut -f1 -d= | sed 's/^/-e /') -T cli ./vendor/bin/vortex-provision timeout-minutes: 30 @@ -154,7 +154,7 @@ - name: Validate Single Directory Components if: ${{ env.VORTEX_CI_IS_SDC_DEVEL_RUNNER == 'true' }} run: | -@@ -512,19 +397,6 @@ +@@ -547,19 +432,6 @@ fi continue-on-error: ${{ vars.VORTEX_CI_SDC_DEVEL_IGNORE_FAILURE == '1' }} @@ -174,7 +174,7 @@ - name: Process test logs and artifacts if: always() run: | -@@ -541,16 +413,6 @@ +@@ -576,16 +448,6 @@ path: .logs include-hidden-files: true if-no-files-found: error diff --git a/.vortex/tests/generate-vortex-dev-gha b/.vortex/tests/generate-vortex-dev-gha new file mode 100755 index 0000000000..062ac08afd --- /dev/null +++ b/.vortex/tests/generate-vortex-dev-gha @@ -0,0 +1,353 @@ +#!/usr/bin/env php + 'url', + 'VORTEX_FETCH_DB_FORCE' => 1, + 'VORTEX_DB_IMAGE' => $db_image, + 'VORTEX_DB_IMAGE_BASE' => $db_image_base, + 'COMPOSE_PROGRESS' => 'plain', + 'VORTEX_PUSH_CONTAINER_REGISTRY_IMAGE_TAG' => $db_image_tag_fi, + 'VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED' => 1, + 'VORTEX_CI_DB_CACHE_BRANCH' => 'vortex-dev-didi-fi', + ]), + '', + build_variant_workflow_job($build_job, 'vortex-dev-didi-build-fi', build_job_replacements('vortex-dev-didi-build-fi', 'vortex-dev-didi-database-fi'), [ + 'VORTEX_DB_IMAGE' => $db_image . ':' . $db_image_tag_fi, + 'VORTEX_CI_DB_CACHE_BRANCH' => 'vortex-dev-didi-fi', + 'DRUPAL_MIGRATION_SKIP' => 1, + ]), + '', + ' # DIDI-II variant jobs', + build_variant_workflow_job($database_job, 'vortex-dev-database-ii', [], [ + 'VORTEX_FETCH_DB_SOURCE' => 'container_registry', + 'VORTEX_FETCH_DB_FORCE' => 1, + 'VORTEX_DB_IMAGE' => $db_image, + 'COMPOSE_PROGRESS' => 'plain', + 'VORTEX_PUSH_CONTAINER_REGISTRY_IMAGE_TAG' => $db_image_tag_ii, + 'VORTEX_EXPORT_DB_CONTAINER_REGISTRY_PUSH_PROCEED' => 1, + 'VORTEX_CI_DB_CACHE_BRANCH' => 'vortex-dev-didi-ii', + ]), + '', + build_variant_workflow_job($build_job, 'vortex-dev-didi-build-ii', build_job_replacements('vortex-dev-didi-build-ii', 'vortex-dev-database-ii'), [ + 'VORTEX_DB_IMAGE' => $db_image . ':' . $db_image_tag_ii, + 'VORTEX_CI_DB_CACHE_BRANCH' => 'vortex-dev-didi-ii', + 'DRUPAL_MIGRATION_SKIP' => 1, + ]), + '', +]); + +if ($check_mode) { + if (!file_exists($output_file)) { + fwrite(STDERR, sprintf("Error: %s does not exist. Run without --check to generate.\n", $output_file)); + exit(1); + } + + $existing = file_get_contents($output_file); + if ($existing !== $output) { + fwrite(STDERR, sprintf("Error: %s is out of date. Run 'php .vortex/tests/generate-vortex-dev-gha' to update.\n", $output_file)); + exit(1); + } + + echo sprintf("OK: %s is up to date.\n", $output_file); + exit(0); +} + +file_put_contents($output_file, $output); +echo sprintf("Generated: %s\n", $output_file); + +/** + * Extract the workflow-level settings from the source lines. + * + * Takes the lines from the first 'defaults', 'env' or 'permissions' key up to + * the 'jobs' key. + * + * @param list $lines + * Source file lines. + */ +function extract_settings(array $lines): string { + $start = NULL; + $end = NULL; + + foreach ($lines as $i => $line) { + if ($start === NULL && preg_match('/^(defaults|env|permissions):/', $line)) { + $start = $i; + } + + if ($start !== NULL && preg_match('/^jobs:/', $line)) { + $end = $i; + break; + } + } + + if ($start === NULL || $end === NULL) { + fwrite(STDERR, "Error: Could not find workflow settings.\n"); + exit(1); + } + + $result = array_slice($lines, $start, $end - $start); + + // Trim trailing blank lines. + while (!empty($result) && trim(end($result)) === '') { + array_pop($result); + } + + return implode("\n", $result); +} + +/** + * Extract a job block from the source lines. + * + * @param list $lines + * Source file lines. + */ +function extract_workflow_job(array $lines, string $pattern): string { + $start = NULL; + + for ($i = 0, $count = count($lines); $i < $count; $i++) { + if (preg_match($pattern, $lines[$i])) { + $start = $i; + break; + } + } + + if ($start === NULL) { + fwrite(STDERR, sprintf("Error: Could not find job matching %s.\n", $pattern)); + exit(1); + } + + $result = [$lines[$start]]; + + for ($i = $start + 1, $count = count($lines); $i < $count; $i++) { + $line = $lines[$i]; + // Stop at the next block at job level (2-space indent) or top level. + if ($line !== '' && (preg_match('/^ \S/', $line) || preg_match('/^\S/', $line))) { + break; + } + $result[] = $line; + } + + // Trim trailing blank lines. + while (!empty($result) && trim(end($result)) === '') { + array_pop($result); + } + + return implode("\n", $result); +} + +/** + * Extract the value a job step writes to $GITHUB_ENV for a variable. + * + * @param list $lines + * Job block lines. + */ +function extract_github_env_value(array $lines, string $name): string { + foreach ($lines as $line) { + if (preg_match('/echo "' . preg_quote($name, '/') . '=([^"]+)"/', $line, $matches)) { + return $matches[1]; + } + } + + fwrite(STDERR, sprintf("Error: Could not find %s written to \$GITHUB_ENV.\n", $name)); + exit(1); +} + +/** + * Build a DIDI variant job YAML block from a source job block. + * + * @param string $job + * Source job block. + * @param string $name + * Variant job name. + * @param array $replacements + * Replacement strings keyed by the string they replace. + * @param array $env + * Container environment variable overrides. + */ +function build_variant_workflow_job(string $job, string $name, array $replacements, array $env): string { + $lines = explode("\n", $job); + + $lines[0] = sprintf(' %s:', $name); + + // The source condition reads workflow dispatch inputs, which this workflow + // does not define. + $lines[find_line($lines, '/^ if: /', 'job condition')] = ' if: ' . VARIANT_JOB_CONDITION; + + $job = implode("\n", set_container_env($lines, $env)); + + foreach ($replacements as $search => $replace) { + if (!str_contains($job, $search)) { + fwrite(STDERR, sprintf("Error: Could not find '%s' in job %s.\n", $search, $name)); + exit(1); + } + + $job = str_replace($search, $replace, $job); + } + + return $job; +} + +/** + * Build the replacements for a build variant job. + * + * Both build variants run in the same workflow run, where an artifact name can + * be uploaded once, so artifact and check run names carry the job name. + * + * @param string $name + * Variant job name. + * @param string $database_job + * Name of the database variant job the build job needs. + * + * @return array + * Replacement strings keyed by the string they replace. + */ +function build_job_replacements(string $name, string $database_job): array { + return [ + 'needs: database' => 'needs: ' . $database_job, + 'name: test-artifacts-' => sprintf('name: test-artifacts-%s-', $name), + 'name: code-artifact' => sprintf('name: code-artifact-%s', $name), + 'check_name: Test results (' => sprintf('check_name: Test results %s (', $name), + ]; +} + +/** + * Set variables in the container 'env' block of job block lines. + * + * Replaces the value of a variable already in the block and appends any other + * variable to the end of the block. + * + * @param array $lines + * Job block lines. + * @param array $env + * Environment variables to set. + * + * @return array + * Job block lines with the variables set. + */ +function set_container_env(array $lines, array $env): array { + $start = find_line($lines, '/^ env:$/', 'container environment', find_line($lines, '/^ container:$/', 'container')); + + // Block entries are indented by 8 spaces. + $end = $start; + for ($i = $start + 1, $count = count($lines); $i < $count && ($lines[$i] === '' || str_starts_with($lines[$i], ' ')); $i++) { + if ($lines[$i] !== '') { + $end = $i; + } + } + + $block = array_slice($lines, $start + 1, $end - $start, TRUE); + + $appended = []; + foreach ($env as $key => $value) { + $line = sprintf(' %s: %s', $key, $value); + $existing = preg_grep('/^ ' . preg_quote($key, '/') . ':/', $block); + + if (empty($existing)) { + $appended[] = $line; + continue; + } + + $lines[array_key_first($existing)] = $line; + } + + array_splice($lines, $end + 1, 0, $appended); + + return $lines; +} + +/** + * Find the index of the first line matching a pattern. + * + * @param array $lines + * Lines to search. + * @param string $pattern + * Regular expression to match. + * @param string $label + * Name of the searched item for the error message. + * @param int $offset + * Index to start the search from. + */ +function find_line(array $lines, string $pattern, string $label, int $offset = 0): int { + for ($i = $offset, $count = count($lines); $i < $count; $i++) { + if (preg_match($pattern, $lines[$i])) { + return $i; + } + } + + fwrite(STDERR, sprintf("Error: Could not find %s matching %s.\n", $label, $pattern)); + exit(1); +} diff --git a/.vortex/tests/lint.ci.sh b/.vortex/tests/lint.ci.sh index 1bfb430f17..efe0ec7495 100755 --- a/.vortex/tests/lint.ci.sh +++ b/.vortex/tests/lint.ci.sh @@ -19,9 +19,21 @@ echo "==> Linting CI configurations in ${ROOT_DIR}." if [ "${FIX}" = "1" ]; then echo "Generating .circleci/vortex-test-common.yml." php "${ROOT_DIR}/.vortex/tests/generate-vortex-dev-circleci" + echo "Generating .github/workflows/vortex-test-didi.yml." + php "${ROOT_DIR}/.vortex/tests/generate-vortex-dev-gha" else echo "Checking that .circleci/vortex-test-common.yml is up to date." php "${ROOT_DIR}/.vortex/tests/generate-vortex-dev-circleci" --check + echo "Checking that .github/workflows/vortex-test-didi.yml is up to date." + php "${ROOT_DIR}/.vortex/tests/generate-vortex-dev-gha" --check +fi + +echo "Checking that both CI providers use the same database base image." +circleci_db_image_base="$(sed -n 's/^ *VORTEX_DB_IMAGE_BASE: *\([^ ]*\) *$/\1/p' "${ROOT_DIR}/.circleci/config.yml")" +gha_db_image_base="$(sed -n 's/.*VORTEX_DB_IMAGE_BASE=\([^" ]*\)".*/\1/p' "${ROOT_DIR}/.github/workflows/build-test-deploy.yml")" +if [ -z "${circleci_db_image_base}" ] || [ "${circleci_db_image_base}" != "${gha_db_image_base}" ]; then + echo "VORTEX_DB_IMAGE_BASE differs between .circleci/config.yml (${circleci_db_image_base:-not set}) and .github/workflows/build-test-deploy.yml (${gha_db_image_base:-not set})." + exit 1 fi # LCOV_EXCL_STOP diff --git a/.vortex/tests/phpcs.xml b/.vortex/tests/phpcs.xml index 05ec37262b..a86126bf5a 100644 --- a/.vortex/tests/phpcs.xml +++ b/.vortex/tests/phpcs.xml @@ -20,6 +20,7 @@ phpunit generate-vortex-dev-circleci + generate-vortex-dev-gha @@ -31,6 +32,7 @@ generate-vortex-dev-circleci + generate-vortex-dev-gha diff --git a/.vortex/tests/phpstan.neon b/.vortex/tests/phpstan.neon index 1624cc22db..24d81e4140 100644 --- a/.vortex/tests/phpstan.neon +++ b/.vortex/tests/phpstan.neon @@ -9,6 +9,7 @@ parameters: paths: - phpunit - generate-vortex-dev-circleci + - generate-vortex-dev-gha excludePaths: - vendor/* diff --git a/.vortex/tests/phpunit/Traits/SutTrait.php b/.vortex/tests/phpunit/Traits/SutTrait.php index ef8c1e1b54..7b587dfa6d 100644 --- a/.vortex/tests/phpunit/Traits/SutTrait.php +++ b/.vortex/tests/phpunit/Traits/SutTrait.php @@ -527,6 +527,7 @@ protected function assertVortexFilesPresent(string $webroot = 'web'): void { $this->assertFileDoesNotExist('.github/workflows/vortex-release.yml'); $this->assertFileDoesNotExist('.github/workflows/vortex-test-docs.yml'); $this->assertFileDoesNotExist('.github/workflows/vortex-test-common.yml'); + $this->assertFileDoesNotExist('.github/workflows/vortex-test-didi.yml'); $this->assertFileDoesNotExist('.github/workflows/vortex-test-installer.yml'); if (file_exists('.circleci/config.yml')) {