From ef7cf5e685da3c8efbcfadd4bc2f9cae1c05c30d Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:01:47 -0700 Subject: [PATCH 01/33] Update GitHub Actions for Node 24 --- .github/actions/docker-compose-pull/action.yml | 4 ++-- .github/workflows/run-single-test.yml | 3 ++- .github/workflows/run-tests.yml | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/actions/docker-compose-pull/action.yml b/.github/actions/docker-compose-pull/action.yml index 4d29cf4696..8615262756 100644 --- a/.github/actions/docker-compose-pull/action.yml +++ b/.github/actions/docker-compose-pull/action.yml @@ -25,7 +25,7 @@ runs: using: composite steps: - name: Pull services - uses: nick-fields/retry@v3 + uses: nick-fields/retry@v4 env: COMPOSE_FILE: ${{ inputs['compose-file'] }} SERVICES: ${{ inputs.services }} @@ -42,7 +42,7 @@ runs: docker compose -f "$COMPOSE_FILE" pull $SERVICES - name: Start services - uses: hoverkraft-tech/compose-action@v2.0.1 + uses: hoverkraft-tech/compose-action@v2.6.0 with: compose-file: ${{ inputs['compose-file'] }} services: ${{ inputs.services }} diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index b033f8a994..092a589fbd 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -46,6 +46,7 @@ env: COMMIT: ${{ inputs.commit }} DOCKER_COMPOSE_FILE: ./develop/github/docker-compose.yml TEMPORAL_VERSION_CHECK_DISABLED: 1 + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true jobs: unit-test: @@ -133,7 +134,7 @@ jobs: - name: Start containerized dependencies if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) && toJson(matrix.containers) != '[]' }} - uses: hoverkraft-tech/compose-action@v2.0.1 + uses: hoverkraft-tech/compose-action@v2.6.0 with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 307e7dd4b5..f799be1a26 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -23,6 +23,7 @@ env: PR_BASE_COMMIT: ${{ github.event.pull_request.base.sha }} DOCKER_COMPOSE_FILE: ./develop/github/docker-compose.yml TEMPORAL_VERSION_CHECK_DISABLED: 1 + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true MAX_TEST_ATTEMPTS: 3 SHARD_COUNT: 3 # NOTE: must match shard count in optimize-test-sharding.yml @@ -404,7 +405,7 @@ jobs: PERSISTENCE_DRIVER: ${{ matrix.persistence_driver }} TEST_TIMEOUT: ${{ matrix.test_timeout }} steps: - - uses: ScribeMD/docker-cache@0.3.7 + - uses: ScribeMD/docker-cache@0.5.0 with: key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(env.DOCKER_COMPOSE_FILE) }} From 473e2092a625b3af39543acafb24e034739a4794 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:07:47 -0700 Subject: [PATCH 02/33] Replace Node 20 workflow actions --- .../actions/docker-compose-pull/action.yml | 19 +++-- .github/actions/docker-image-cache/action.yml | 85 +++++++++++++++++++ .github/workflows/run-single-test.yml | 9 +- .github/workflows/run-tests.yml | 37 ++++++-- 4 files changed, 130 insertions(+), 20 deletions(-) create mode 100644 .github/actions/docker-image-cache/action.yml diff --git a/.github/actions/docker-compose-pull/action.yml b/.github/actions/docker-compose-pull/action.yml index 8615262756..685759e77e 100644 --- a/.github/actions/docker-compose-pull/action.yml +++ b/.github/actions/docker-compose-pull/action.yml @@ -17,10 +17,6 @@ inputs: timeout-minutes: description: Timeout for each pull attempt. default: "1" - down-flags: - description: Additional options to pass to docker compose down. - default: "" - runs: using: composite steps: @@ -42,8 +38,13 @@ runs: docker compose -f "$COMPOSE_FILE" pull $SERVICES - name: Start services - uses: hoverkraft-tech/compose-action@v2.6.0 - with: - compose-file: ${{ inputs['compose-file'] }} - services: ${{ inputs.services }} - down-flags: ${{ inputs['down-flags'] }} + shell: bash + env: + COMPOSE_FILE: ${{ inputs['compose-file'] }} + SERVICES: ${{ inputs.services }} + run: | + if [[ -z "${SERVICES//[[:space:]]/}" ]]; then + echo "No services configured for docker compose up." + exit 0 + fi + docker compose -f "$COMPOSE_FILE" up -d $SERVICES diff --git a/.github/actions/docker-image-cache/action.yml b/.github/actions/docker-image-cache/action.yml new file mode 100644 index 0000000000..54ada8f299 --- /dev/null +++ b/.github/actions/docker-image-cache/action.yml @@ -0,0 +1,85 @@ +name: Docker Image Cache +description: Restore or save Docker images using actions/cache. + +inputs: + mode: + description: Use "restore" or "save". + required: true + key: + description: Cache key. + required: true + path: + description: Directory used to store the Docker image archive. + required: true + compose-file: + description: Docker Compose file whose images should be saved. + required: false + +outputs: + cache-hit: + description: Whether the restore found an exact cache hit. + value: ${{ steps.restore.outputs.cache-hit }} + +runs: + using: composite + steps: + - name: Restore cache + id: restore + if: ${{ inputs.mode == 'restore' }} + uses: actions/cache/restore@v5 + with: + path: ${{ inputs.path }} + key: ${{ inputs.key }} + + - name: Load Docker images + if: ${{ inputs.mode == 'restore' && steps.restore.outputs.cache-hit == 'true' }} + shell: bash + env: + CACHE_PATH: ${{ inputs.path }} + run: | + if [[ -f "$CACHE_PATH/images.tar" ]]; then + docker load --input "$CACHE_PATH/images.tar" + else + echo "Docker image cache hit did not include images.tar." + fi + + - name: Save Docker images to archive + id: archive + if: ${{ inputs.mode == 'save' }} + shell: bash + env: + CACHE_PATH: ${{ inputs.path }} + COMPOSE_FILE: ${{ inputs['compose-file'] }} + run: | + if [[ -z "$COMPOSE_FILE" ]]; then + echo "compose-file is required when mode is save." + exit 1 + fi + + mkdir -p "$CACHE_PATH" + images_file="$CACHE_PATH/images.txt" + : > "$images_file" + + while IFS= read -r image; do + if docker image inspect "$image" >/dev/null 2>&1; then + printf '%s\n' "$image" >> "$images_file" + fi + done < <(docker compose -f "$COMPOSE_FILE" config --images | sort -u) + + if [[ ! -s "$images_file" ]]; then + echo "No Docker images are available to cache." + echo "cacheable=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + # Word splitting is intentional: Docker image references cannot contain whitespace. + # shellcheck disable=SC2046 + docker save --output "$CACHE_PATH/images.tar" $(cat "$images_file") + echo "cacheable=true" >> "$GITHUB_OUTPUT" + + - name: Save cache + if: ${{ inputs.mode == 'save' && steps.archive.outputs.cacheable == 'true' }} + uses: actions/cache/save@v5 + with: + path: ${{ inputs.path }} + key: ${{ inputs.key }} diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index 092a589fbd..6f38d348af 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -46,7 +46,6 @@ env: COMMIT: ${{ inputs.commit }} DOCKER_COMPOSE_FILE: ./develop/github/docker-compose.yml TEMPORAL_VERSION_CHECK_DISABLED: 1 - FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true jobs: unit-test: @@ -134,11 +133,10 @@ jobs: - name: Start containerized dependencies if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) && toJson(matrix.containers) != '[]' }} - uses: hoverkraft-tech/compose-action@v2.6.0 + uses: ./.github/actions/docker-compose-pull with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" - down-flags: -v - uses: actions/setup-go@v6 if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) }} @@ -152,3 +150,8 @@ jobs: env: TEST_ARGS: "-run ${{ inputs.test_name }} -count ${{ inputs.n_runs }}" TEST_TIMEOUT: "${{ inputs.timeout_minutes }}m" + + - name: Tear down docker compose + if: ${{ always() && contains(fromJSON(inputs.test_dbs), matrix.name) && toJson(matrix.containers) != '[]' }} + run: | + docker compose -f ${{ env.DOCKER_COMPOSE_FILE }} down -v diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index f799be1a26..1e3a24cabb 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -23,7 +23,6 @@ env: PR_BASE_COMMIT: ${{ github.event.pull_request.base.sha }} DOCKER_COMPOSE_FILE: ./develop/github/docker-compose.yml TEMPORAL_VERSION_CHECK_DISABLED: 1 - FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true MAX_TEST_ATTEMPTS: 3 SHARD_COUNT: 3 # NOTE: must match shard count in optimize-test-sharding.yml @@ -346,7 +345,6 @@ jobs: cassandra mysql postgresql - down-flags: -v - uses: actions/setup-go@v6 with: @@ -404,23 +402,37 @@ jobs: PERSISTENCE_TYPE: ${{ matrix.persistence_type }} PERSISTENCE_DRIVER: ${{ matrix.persistence_driver }} TEST_TIMEOUT: ${{ matrix.test_timeout }} + DOCKER_IMAGE_CACHE_PATH: ${{ runner.temp }}/docker-image-cache steps: - - uses: ScribeMD/docker-cache@0.5.0 - with: - key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(env.DOCKER_COMPOSE_FILE) }} - - uses: actions/checkout@v6 with: token: ${{ secrets.GITHUB_TOKEN }} ref: ${{ env.COMMIT }} + - name: Restore Docker image cache + id: docker-image-cache + if: ${{ toJson(matrix.containers) != '[]' }} + uses: ./.github/actions/docker-image-cache + with: + mode: restore + key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(env.DOCKER_COMPOSE_FILE) }}-${{ join(matrix.containers, '-') }} + path: ${{ env.DOCKER_IMAGE_CACHE_PATH }} + - name: Start containerized dependencies if: ${{ toJson(matrix.containers) != '[]' }} uses: ./.github/actions/docker-compose-pull with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" - down-flags: -v + + - name: Save Docker image cache + if: ${{ toJson(matrix.containers) != '[]' && steps.docker-image-cache.outputs.cache-hit != 'true' }} + uses: ./.github/actions/docker-image-cache + with: + mode: save + key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(env.DOCKER_COMPOSE_FILE) }}-${{ join(matrix.containers, '-') }} + path: ${{ env.DOCKER_IMAGE_CACHE_PATH }} + compose-file: ${{ env.DOCKER_COMPOSE_FILE }} - uses: actions/setup-go@v6 with: @@ -474,6 +486,11 @@ jobs: codecov-flag: functional-test debug-log-path: ${{ github.workspace }}/.testoutput/debug.log + - name: Tear down docker compose + if: ${{ always() && toJson(matrix.containers) != '[]' }} + run: | + docker compose -f ${{ env.DOCKER_COMPOSE_FILE }} down -v + mixed-brain-test: name: Mixed brain test needs: [pre-build, test-setup] @@ -489,7 +506,6 @@ jobs: with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: postgresql - down-flags: -v - uses: actions/setup-go@v6 with: @@ -535,6 +551,11 @@ jobs: if: always() run: cat .testoutput/mixedbrain_omes.log || true + - name: Tear down docker compose + if: always() + run: | + docker compose -f ${{ env.DOCKER_COMPOSE_FILE }} down -v + test-status: if: always() name: Test Status From 9858d06a19eb8eb1634e637a0020640db1cc3a9b Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:10:06 -0700 Subject: [PATCH 03/33] Integrate Docker cache into compose action --- .../actions/docker-compose-pull/action.yml | 50 -------- .../actions/docker-compose-start/action.yml | 118 ++++++++++++++++++ .github/actions/docker-image-cache/action.yml | 85 ------------- .github/workflows/run-single-test.yml | 2 +- .github/workflows/run-tests.yml | 26 +--- 5 files changed, 123 insertions(+), 158 deletions(-) delete mode 100644 .github/actions/docker-compose-pull/action.yml create mode 100644 .github/actions/docker-compose-start/action.yml delete mode 100644 .github/actions/docker-image-cache/action.yml diff --git a/.github/actions/docker-compose-pull/action.yml b/.github/actions/docker-compose-pull/action.yml deleted file mode 100644 index 685759e77e..0000000000 --- a/.github/actions/docker-compose-pull/action.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Docker Compose Start -description: Pull Docker Compose services with retries, then start them. - -inputs: - compose-file: - description: Docker Compose file to use. - required: true - services: - description: Whitespace-delimited list of services to pull. - required: true - attempts: - description: Number of pull attempts. - default: "5" - delay-seconds: - description: Delay between failed attempts. - default: "5" - timeout-minutes: - description: Timeout for each pull attempt. - default: "1" -runs: - using: composite - steps: - - name: Pull services - uses: nick-fields/retry@v4 - env: - COMPOSE_FILE: ${{ inputs['compose-file'] }} - SERVICES: ${{ inputs.services }} - with: - max_attempts: ${{ inputs.attempts }} - retry_wait_seconds: ${{ inputs['delay-seconds'] }} - timeout_minutes: ${{ inputs['timeout-minutes'] }} - shell: bash - command: | - if [[ -z "${SERVICES//[[:space:]]/}" ]]; then - echo "No services configured for docker compose pull." - exit 0 - fi - docker compose -f "$COMPOSE_FILE" pull $SERVICES - - - name: Start services - shell: bash - env: - COMPOSE_FILE: ${{ inputs['compose-file'] }} - SERVICES: ${{ inputs.services }} - run: | - if [[ -z "${SERVICES//[[:space:]]/}" ]]; then - echo "No services configured for docker compose up." - exit 0 - fi - docker compose -f "$COMPOSE_FILE" up -d $SERVICES diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml new file mode 100644 index 0000000000..542fd8cd13 --- /dev/null +++ b/.github/actions/docker-compose-start/action.yml @@ -0,0 +1,118 @@ +name: Docker Compose Start +description: Restore Docker image cache, pull Docker Compose services with retries, then start them. + +inputs: + compose-file: + description: Docker Compose file to use. + required: true + services: + description: Whitespace-delimited list of services to pull. + required: true + attempts: + description: Number of pull attempts. + default: "5" + delay-seconds: + description: Delay between failed attempts. + default: "5" + timeout-minutes: + description: Timeout for each pull attempt. + default: "1" + cache-key: + description: Cache key for Docker images. Leave empty to disable image caching. + default: "" + cache-path: + description: Directory used to store the Docker image archive. + default: ${{ runner.temp }}/docker-image-cache + +outputs: + cache-hit: + description: Whether the Docker image cache found an exact cache hit. + value: ${{ steps.restore-cache.outputs.cache-hit }} + +runs: + using: composite + steps: + - name: Restore Docker image cache + id: restore-cache + if: ${{ inputs.cache-key != '' }} + uses: actions/cache/restore@v5 + with: + path: ${{ inputs['cache-path'] }} + key: ${{ inputs.cache-key }} + + - name: Load Docker images + if: ${{ inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit == 'true' }} + shell: bash + env: + CACHE_PATH: ${{ inputs['cache-path'] }} + run: | + if [[ -f "$CACHE_PATH/images.tar" ]]; then + docker load --input "$CACHE_PATH/images.tar" + else + echo "Docker image cache hit did not include images.tar." + fi + + - name: Pull services + uses: nick-fields/retry@v4 + env: + COMPOSE_FILE: ${{ inputs['compose-file'] }} + SERVICES: ${{ inputs.services }} + with: + max_attempts: ${{ inputs.attempts }} + retry_wait_seconds: ${{ inputs['delay-seconds'] }} + timeout_minutes: ${{ inputs['timeout-minutes'] }} + shell: bash + command: | + if [[ -z "${SERVICES//[[:space:]]/}" ]]; then + echo "No services configured for docker compose pull." + exit 0 + fi + docker compose -f "$COMPOSE_FILE" pull $SERVICES + + - name: Start services + shell: bash + env: + COMPOSE_FILE: ${{ inputs['compose-file'] }} + SERVICES: ${{ inputs.services }} + run: | + if [[ -z "${SERVICES//[[:space:]]/}" ]]; then + echo "No services configured for docker compose up." + exit 0 + fi + docker compose -f "$COMPOSE_FILE" up -d $SERVICES + + - name: Save Docker images to archive + id: archive + if: ${{ inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit != 'true' }} + shell: bash + env: + CACHE_PATH: ${{ inputs['cache-path'] }} + COMPOSE_FILE: ${{ inputs['compose-file'] }} + run: | + mkdir -p "$CACHE_PATH" + images_file="$CACHE_PATH/images.txt" + : > "$images_file" + + while IFS= read -r image; do + if docker image inspect "$image" >/dev/null 2>&1; then + printf '%s\n' "$image" >> "$images_file" + fi + done < <(docker compose -f "$COMPOSE_FILE" config --images | sort -u) + + if [[ ! -s "$images_file" ]]; then + echo "No Docker images are available to cache." + echo "cacheable=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + # Word splitting is intentional: Docker image references cannot contain whitespace. + # shellcheck disable=SC2046 + docker save --output "$CACHE_PATH/images.tar" $(cat "$images_file") + echo "cacheable=true" >> "$GITHUB_OUTPUT" + + - name: Save Docker image cache + if: ${{ inputs.cache-key != '' && steps.archive.outputs.cacheable == 'true' }} + uses: actions/cache/save@v5 + with: + path: ${{ inputs['cache-path'] }} + key: ${{ inputs.cache-key }} diff --git a/.github/actions/docker-image-cache/action.yml b/.github/actions/docker-image-cache/action.yml deleted file mode 100644 index 54ada8f299..0000000000 --- a/.github/actions/docker-image-cache/action.yml +++ /dev/null @@ -1,85 +0,0 @@ -name: Docker Image Cache -description: Restore or save Docker images using actions/cache. - -inputs: - mode: - description: Use "restore" or "save". - required: true - key: - description: Cache key. - required: true - path: - description: Directory used to store the Docker image archive. - required: true - compose-file: - description: Docker Compose file whose images should be saved. - required: false - -outputs: - cache-hit: - description: Whether the restore found an exact cache hit. - value: ${{ steps.restore.outputs.cache-hit }} - -runs: - using: composite - steps: - - name: Restore cache - id: restore - if: ${{ inputs.mode == 'restore' }} - uses: actions/cache/restore@v5 - with: - path: ${{ inputs.path }} - key: ${{ inputs.key }} - - - name: Load Docker images - if: ${{ inputs.mode == 'restore' && steps.restore.outputs.cache-hit == 'true' }} - shell: bash - env: - CACHE_PATH: ${{ inputs.path }} - run: | - if [[ -f "$CACHE_PATH/images.tar" ]]; then - docker load --input "$CACHE_PATH/images.tar" - else - echo "Docker image cache hit did not include images.tar." - fi - - - name: Save Docker images to archive - id: archive - if: ${{ inputs.mode == 'save' }} - shell: bash - env: - CACHE_PATH: ${{ inputs.path }} - COMPOSE_FILE: ${{ inputs['compose-file'] }} - run: | - if [[ -z "$COMPOSE_FILE" ]]; then - echo "compose-file is required when mode is save." - exit 1 - fi - - mkdir -p "$CACHE_PATH" - images_file="$CACHE_PATH/images.txt" - : > "$images_file" - - while IFS= read -r image; do - if docker image inspect "$image" >/dev/null 2>&1; then - printf '%s\n' "$image" >> "$images_file" - fi - done < <(docker compose -f "$COMPOSE_FILE" config --images | sort -u) - - if [[ ! -s "$images_file" ]]; then - echo "No Docker images are available to cache." - echo "cacheable=false" >> "$GITHUB_OUTPUT" - exit 0 - fi - - # Word splitting is intentional: Docker image references cannot contain whitespace. - # shellcheck disable=SC2046 - docker save --output "$CACHE_PATH/images.tar" $(cat "$images_file") - echo "cacheable=true" >> "$GITHUB_OUTPUT" - - - name: Save cache - if: ${{ inputs.mode == 'save' && steps.archive.outputs.cacheable == 'true' }} - uses: actions/cache/save@v5 - with: - path: ${{ inputs.path }} - key: ${{ inputs.key }} diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index 6f38d348af..9f9d06b391 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -133,7 +133,7 @@ jobs: - name: Start containerized dependencies if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) && toJson(matrix.containers) != '[]' }} - uses: ./.github/actions/docker-compose-pull + uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 1e3a24cabb..893a41786e 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -338,7 +338,7 @@ jobs: ref: ${{ env.COMMIT }} - name: Start containerized dependencies - uses: ./.github/actions/docker-compose-pull + uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: | @@ -402,37 +402,19 @@ jobs: PERSISTENCE_TYPE: ${{ matrix.persistence_type }} PERSISTENCE_DRIVER: ${{ matrix.persistence_driver }} TEST_TIMEOUT: ${{ matrix.test_timeout }} - DOCKER_IMAGE_CACHE_PATH: ${{ runner.temp }}/docker-image-cache steps: - uses: actions/checkout@v6 with: token: ${{ secrets.GITHUB_TOKEN }} ref: ${{ env.COMMIT }} - - name: Restore Docker image cache - id: docker-image-cache - if: ${{ toJson(matrix.containers) != '[]' }} - uses: ./.github/actions/docker-image-cache - with: - mode: restore - key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(env.DOCKER_COMPOSE_FILE) }}-${{ join(matrix.containers, '-') }} - path: ${{ env.DOCKER_IMAGE_CACHE_PATH }} - - name: Start containerized dependencies if: ${{ toJson(matrix.containers) != '[]' }} - uses: ./.github/actions/docker-compose-pull + uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" - - - name: Save Docker image cache - if: ${{ toJson(matrix.containers) != '[]' && steps.docker-image-cache.outputs.cache-hit != 'true' }} - uses: ./.github/actions/docker-image-cache - with: - mode: save - key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(env.DOCKER_COMPOSE_FILE) }}-${{ join(matrix.containers, '-') }} - path: ${{ env.DOCKER_IMAGE_CACHE_PATH }} - compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + cache-key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(env.DOCKER_COMPOSE_FILE) }}-${{ join(matrix.containers, '-') }} - uses: actions/setup-go@v6 with: @@ -502,7 +484,7 @@ jobs: ref: ${{ env.COMMIT }} - name: Start PostgreSQL - uses: ./.github/actions/docker-compose-pull + uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: postgresql From edc7e824c1853dc1492a9d0c82605de7a9604673 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:16:29 -0700 Subject: [PATCH 04/33] Generalize docker compose action --- .../action.yml | 42 +++++++++++++++---- .github/workflows/run-single-test.yml | 9 ++-- .github/workflows/run-tests.yml | 27 ++++++++---- 3 files changed, 58 insertions(+), 20 deletions(-) rename .github/actions/{docker-compose-start => docker-compose}/action.yml (70%) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose/action.yml similarity index 70% rename from .github/actions/docker-compose-start/action.yml rename to .github/actions/docker-compose/action.yml index 542fd8cd13..2763d1e00c 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose/action.yml @@ -1,13 +1,19 @@ -name: Docker Compose Start -description: Restore Docker image cache, pull Docker Compose services with retries, then start them. +name: Docker Compose +description: Start or stop Docker Compose services, with optional Docker image caching. inputs: + action: + description: Operation to perform. Use "start" or "stop". + default: start compose-file: description: Docker Compose file to use. required: true services: - description: Whitespace-delimited list of services to pull. - required: true + description: Whitespace-delimited list of services to start. + default: "" + down-flags: + description: Additional options to pass to docker compose down. + default: "" attempts: description: Number of pull attempts. default: "5" @@ -34,14 +40,14 @@ runs: steps: - name: Restore Docker image cache id: restore-cache - if: ${{ inputs.cache-key != '' }} + if: ${{ inputs.action == 'start' && inputs.cache-key != '' }} uses: actions/cache/restore@v5 with: path: ${{ inputs['cache-path'] }} key: ${{ inputs.cache-key }} - name: Load Docker images - if: ${{ inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit == 'true' }} + if: ${{ inputs.action == 'start' && inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit == 'true' }} shell: bash env: CACHE_PATH: ${{ inputs['cache-path'] }} @@ -53,6 +59,7 @@ runs: fi - name: Pull services + if: ${{ inputs.action == 'start' }} uses: nick-fields/retry@v4 env: COMPOSE_FILE: ${{ inputs['compose-file'] }} @@ -70,6 +77,7 @@ runs: docker compose -f "$COMPOSE_FILE" pull $SERVICES - name: Start services + if: ${{ inputs.action == 'start' }} shell: bash env: COMPOSE_FILE: ${{ inputs['compose-file'] }} @@ -83,7 +91,7 @@ runs: - name: Save Docker images to archive id: archive - if: ${{ inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit != 'true' }} + if: ${{ inputs.action == 'start' && inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit != 'true' }} shell: bash env: CACHE_PATH: ${{ inputs['cache-path'] }} @@ -111,8 +119,26 @@ runs: echo "cacheable=true" >> "$GITHUB_OUTPUT" - name: Save Docker image cache - if: ${{ inputs.cache-key != '' && steps.archive.outputs.cacheable == 'true' }} + if: ${{ inputs.action == 'start' && inputs.cache-key != '' && steps.archive.outputs.cacheable == 'true' }} uses: actions/cache/save@v5 with: path: ${{ inputs['cache-path'] }} key: ${{ inputs.cache-key }} + + - name: Stop services + if: ${{ inputs.action == 'stop' }} + shell: bash + env: + COMPOSE_FILE: ${{ inputs['compose-file'] }} + DOWN_FLAGS: ${{ inputs['down-flags'] }} + run: | + docker compose -f "$COMPOSE_FILE" down $DOWN_FLAGS + + - name: Validate action + if: ${{ inputs.action != 'start' && inputs.action != 'stop' }} + shell: bash + env: + ACTION: ${{ inputs.action }} + run: | + echo "Unsupported docker-compose action: $ACTION" + exit 1 diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index 9f9d06b391..6feae95563 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -133,7 +133,7 @@ jobs: - name: Start containerized dependencies if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) && toJson(matrix.containers) != '[]' }} - uses: ./.github/actions/docker-compose-start + uses: ./.github/actions/docker-compose with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" @@ -153,5 +153,8 @@ jobs: - name: Tear down docker compose if: ${{ always() && contains(fromJSON(inputs.test_dbs), matrix.name) && toJson(matrix.containers) != '[]' }} - run: | - docker compose -f ${{ env.DOCKER_COMPOSE_FILE }} down -v + uses: ./.github/actions/docker-compose + with: + action: stop + compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + down-flags: -v diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 893a41786e..a3b644318c 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -338,7 +338,7 @@ jobs: ref: ${{ env.COMMIT }} - name: Start containerized dependencies - uses: ./.github/actions/docker-compose-start + uses: ./.github/actions/docker-compose with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: | @@ -384,8 +384,11 @@ jobs: - name: Tear down docker compose if: ${{ always() }} - run: | - docker compose -f ${{ env.DOCKER_COMPOSE_FILE }} down -v + uses: ./.github/actions/docker-compose + with: + action: stop + compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + down-flags: -v # Root job name includes matrix details so it is unique per job variant. # This MUST stay in sync with the `job_name` passed to the job-id action below. @@ -410,7 +413,7 @@ jobs: - name: Start containerized dependencies if: ${{ toJson(matrix.containers) != '[]' }} - uses: ./.github/actions/docker-compose-start + uses: ./.github/actions/docker-compose with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" @@ -470,8 +473,11 @@ jobs: - name: Tear down docker compose if: ${{ always() && toJson(matrix.containers) != '[]' }} - run: | - docker compose -f ${{ env.DOCKER_COMPOSE_FILE }} down -v + uses: ./.github/actions/docker-compose + with: + action: stop + compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + down-flags: -v mixed-brain-test: name: Mixed brain test @@ -484,7 +490,7 @@ jobs: ref: ${{ env.COMMIT }} - name: Start PostgreSQL - uses: ./.github/actions/docker-compose-start + uses: ./.github/actions/docker-compose with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: postgresql @@ -535,8 +541,11 @@ jobs: - name: Tear down docker compose if: always() - run: | - docker compose -f ${{ env.DOCKER_COMPOSE_FILE }} down -v + uses: ./.github/actions/docker-compose + with: + action: stop + compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + down-flags: -v test-status: if: always() From 50f06fef08439b4dabeace62b9dd140afe07c6c8 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:19:37 -0700 Subject: [PATCH 05/33] Rename docker compose teardown steps --- .github/workflows/run-single-test.yml | 2 +- .github/workflows/run-tests.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index 6feae95563..61b23fe810 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -151,7 +151,7 @@ jobs: TEST_ARGS: "-run ${{ inputs.test_name }} -count ${{ inputs.n_runs }}" TEST_TIMEOUT: "${{ inputs.timeout_minutes }}m" - - name: Tear down docker compose + - name: Stop containerized dependencies if: ${{ always() && contains(fromJSON(inputs.test_dbs), matrix.name) && toJson(matrix.containers) != '[]' }} uses: ./.github/actions/docker-compose with: diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index a3b644318c..2d70b6c31e 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -382,7 +382,7 @@ jobs: job-name: Integration test artifact-name-suffix: integration-test - - name: Tear down docker compose + - name: Stop containerized dependencies if: ${{ always() }} uses: ./.github/actions/docker-compose with: @@ -471,7 +471,7 @@ jobs: codecov-flag: functional-test debug-log-path: ${{ github.workspace }}/.testoutput/debug.log - - name: Tear down docker compose + - name: Stop containerized dependencies if: ${{ always() && toJson(matrix.containers) != '[]' }} uses: ./.github/actions/docker-compose with: @@ -539,7 +539,7 @@ jobs: if: always() run: cat .testoutput/mixedbrain_omes.log || true - - name: Tear down docker compose + - name: Stop containerized dependencies if: always() uses: ./.github/actions/docker-compose with: From 10a636896008b73331cfaf5bb5476e071b01cb1c Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:21:07 -0700 Subject: [PATCH 06/33] Clean up docker compose action branching --- .github/actions/docker-compose/action.yml | 55 +++++++++++++---------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/.github/actions/docker-compose/action.yml b/.github/actions/docker-compose/action.yml index 2763d1e00c..443c60275f 100644 --- a/.github/actions/docker-compose/action.yml +++ b/.github/actions/docker-compose/action.yml @@ -38,16 +38,41 @@ outputs: runs: using: composite steps: + - name: Resolve action + id: mode + shell: bash + env: + ACTION: ${{ inputs.action }} + run: | + case "$ACTION" in + start|stop) + echo "name=$ACTION" >> "$GITHUB_OUTPUT" + ;; + *) + echo "Unsupported docker-compose action: $ACTION" + exit 1 + ;; + esac + + - name: Stop services + if: ${{ steps.mode.outputs.name == 'stop' }} + shell: bash + env: + COMPOSE_FILE: ${{ inputs['compose-file'] }} + DOWN_FLAGS: ${{ inputs['down-flags'] }} + run: | + docker compose -f "$COMPOSE_FILE" down $DOWN_FLAGS + - name: Restore Docker image cache id: restore-cache - if: ${{ inputs.action == 'start' && inputs.cache-key != '' }} + if: ${{ steps.mode.outputs.name == 'start' && inputs.cache-key != '' }} uses: actions/cache/restore@v5 with: path: ${{ inputs['cache-path'] }} key: ${{ inputs.cache-key }} - name: Load Docker images - if: ${{ inputs.action == 'start' && inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit == 'true' }} + if: ${{ steps.mode.outputs.name == 'start' && inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit == 'true' }} shell: bash env: CACHE_PATH: ${{ inputs['cache-path'] }} @@ -59,7 +84,7 @@ runs: fi - name: Pull services - if: ${{ inputs.action == 'start' }} + if: ${{ steps.mode.outputs.name == 'start' }} uses: nick-fields/retry@v4 env: COMPOSE_FILE: ${{ inputs['compose-file'] }} @@ -77,7 +102,7 @@ runs: docker compose -f "$COMPOSE_FILE" pull $SERVICES - name: Start services - if: ${{ inputs.action == 'start' }} + if: ${{ steps.mode.outputs.name == 'start' }} shell: bash env: COMPOSE_FILE: ${{ inputs['compose-file'] }} @@ -91,7 +116,7 @@ runs: - name: Save Docker images to archive id: archive - if: ${{ inputs.action == 'start' && inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit != 'true' }} + if: ${{ steps.mode.outputs.name == 'start' && inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit != 'true' }} shell: bash env: CACHE_PATH: ${{ inputs['cache-path'] }} @@ -119,26 +144,8 @@ runs: echo "cacheable=true" >> "$GITHUB_OUTPUT" - name: Save Docker image cache - if: ${{ inputs.action == 'start' && inputs.cache-key != '' && steps.archive.outputs.cacheable == 'true' }} + if: ${{ steps.mode.outputs.name == 'start' && inputs.cache-key != '' && steps.archive.outputs.cacheable == 'true' }} uses: actions/cache/save@v5 with: path: ${{ inputs['cache-path'] }} key: ${{ inputs.cache-key }} - - - name: Stop services - if: ${{ inputs.action == 'stop' }} - shell: bash - env: - COMPOSE_FILE: ${{ inputs['compose-file'] }} - DOWN_FLAGS: ${{ inputs['down-flags'] }} - run: | - docker compose -f "$COMPOSE_FILE" down $DOWN_FLAGS - - - name: Validate action - if: ${{ inputs.action != 'start' && inputs.action != 'stop' }} - shell: bash - env: - ACTION: ${{ inputs.action }} - run: | - echo "Unsupported docker-compose action: $ACTION" - exit 1 From 1dad9193da1edab60c56219166f179aea5927bab Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:23:38 -0700 Subject: [PATCH 07/33] Split docker compose start and stop actions --- .../action.yml | 45 +++---------------- .../actions/docker-compose-stop/action.yml | 21 +++++++++ .github/workflows/run-single-test.yml | 7 ++- .github/workflows/run-tests.yml | 21 ++++----- 4 files changed, 39 insertions(+), 55 deletions(-) rename .github/actions/{docker-compose => docker-compose-start}/action.yml (69%) create mode 100644 .github/actions/docker-compose-stop/action.yml diff --git a/.github/actions/docker-compose/action.yml b/.github/actions/docker-compose-start/action.yml similarity index 69% rename from .github/actions/docker-compose/action.yml rename to .github/actions/docker-compose-start/action.yml index 443c60275f..30673b8352 100644 --- a/.github/actions/docker-compose/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -1,19 +1,13 @@ -name: Docker Compose -description: Start or stop Docker Compose services, with optional Docker image caching. +name: Docker Compose Start +description: Restore Docker image cache, pull Docker Compose services with retries, then start them. inputs: - action: - description: Operation to perform. Use "start" or "stop". - default: start compose-file: description: Docker Compose file to use. required: true services: description: Whitespace-delimited list of services to start. default: "" - down-flags: - description: Additional options to pass to docker compose down. - default: "" attempts: description: Number of pull attempts. default: "5" @@ -38,41 +32,16 @@ outputs: runs: using: composite steps: - - name: Resolve action - id: mode - shell: bash - env: - ACTION: ${{ inputs.action }} - run: | - case "$ACTION" in - start|stop) - echo "name=$ACTION" >> "$GITHUB_OUTPUT" - ;; - *) - echo "Unsupported docker-compose action: $ACTION" - exit 1 - ;; - esac - - - name: Stop services - if: ${{ steps.mode.outputs.name == 'stop' }} - shell: bash - env: - COMPOSE_FILE: ${{ inputs['compose-file'] }} - DOWN_FLAGS: ${{ inputs['down-flags'] }} - run: | - docker compose -f "$COMPOSE_FILE" down $DOWN_FLAGS - - name: Restore Docker image cache id: restore-cache - if: ${{ steps.mode.outputs.name == 'start' && inputs.cache-key != '' }} + if: ${{ inputs.cache-key != '' }} uses: actions/cache/restore@v5 with: path: ${{ inputs['cache-path'] }} key: ${{ inputs.cache-key }} - name: Load Docker images - if: ${{ steps.mode.outputs.name == 'start' && inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit == 'true' }} + if: ${{ inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit == 'true' }} shell: bash env: CACHE_PATH: ${{ inputs['cache-path'] }} @@ -84,7 +53,6 @@ runs: fi - name: Pull services - if: ${{ steps.mode.outputs.name == 'start' }} uses: nick-fields/retry@v4 env: COMPOSE_FILE: ${{ inputs['compose-file'] }} @@ -102,7 +70,6 @@ runs: docker compose -f "$COMPOSE_FILE" pull $SERVICES - name: Start services - if: ${{ steps.mode.outputs.name == 'start' }} shell: bash env: COMPOSE_FILE: ${{ inputs['compose-file'] }} @@ -116,7 +83,7 @@ runs: - name: Save Docker images to archive id: archive - if: ${{ steps.mode.outputs.name == 'start' && inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit != 'true' }} + if: ${{ inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit != 'true' }} shell: bash env: CACHE_PATH: ${{ inputs['cache-path'] }} @@ -144,7 +111,7 @@ runs: echo "cacheable=true" >> "$GITHUB_OUTPUT" - name: Save Docker image cache - if: ${{ steps.mode.outputs.name == 'start' && inputs.cache-key != '' && steps.archive.outputs.cacheable == 'true' }} + if: ${{ inputs.cache-key != '' && steps.archive.outputs.cacheable == 'true' }} uses: actions/cache/save@v5 with: path: ${{ inputs['cache-path'] }} diff --git a/.github/actions/docker-compose-stop/action.yml b/.github/actions/docker-compose-stop/action.yml new file mode 100644 index 0000000000..5de58f16de --- /dev/null +++ b/.github/actions/docker-compose-stop/action.yml @@ -0,0 +1,21 @@ +name: Docker Compose Stop +description: Stop Docker Compose services. + +inputs: + compose-file: + description: Docker Compose file to use. + required: true + flags: + description: Additional options to pass to docker compose down. + default: "" + +runs: + using: composite + steps: + - name: Stop services + shell: bash + env: + COMPOSE_FILE: ${{ inputs['compose-file'] }} + FLAGS: ${{ inputs.flags }} + run: | + docker compose -f "$COMPOSE_FILE" down $FLAGS diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index 61b23fe810..ef65caea58 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -133,7 +133,7 @@ jobs: - name: Start containerized dependencies if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) && toJson(matrix.containers) != '[]' }} - uses: ./.github/actions/docker-compose + uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" @@ -153,8 +153,7 @@ jobs: - name: Stop containerized dependencies if: ${{ always() && contains(fromJSON(inputs.test_dbs), matrix.name) && toJson(matrix.containers) != '[]' }} - uses: ./.github/actions/docker-compose + uses: ./.github/actions/docker-compose-stop with: - action: stop compose-file: ${{ env.DOCKER_COMPOSE_FILE }} - down-flags: -v + flags: -v diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 2d70b6c31e..56b1ed5cfa 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -338,7 +338,7 @@ jobs: ref: ${{ env.COMMIT }} - name: Start containerized dependencies - uses: ./.github/actions/docker-compose + uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: | @@ -384,11 +384,10 @@ jobs: - name: Stop containerized dependencies if: ${{ always() }} - uses: ./.github/actions/docker-compose + uses: ./.github/actions/docker-compose-stop with: - action: stop compose-file: ${{ env.DOCKER_COMPOSE_FILE }} - down-flags: -v + flags: -v # Root job name includes matrix details so it is unique per job variant. # This MUST stay in sync with the `job_name` passed to the job-id action below. @@ -413,7 +412,7 @@ jobs: - name: Start containerized dependencies if: ${{ toJson(matrix.containers) != '[]' }} - uses: ./.github/actions/docker-compose + uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" @@ -473,11 +472,10 @@ jobs: - name: Stop containerized dependencies if: ${{ always() && toJson(matrix.containers) != '[]' }} - uses: ./.github/actions/docker-compose + uses: ./.github/actions/docker-compose-stop with: - action: stop compose-file: ${{ env.DOCKER_COMPOSE_FILE }} - down-flags: -v + flags: -v mixed-brain-test: name: Mixed brain test @@ -490,7 +488,7 @@ jobs: ref: ${{ env.COMMIT }} - name: Start PostgreSQL - uses: ./.github/actions/docker-compose + uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: postgresql @@ -541,11 +539,10 @@ jobs: - name: Stop containerized dependencies if: always() - uses: ./.github/actions/docker-compose + uses: ./.github/actions/docker-compose-stop with: - action: stop compose-file: ${{ env.DOCKER_COMPOSE_FILE }} - down-flags: -v + flags: -v test-status: if: always() From 8e98afba3035e4f424a50a8c78263837c437f926 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:26:54 -0700 Subject: [PATCH 08/33] Infer docker compose cache key --- .../actions/docker-compose-start/action.yml | 30 +++++++++++++------ .github/workflows/run-tests.yml | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index 30673b8352..ab757dd332 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -17,9 +17,9 @@ inputs: timeout-minutes: description: Timeout for each pull attempt. default: "1" - cache-key: - description: Cache key for Docker images. Leave empty to disable image caching. - default: "" + cache: + description: Set to "true" to cache Docker images. + default: "false" cache-path: description: Directory used to store the Docker image archive. default: ${{ runner.temp }}/docker-image-cache @@ -32,16 +32,28 @@ outputs: runs: using: composite steps: + - name: Prepare Docker image cache + id: cache + if: ${{ inputs.cache == 'true' }} + shell: bash + env: + COMPOSE_FILE: ${{ inputs['compose-file'] }} + SERVICES: ${{ inputs.services }} + run: | + compose_hash="$(shasum -a 256 "$COMPOSE_FILE" | awk '{print $1}')" + services_hash="$(printf '%s' "$SERVICES" | tr '[:space:]' '\n' | sed '/^$/d' | sort | shasum -a 256 | awk '{print $1}')" + echo "key=docker-${RUNNER_OS}${RUNNER_ARCH}-${compose_hash}-${services_hash}" >> "$GITHUB_OUTPUT" + - name: Restore Docker image cache id: restore-cache - if: ${{ inputs.cache-key != '' }} + if: ${{ steps.cache.outputs.key != '' }} uses: actions/cache/restore@v5 with: path: ${{ inputs['cache-path'] }} - key: ${{ inputs.cache-key }} + key: ${{ steps.cache.outputs.key }} - name: Load Docker images - if: ${{ inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit == 'true' }} + if: ${{ steps.cache.outputs.key != '' && steps.restore-cache.outputs.cache-hit == 'true' }} shell: bash env: CACHE_PATH: ${{ inputs['cache-path'] }} @@ -83,7 +95,7 @@ runs: - name: Save Docker images to archive id: archive - if: ${{ inputs.cache-key != '' && steps.restore-cache.outputs.cache-hit != 'true' }} + if: ${{ steps.cache.outputs.key != '' && steps.restore-cache.outputs.cache-hit != 'true' }} shell: bash env: CACHE_PATH: ${{ inputs['cache-path'] }} @@ -111,8 +123,8 @@ runs: echo "cacheable=true" >> "$GITHUB_OUTPUT" - name: Save Docker image cache - if: ${{ inputs.cache-key != '' && steps.archive.outputs.cacheable == 'true' }} + if: ${{ steps.cache.outputs.key != '' && steps.archive.outputs.cacheable == 'true' }} uses: actions/cache/save@v5 with: path: ${{ inputs['cache-path'] }} - key: ${{ inputs.cache-key }} + key: ${{ steps.cache.outputs.key }} diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 56b1ed5cfa..e5113d5c2e 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -416,7 +416,7 @@ jobs: with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" - cache-key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(env.DOCKER_COMPOSE_FILE) }}-${{ join(matrix.containers, '-') }} + cache: true - uses: actions/setup-go@v6 with: From b138aaa6cf2b2baa2d2af1a43f6014cc5e16e801 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:31:14 -0700 Subject: [PATCH 09/33] Simplify docker compose start scripts --- .github/actions/docker-compose-start/action.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index ab757dd332..f9e897e2e2 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -40,9 +40,13 @@ runs: COMPOSE_FILE: ${{ inputs['compose-file'] }} SERVICES: ${{ inputs.services }} run: | - compose_hash="$(shasum -a 256 "$COMPOSE_FILE" | awk '{print $1}')" - services_hash="$(printf '%s' "$SERVICES" | tr '[:space:]' '\n' | sed '/^$/d' | sort | shasum -a 256 | awk '{print $1}')" - echo "key=docker-${RUNNER_OS}${RUNNER_ARCH}-${compose_hash}-${services_hash}" >> "$GITHUB_OUTPUT" + services_file="$RUNNER_TEMP/docker-compose-services.txt" + printf '%s' "$SERVICES" | tr '[:space:]' '\n' | sed '/^$/d' | sort > "$services_file" + + normalized_services="$(paste -sd '-' "$services_file")" + compose_hash="$(shasum -a 256 "$COMPOSE_FILE" | cut -d ' ' -f 1)" + + echo "key=docker-${RUNNER_OS}${RUNNER_ARCH}-${compose_hash}-${normalized_services}" >> "$GITHUB_OUTPUT" - name: Restore Docker image cache id: restore-cache @@ -117,9 +121,8 @@ runs: exit 0 fi - # Word splitting is intentional: Docker image references cannot contain whitespace. - # shellcheck disable=SC2046 - docker save --output "$CACHE_PATH/images.tar" $(cat "$images_file") + mapfile -t images < "$images_file" + docker save --output "$CACHE_PATH/images.tar" "${images[@]}" echo "cacheable=true" >> "$GITHUB_OUTPUT" - name: Save Docker image cache From 2250c6153bbf4e91f128895b9116a4f6ee2139d6 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:31:43 -0700 Subject: [PATCH 10/33] Document docker compose cache scripting --- .github/actions/docker-compose-start/action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index f9e897e2e2..b82079c010 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -40,6 +40,7 @@ runs: COMPOSE_FILE: ${{ inputs['compose-file'] }} SERVICES: ${{ inputs.services }} run: | + # Normalize service order so equivalent service lists share a cache key. services_file="$RUNNER_TEMP/docker-compose-services.txt" printf '%s' "$SERVICES" | tr '[:space:]' '\n' | sed '/^$/d' | sort > "$services_file" @@ -109,6 +110,7 @@ runs: images_file="$CACHE_PATH/images.txt" : > "$images_file" + # Only cache images that were actually pulled for this job's services. while IFS= read -r image; do if docker image inspect "$image" >/dev/null 2>&1; then printf '%s\n' "$image" >> "$images_file" From eff4d7848c01f8e68b149da7778cbab63deb53ef Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:33:22 -0700 Subject: [PATCH 11/33] Simplify docker compose stop condition --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index e5113d5c2e..e5044bc12d 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -471,7 +471,7 @@ jobs: debug-log-path: ${{ github.workspace }}/.testoutput/debug.log - name: Stop containerized dependencies - if: ${{ always() && toJson(matrix.containers) != '[]' }} + if: always() uses: ./.github/actions/docker-compose-stop with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} From fd5b8f732faac99362c4a1c3493610587e62ac7a Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:34:17 -0700 Subject: [PATCH 12/33] Simplify single test compose guards --- .github/workflows/run-single-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index ef65caea58..e62f3c50f4 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -132,7 +132,7 @@ jobs: ref: ${{ env.COMMIT }} - name: Start containerized dependencies - if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) && toJson(matrix.containers) != '[]' }} + if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) }} uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} @@ -152,7 +152,7 @@ jobs: TEST_TIMEOUT: "${{ inputs.timeout_minutes }}m" - name: Stop containerized dependencies - if: ${{ always() && contains(fromJSON(inputs.test_dbs), matrix.name) && toJson(matrix.containers) != '[]' }} + if: ${{ always() && contains(fromJSON(inputs.test_dbs), matrix.name) }} uses: ./.github/actions/docker-compose-stop with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} From 864469dfd7a65252e21e11f84129b3c8325fe757 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:34:59 -0700 Subject: [PATCH 13/33] Remove redundant compose start guard --- .github/workflows/run-tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index e5044bc12d..65631f745b 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -411,7 +411,6 @@ jobs: ref: ${{ env.COMMIT }} - name: Start containerized dependencies - if: ${{ toJson(matrix.containers) != '[]' }} uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} From 68130a73f9a4faef8eb12fa11e471a738fcf44c6 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:37:03 -0700 Subject: [PATCH 14/33] Use raw compose services for cache key --- .github/actions/docker-compose-start/action.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index b82079c010..2fc7f5800f 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -40,14 +40,10 @@ runs: COMPOSE_FILE: ${{ inputs['compose-file'] }} SERVICES: ${{ inputs.services }} run: | - # Normalize service order so equivalent service lists share a cache key. - services_file="$RUNNER_TEMP/docker-compose-services.txt" - printf '%s' "$SERVICES" | tr '[:space:]' '\n' | sed '/^$/d' | sort > "$services_file" - - normalized_services="$(paste -sd '-' "$services_file")" compose_hash="$(shasum -a 256 "$COMPOSE_FILE" | cut -d ' ' -f 1)" + services_hash="$(printf '%s' "$SERVICES" | shasum -a 256 | cut -d ' ' -f 1)" - echo "key=docker-${RUNNER_OS}${RUNNER_ARCH}-${compose_hash}-${normalized_services}" >> "$GITHUB_OUTPUT" + echo "key=docker-${RUNNER_OS}${RUNNER_ARCH}-${compose_hash}-${services_hash}" >> "$GITHUB_OUTPUT" - name: Restore Docker image cache id: restore-cache From b97c900d21fa7128378302c79216049c575f0272 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:42:27 -0700 Subject: [PATCH 15/33] Use hashFiles for compose cache key --- .github/actions/docker-compose-start/action.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index 2fc7f5800f..05ff5b39a9 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -37,24 +37,22 @@ runs: if: ${{ inputs.cache == 'true' }} shell: bash env: - COMPOSE_FILE: ${{ inputs['compose-file'] }} SERVICES: ${{ inputs.services }} run: | - compose_hash="$(shasum -a 256 "$COMPOSE_FILE" | cut -d ' ' -f 1)" services_hash="$(printf '%s' "$SERVICES" | shasum -a 256 | cut -d ' ' -f 1)" - echo "key=docker-${RUNNER_OS}${RUNNER_ARCH}-${compose_hash}-${services_hash}" >> "$GITHUB_OUTPUT" + echo "services-hash=$services_hash" >> "$GITHUB_OUTPUT" - name: Restore Docker image cache id: restore-cache - if: ${{ steps.cache.outputs.key != '' }} + if: ${{ steps.cache.outputs.services-hash != '' }} uses: actions/cache/restore@v5 with: path: ${{ inputs['cache-path'] }} - key: ${{ steps.cache.outputs.key }} + key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(inputs['compose-file']) }}-${{ steps.cache.outputs.services-hash }} - name: Load Docker images - if: ${{ steps.cache.outputs.key != '' && steps.restore-cache.outputs.cache-hit == 'true' }} + if: ${{ steps.cache.outputs.services-hash != '' && steps.restore-cache.outputs.cache-hit == 'true' }} shell: bash env: CACHE_PATH: ${{ inputs['cache-path'] }} @@ -96,7 +94,7 @@ runs: - name: Save Docker images to archive id: archive - if: ${{ steps.cache.outputs.key != '' && steps.restore-cache.outputs.cache-hit != 'true' }} + if: ${{ steps.cache.outputs.services-hash != '' && steps.restore-cache.outputs.cache-hit != 'true' }} shell: bash env: CACHE_PATH: ${{ inputs['cache-path'] }} @@ -124,8 +122,8 @@ runs: echo "cacheable=true" >> "$GITHUB_OUTPUT" - name: Save Docker image cache - if: ${{ steps.cache.outputs.key != '' && steps.archive.outputs.cacheable == 'true' }} + if: ${{ steps.cache.outputs.services-hash != '' && steps.archive.outputs.cacheable == 'true' }} uses: actions/cache/save@v5 with: path: ${{ inputs['cache-path'] }} - key: ${{ steps.cache.outputs.key }} + key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(inputs['compose-file']) }}-${{ steps.cache.outputs.services-hash }} From 6c6ede83ceabd0c9db54fcc5d41004052b7477e4 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:58:04 -0700 Subject: [PATCH 16/33] Simplify compose start cache guards --- .github/actions/docker-compose-start/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index 05ff5b39a9..0ab766e00a 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -45,14 +45,14 @@ runs: - name: Restore Docker image cache id: restore-cache - if: ${{ steps.cache.outputs.services-hash != '' }} + if: ${{ inputs.cache == 'true' }} uses: actions/cache/restore@v5 with: path: ${{ inputs['cache-path'] }} key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(inputs['compose-file']) }}-${{ steps.cache.outputs.services-hash }} - name: Load Docker images - if: ${{ steps.cache.outputs.services-hash != '' && steps.restore-cache.outputs.cache-hit == 'true' }} + if: ${{ inputs.cache == 'true' && steps.restore-cache.outputs.cache-hit == 'true' }} shell: bash env: CACHE_PATH: ${{ inputs['cache-path'] }} @@ -94,7 +94,7 @@ runs: - name: Save Docker images to archive id: archive - if: ${{ steps.cache.outputs.services-hash != '' && steps.restore-cache.outputs.cache-hit != 'true' }} + if: ${{ inputs.cache == 'true' && steps.restore-cache.outputs.cache-hit != 'true' }} shell: bash env: CACHE_PATH: ${{ inputs['cache-path'] }} @@ -122,7 +122,7 @@ runs: echo "cacheable=true" >> "$GITHUB_OUTPUT" - name: Save Docker image cache - if: ${{ steps.cache.outputs.services-hash != '' && steps.archive.outputs.cacheable == 'true' }} + if: ${{ inputs.cache == 'true' && steps.archive.outputs.cacheable == 'true' }} uses: actions/cache/save@v5 with: path: ${{ inputs['cache-path'] }} From b162966d70ab7a45199f6f2127e70263dcedb227 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 09:59:02 -0700 Subject: [PATCH 17/33] Deduplicate compose cache key --- .github/actions/docker-compose-start/action.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index 0ab766e00a..0a324eb527 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -24,11 +24,6 @@ inputs: description: Directory used to store the Docker image archive. default: ${{ runner.temp }}/docker-image-cache -outputs: - cache-hit: - description: Whether the Docker image cache found an exact cache hit. - value: ${{ steps.restore-cache.outputs.cache-hit }} - runs: using: composite steps: @@ -41,7 +36,7 @@ runs: run: | services_hash="$(printf '%s' "$SERVICES" | shasum -a 256 | cut -d ' ' -f 1)" - echo "services-hash=$services_hash" >> "$GITHUB_OUTPUT" + echo "key=docker-${RUNNER_OS}${RUNNER_ARCH}-${{ hashFiles(inputs['compose-file']) }}-${services_hash}" >> "$GITHUB_OUTPUT" - name: Restore Docker image cache id: restore-cache @@ -49,7 +44,7 @@ runs: uses: actions/cache/restore@v5 with: path: ${{ inputs['cache-path'] }} - key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(inputs['compose-file']) }}-${{ steps.cache.outputs.services-hash }} + key: ${{ steps.cache.outputs.key }} - name: Load Docker images if: ${{ inputs.cache == 'true' && steps.restore-cache.outputs.cache-hit == 'true' }} @@ -126,4 +121,4 @@ runs: uses: actions/cache/save@v5 with: path: ${{ inputs['cache-path'] }} - key: docker-${{ runner.os }}${{ runner.arch }}-${{ hashFiles(inputs['compose-file']) }}-${{ steps.cache.outputs.services-hash }} + key: ${{ steps.cache.outputs.key }} From 0f58b87d1b613c8a89c06406ae6cee183859a52e Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 10:06:36 -0700 Subject: [PATCH 18/33] Avoid expression interpolation in compose script --- .github/actions/docker-compose-start/action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index 0a324eb527..63b63065db 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -32,11 +32,12 @@ runs: if: ${{ inputs.cache == 'true' }} shell: bash env: + COMPOSE_HASH: ${{ hashFiles(inputs['compose-file']) }} SERVICES: ${{ inputs.services }} run: | services_hash="$(printf '%s' "$SERVICES" | shasum -a 256 | cut -d ' ' -f 1)" - echo "key=docker-${RUNNER_OS}${RUNNER_ARCH}-${{ hashFiles(inputs['compose-file']) }}-${services_hash}" >> "$GITHUB_OUTPUT" + echo "key=docker-${RUNNER_OS}${RUNNER_ARCH}-${COMPOSE_HASH}-${services_hash}" >> "$GITHUB_OUTPUT" - name: Restore Docker image cache id: restore-cache From 28045ad6c406587f24722b2fe9369eb3f72cec4f Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 10:22:58 -0700 Subject: [PATCH 19/33] Update github-script to v9 --- .github/workflows/check-pr-placeholders.yml | 2 +- .github/workflows/promote-docker-image.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-pr-placeholders.yml b/.github/workflows/check-pr-placeholders.yml index 51ade33a61..807e5f74b2 100644 --- a/.github/workflows/check-pr-placeholders.yml +++ b/.github/workflows/check-pr-placeholders.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Validate PR description for placeholder lines or empty sections - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const pr = await github.rest.pulls.get({ diff --git a/.github/workflows/promote-docker-image.yml b/.github/workflows/promote-docker-image.yml index e545aa7502..446396ff6b 100644 --- a/.github/workflows/promote-docker-image.yml +++ b/.github/workflows/promote-docker-image.yml @@ -30,7 +30,7 @@ jobs: steps: - name: Validate input tags id: validate - uses: actions/github-script@v8 + uses: actions/github-script@v9 env: SOURCE_TAG: ${{ inputs.source-tag }} TARGET_TAGS: ${{ inputs.target-tags }} @@ -94,7 +94,7 @@ jobs: sudo mv crane /usr/local/bin/ - name: Promote image - uses: actions/github-script@v8 + uses: actions/github-script@v9 env: SOURCE_TAG: ${{ needs.validate-inputs.outputs.source-tag-safe }} TARGET_TAGS: ${{ needs.validate-inputs.outputs.target-tags-safe }} From cc7b57a8dfde93b1353ca0f1b2ac681ab71de377 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 10:25:30 -0700 Subject: [PATCH 20/33] Add permissions to promote docker workflow --- .github/workflows/promote-docker-image.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/promote-docker-image.yml b/.github/workflows/promote-docker-image.yml index 446396ff6b..37859b4567 100644 --- a/.github/workflows/promote-docker-image.yml +++ b/.github/workflows/promote-docker-image.yml @@ -21,6 +21,9 @@ on: DOCKERHUB_TOKEN: required: true +permissions: + contents: read + jobs: validate-inputs: runs-on: ubuntu-latest From 5ce7ce799a859ab817d7b50ad436c021245aa35d Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 19:05:07 -0700 Subject: [PATCH 21/33] Wait for compose services on start --- .github/actions/docker-compose-start/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index 63b63065db..a5005785f4 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -86,7 +86,7 @@ runs: echo "No services configured for docker compose up." exit 0 fi - docker compose -f "$COMPOSE_FILE" up -d $SERVICES + docker compose -f "$COMPOSE_FILE" up -d --wait $SERVICES - name: Save Docker images to archive id: archive From 22193373479f6f1417946e6ee0ea38be28003ca6 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 19:05:45 -0700 Subject: [PATCH 22/33] Align compose cache with requested services --- .github/actions/docker-compose-start/action.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index a5005785f4..89c0943086 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -60,6 +60,7 @@ runs: fi - name: Pull services + if: ${{ steps.restore-cache.outputs.cache-hit != 'true' }} uses: nick-fields/retry@v4 env: COMPOSE_FILE: ${{ inputs['compose-file'] }} @@ -95,6 +96,7 @@ runs: env: CACHE_PATH: ${{ inputs['cache-path'] }} COMPOSE_FILE: ${{ inputs['compose-file'] }} + SERVICES: ${{ inputs.services }} run: | mkdir -p "$CACHE_PATH" images_file="$CACHE_PATH/images.txt" @@ -105,7 +107,7 @@ runs: if docker image inspect "$image" >/dev/null 2>&1; then printf '%s\n' "$image" >> "$images_file" fi - done < <(docker compose -f "$COMPOSE_FILE" config --images | sort -u) + done < <(docker compose -f "$COMPOSE_FILE" config --images $SERVICES | sort -u) if [[ ! -s "$images_file" ]]; then echo "No Docker images are available to cache." From acce778eef36b4c49e2e4fb7492e94a9eb2b128d Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 19:45:59 -0700 Subject: [PATCH 23/33] Make compose up flags configurable --- .github/actions/docker-compose-start/action.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index 89c0943086..8ffdd15b13 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -17,6 +17,9 @@ inputs: timeout-minutes: description: Timeout for each pull attempt. default: "1" + up-flags: + description: Additional options to pass to docker compose up. + default: "--wait" cache: description: Set to "true" to cache Docker images. default: "false" @@ -82,12 +85,13 @@ runs: env: COMPOSE_FILE: ${{ inputs['compose-file'] }} SERVICES: ${{ inputs.services }} + UP_FLAGS: ${{ inputs['up-flags'] }} run: | if [[ -z "${SERVICES//[[:space:]]/}" ]]; then echo "No services configured for docker compose up." exit 0 fi - docker compose -f "$COMPOSE_FILE" up -d --wait $SERVICES + docker compose -f "$COMPOSE_FILE" up -d $UP_FLAGS $SERVICES - name: Save Docker images to archive id: archive From 6a56486f9a18d2629b982a47e9f68cd5f558face Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 19:50:08 -0700 Subject: [PATCH 24/33] Pass compose wait flag explicitly --- .github/actions/docker-compose-start/action.yml | 2 +- .github/workflows/run-single-test.yml | 1 + .github/workflows/run-tests.yml | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index 8ffdd15b13..ebf98c1e71 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -19,7 +19,7 @@ inputs: default: "1" up-flags: description: Additional options to pass to docker compose up. - default: "--wait" + default: "" cache: description: Set to "true" to cache Docker images. default: "false" diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index e62f3c50f4..6c752a65bb 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -137,6 +137,7 @@ jobs: with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" + up-flags: --wait - uses: actions/setup-go@v6 if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) }} diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 65631f745b..8d40e9d67d 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -345,6 +345,7 @@ jobs: cassandra mysql postgresql + up-flags: --wait - uses: actions/setup-go@v6 with: @@ -415,6 +416,7 @@ jobs: with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" + up-flags: --wait cache: true - uses: actions/setup-go@v6 @@ -491,6 +493,7 @@ jobs: with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: postgresql + up-flags: --wait - uses: actions/setup-go@v6 with: From 3a632e55878e9a2e012fdbd8b8deb6a7449cbc62 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 19:50:36 -0700 Subject: [PATCH 25/33] Rename compose start flags input --- .github/actions/docker-compose-start/action.yml | 6 +++--- .github/workflows/run-single-test.yml | 2 +- .github/workflows/run-tests.yml | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index ebf98c1e71..cc4f977f19 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -17,7 +17,7 @@ inputs: timeout-minutes: description: Timeout for each pull attempt. default: "1" - up-flags: + flags: description: Additional options to pass to docker compose up. default: "" cache: @@ -85,13 +85,13 @@ runs: env: COMPOSE_FILE: ${{ inputs['compose-file'] }} SERVICES: ${{ inputs.services }} - UP_FLAGS: ${{ inputs['up-flags'] }} + FLAGS: ${{ inputs.flags }} run: | if [[ -z "${SERVICES//[[:space:]]/}" ]]; then echo "No services configured for docker compose up." exit 0 fi - docker compose -f "$COMPOSE_FILE" up -d $UP_FLAGS $SERVICES + docker compose -f "$COMPOSE_FILE" up -d $FLAGS $SERVICES - name: Save Docker images to archive id: archive diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index 6c752a65bb..013f73e56a 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -137,7 +137,7 @@ jobs: with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" - up-flags: --wait + flags: --wait - uses: actions/setup-go@v6 if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) }} diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 8d40e9d67d..a87815e707 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -345,7 +345,7 @@ jobs: cassandra mysql postgresql - up-flags: --wait + flags: --wait - uses: actions/setup-go@v6 with: @@ -416,7 +416,7 @@ jobs: with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" - up-flags: --wait + flags: --wait cache: true - uses: actions/setup-go@v6 @@ -493,7 +493,7 @@ jobs: with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: postgresql - up-flags: --wait + flags: --wait - uses: actions/setup-go@v6 with: From bbca562726ee62cf530d5cabaac3b09c91a538e1 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 20:18:22 -0700 Subject: [PATCH 26/33] Add docker compose healthy action --- .../actions/docker-compose-healthy/action.yml | 31 +++++++++++++++++++ .github/workflows/run-tests.yml | 15 +++++---- 2 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 .github/actions/docker-compose-healthy/action.yml diff --git a/.github/actions/docker-compose-healthy/action.yml b/.github/actions/docker-compose-healthy/action.yml new file mode 100644 index 0000000000..71ec1ce777 --- /dev/null +++ b/.github/actions/docker-compose-healthy/action.yml @@ -0,0 +1,31 @@ +name: Docker Compose Healthy +description: Wait for Docker Compose services to become healthy. + +inputs: + compose-file: + description: Docker Compose file to use. + required: true + services: + description: Whitespace-delimited list of services to wait for. Defaults to running services. + default: "" + +runs: + using: composite + steps: + - name: Wait for services + shell: bash + env: + COMPOSE_FILE: ${{ inputs['compose-file'] }} + SERVICES: ${{ inputs.services }} + run: | + if [[ -z "${SERVICES//[[:space:]]/}" ]]; then + SERVICES="$(docker compose -f "$COMPOSE_FILE" ps --services)" + fi + + if [[ -z "${SERVICES//[[:space:]]/}" ]]; then + echo "No services configured for docker compose healthy." + exit 0 + fi + + read -r -a services <<< "$SERVICES" + docker compose -f "$COMPOSE_FILE" up --wait "${services[@]}" diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index a87815e707..514bc0712d 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -365,10 +365,9 @@ jobs: key: go-${{ runner.os }}${{ runner.arch }}-build-${{ env.COMMIT }} - name: Wait for containerized dependencies to be healthy - run: | - # Word splitting is intentional here. - # shellcheck disable=SC2046 - docker compose -f ${{ env.DOCKER_COMPOSE_FILE }} up --wait $(docker compose -f ${{ env.DOCKER_COMPOSE_FILE }} ps --services) + uses: ./.github/actions/docker-compose-healthy + with: + compose-file: ${{ env.DOCKER_COMPOSE_FILE }} - name: Run integration test timeout-minutes: 15 @@ -441,10 +440,10 @@ jobs: - name: Wait for containerized dependencies to be healthy if: ${{ toJson(matrix.containers) != '[]' }} - run: | - # Word splitting is intentional here. - # shellcheck disable=SC2046 - docker compose -f ${{ env.DOCKER_COMPOSE_FILE }} up --wait $(docker compose -f ${{ env.DOCKER_COMPOSE_FILE }} ps --services) + uses: ./.github/actions/docker-compose-healthy + with: + compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + services: "${{ join(matrix.containers, '\n') }}" - name: Run functional test timeout-minutes: ${{ matrix.github_timeout }} From cd1a623eca17502a5abb2875cd6cdee955616a8c Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 20:21:09 -0700 Subject: [PATCH 27/33] Move compose wait to healthy action --- .github/actions/docker-compose-healthy/action.yml | 6 +----- .github/workflows/run-single-test.yml | 8 +++++++- .github/workflows/run-tests.yml | 7 ++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/actions/docker-compose-healthy/action.yml b/.github/actions/docker-compose-healthy/action.yml index 71ec1ce777..8fec25f7e6 100644 --- a/.github/actions/docker-compose-healthy/action.yml +++ b/.github/actions/docker-compose-healthy/action.yml @@ -6,7 +6,7 @@ inputs: description: Docker Compose file to use. required: true services: - description: Whitespace-delimited list of services to wait for. Defaults to running services. + description: Whitespace-delimited list of services to wait for. default: "" runs: @@ -18,10 +18,6 @@ runs: COMPOSE_FILE: ${{ inputs['compose-file'] }} SERVICES: ${{ inputs.services }} run: | - if [[ -z "${SERVICES//[[:space:]]/}" ]]; then - SERVICES="$(docker compose -f "$COMPOSE_FILE" ps --services)" - fi - if [[ -z "${SERVICES//[[:space:]]/}" ]]; then echo "No services configured for docker compose healthy." exit 0 diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index 013f73e56a..402df3ac77 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -137,7 +137,13 @@ jobs: with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" - flags: --wait + + - name: Wait for containerized dependencies to be healthy + if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) }} + uses: ./.github/actions/docker-compose-healthy + with: + compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + services: "${{ join(matrix.containers, '\n') }}" - uses: actions/setup-go@v6 if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) }} diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 514bc0712d..1bab18b93d 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -345,7 +345,6 @@ jobs: cassandra mysql postgresql - flags: --wait - uses: actions/setup-go@v6 with: @@ -368,6 +367,10 @@ jobs: uses: ./.github/actions/docker-compose-healthy with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + services: | + cassandra + mysql + postgresql - name: Run integration test timeout-minutes: 15 @@ -415,7 +418,6 @@ jobs: with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: "${{ join(matrix.containers, '\n') }}" - flags: --wait cache: true - uses: actions/setup-go@v6 @@ -492,7 +494,6 @@ jobs: with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} services: postgresql - flags: --wait - uses: actions/setup-go@v6 with: From 1289548255f99fd93d881c722a9af0fd2b7c1f9d Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 20:22:39 -0700 Subject: [PATCH 28/33] Reuse integration compose services --- .github/workflows/run-tests.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 1bab18b93d..16111497eb 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -331,6 +331,11 @@ jobs: name: Integration test needs: [pre-build, test-setup] runs-on: ${{ needs.test-setup.outputs.runner_arm }} + env: + CONTAINERS: | + cassandra + mysql + postgresql steps: - uses: actions/checkout@v6 with: @@ -341,10 +346,7 @@ jobs: uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} - services: | - cassandra - mysql - postgresql + services: ${{ env.CONTAINERS }} - uses: actions/setup-go@v6 with: @@ -367,10 +369,7 @@ jobs: uses: ./.github/actions/docker-compose-healthy with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} - services: | - cassandra - mysql - postgresql + services: ${{ env.CONTAINERS }} - name: Run integration test timeout-minutes: 15 From a9f0a5df5a1a3fda0661ef738023e4f9b9b0afad Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 20:23:53 -0700 Subject: [PATCH 29/33] Reuse matrix compose services --- .github/workflows/run-single-test.yml | 5 +++-- .github/workflows/run-tests.yml | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index 402df3ac77..a2bb07ccb7 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -124,6 +124,7 @@ jobs: env: PERSISTENCE_TYPE: ${{ matrix.persistence_type }} PERSISTENCE_DRIVER: ${{ matrix.persistence_driver }} + CONTAINERS: ${{ join(matrix.containers, '\n') }} steps: - uses: actions/checkout@v6 if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) }} @@ -136,14 +137,14 @@ jobs: uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} - services: "${{ join(matrix.containers, '\n') }}" + services: ${{ env.CONTAINERS }} - name: Wait for containerized dependencies to be healthy if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) }} uses: ./.github/actions/docker-compose-healthy with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} - services: "${{ join(matrix.containers, '\n') }}" + services: ${{ env.CONTAINERS }} - uses: actions/setup-go@v6 if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) }} diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 16111497eb..98c2024ce5 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -406,6 +406,7 @@ jobs: PERSISTENCE_TYPE: ${{ matrix.persistence_type }} PERSISTENCE_DRIVER: ${{ matrix.persistence_driver }} TEST_TIMEOUT: ${{ matrix.test_timeout }} + CONTAINERS: ${{ join(matrix.containers, '\n') }} steps: - uses: actions/checkout@v6 with: @@ -416,7 +417,7 @@ jobs: uses: ./.github/actions/docker-compose-start with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} - services: "${{ join(matrix.containers, '\n') }}" + services: ${{ env.CONTAINERS }} cache: true - uses: actions/setup-go@v6 @@ -444,7 +445,7 @@ jobs: uses: ./.github/actions/docker-compose-healthy with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} - services: "${{ join(matrix.containers, '\n') }}" + services: ${{ env.CONTAINERS }} - name: Run functional test timeout-minutes: ${{ matrix.github_timeout }} From dacc2570edb2431e614fbbbe5582857431d56929 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 20:24:21 -0700 Subject: [PATCH 30/33] Always run compose healthy action --- .github/workflows/run-tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 98c2024ce5..61739e34e1 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -441,7 +441,6 @@ jobs: run: echo "::notice::${{ matrix.display_name == 'smoke' && 'This is a smoke test. Add the test-all-dbs label to run all tests on all DBs.' || needs.test-setup.outputs.full_test_reason }}" - name: Wait for containerized dependencies to be healthy - if: ${{ toJson(matrix.containers) != '[]' }} uses: ./.github/actions/docker-compose-healthy with: compose-file: ${{ env.DOCKER_COMPOSE_FILE }} From ebeb79c9ad789f0fa59488ce2630f3b4ff39fa29 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 25 May 2026 20:38:14 -0700 Subject: [PATCH 31/33] Fix docker compose service inputs --- .github/workflows/run-single-test.yml | 2 +- .github/workflows/run-tests.yml | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index a2bb07ccb7..cb1cbd08fc 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -124,7 +124,7 @@ jobs: env: PERSISTENCE_TYPE: ${{ matrix.persistence_type }} PERSISTENCE_DRIVER: ${{ matrix.persistence_driver }} - CONTAINERS: ${{ join(matrix.containers, '\n') }} + CONTAINERS: ${{ join(matrix.containers, ' ') }} steps: - uses: actions/checkout@v6 if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) }} diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 61739e34e1..62583c633e 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -332,10 +332,7 @@ jobs: needs: [pre-build, test-setup] runs-on: ${{ needs.test-setup.outputs.runner_arm }} env: - CONTAINERS: | - cassandra - mysql - postgresql + CONTAINERS: cassandra mysql postgresql steps: - uses: actions/checkout@v6 with: @@ -406,7 +403,7 @@ jobs: PERSISTENCE_TYPE: ${{ matrix.persistence_type }} PERSISTENCE_DRIVER: ${{ matrix.persistence_driver }} TEST_TIMEOUT: ${{ matrix.test_timeout }} - CONTAINERS: ${{ join(matrix.containers, '\n') }} + CONTAINERS: ${{ join(matrix.containers, ' ') }} steps: - uses: actions/checkout@v6 with: From 06f41a295569303d309ec3b9de1c2b39e686d722 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 26 May 2026 20:05:47 -0700 Subject: [PATCH 32/33] =?UTF-8?q?=F0=9F=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actions/docker-compose-healthy/action.yml | 4 +-- .../actions/docker-compose-start/action.yml | 28 +++++++++---------- .../actions/docker-compose-stop/action.yml | 4 +-- .github/workflows/run-single-test.yml | 6 ++-- .github/workflows/run-tests.yml | 16 +++++------ 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/.github/actions/docker-compose-healthy/action.yml b/.github/actions/docker-compose-healthy/action.yml index 8fec25f7e6..3160d7ab10 100644 --- a/.github/actions/docker-compose-healthy/action.yml +++ b/.github/actions/docker-compose-healthy/action.yml @@ -2,7 +2,7 @@ name: Docker Compose Healthy description: Wait for Docker Compose services to become healthy. inputs: - compose-file: + compose_file: description: Docker Compose file to use. required: true services: @@ -15,7 +15,7 @@ runs: - name: Wait for services shell: bash env: - COMPOSE_FILE: ${{ inputs['compose-file'] }} + COMPOSE_FILE: ${{ inputs.compose_file }} SERVICES: ${{ inputs.services }} run: | if [[ -z "${SERVICES//[[:space:]]/}" ]]; then diff --git a/.github/actions/docker-compose-start/action.yml b/.github/actions/docker-compose-start/action.yml index cc4f977f19..e0cc44cc62 100644 --- a/.github/actions/docker-compose-start/action.yml +++ b/.github/actions/docker-compose-start/action.yml @@ -2,7 +2,7 @@ name: Docker Compose Start description: Restore Docker image cache, pull Docker Compose services with retries, then start them. inputs: - compose-file: + compose_file: description: Docker Compose file to use. required: true services: @@ -11,10 +11,10 @@ inputs: attempts: description: Number of pull attempts. default: "5" - delay-seconds: + delay_seconds: description: Delay between failed attempts. default: "5" - timeout-minutes: + timeout_minutes: description: Timeout for each pull attempt. default: "1" flags: @@ -23,7 +23,7 @@ inputs: cache: description: Set to "true" to cache Docker images. default: "false" - cache-path: + cache_path: description: Directory used to store the Docker image archive. default: ${{ runner.temp }}/docker-image-cache @@ -35,7 +35,7 @@ runs: if: ${{ inputs.cache == 'true' }} shell: bash env: - COMPOSE_HASH: ${{ hashFiles(inputs['compose-file']) }} + COMPOSE_HASH: ${{ hashFiles(inputs.compose_file) }} SERVICES: ${{ inputs.services }} run: | services_hash="$(printf '%s' "$SERVICES" | shasum -a 256 | cut -d ' ' -f 1)" @@ -47,14 +47,14 @@ runs: if: ${{ inputs.cache == 'true' }} uses: actions/cache/restore@v5 with: - path: ${{ inputs['cache-path'] }} + path: ${{ inputs.cache_path }} key: ${{ steps.cache.outputs.key }} - name: Load Docker images if: ${{ inputs.cache == 'true' && steps.restore-cache.outputs.cache-hit == 'true' }} shell: bash env: - CACHE_PATH: ${{ inputs['cache-path'] }} + CACHE_PATH: ${{ inputs.cache_path }} run: | if [[ -f "$CACHE_PATH/images.tar" ]]; then docker load --input "$CACHE_PATH/images.tar" @@ -66,12 +66,12 @@ runs: if: ${{ steps.restore-cache.outputs.cache-hit != 'true' }} uses: nick-fields/retry@v4 env: - COMPOSE_FILE: ${{ inputs['compose-file'] }} + COMPOSE_FILE: ${{ inputs.compose_file }} SERVICES: ${{ inputs.services }} with: max_attempts: ${{ inputs.attempts }} - retry_wait_seconds: ${{ inputs['delay-seconds'] }} - timeout_minutes: ${{ inputs['timeout-minutes'] }} + retry_wait_seconds: ${{ inputs.delay_seconds }} + timeout_minutes: ${{ inputs.timeout_minutes }} shell: bash command: | if [[ -z "${SERVICES//[[:space:]]/}" ]]; then @@ -83,7 +83,7 @@ runs: - name: Start services shell: bash env: - COMPOSE_FILE: ${{ inputs['compose-file'] }} + COMPOSE_FILE: ${{ inputs.compose_file }} SERVICES: ${{ inputs.services }} FLAGS: ${{ inputs.flags }} run: | @@ -98,8 +98,8 @@ runs: if: ${{ inputs.cache == 'true' && steps.restore-cache.outputs.cache-hit != 'true' }} shell: bash env: - CACHE_PATH: ${{ inputs['cache-path'] }} - COMPOSE_FILE: ${{ inputs['compose-file'] }} + CACHE_PATH: ${{ inputs.cache_path }} + COMPOSE_FILE: ${{ inputs.compose_file }} SERVICES: ${{ inputs.services }} run: | mkdir -p "$CACHE_PATH" @@ -127,5 +127,5 @@ runs: if: ${{ inputs.cache == 'true' && steps.archive.outputs.cacheable == 'true' }} uses: actions/cache/save@v5 with: - path: ${{ inputs['cache-path'] }} + path: ${{ inputs.cache_path }} key: ${{ steps.cache.outputs.key }} diff --git a/.github/actions/docker-compose-stop/action.yml b/.github/actions/docker-compose-stop/action.yml index 5de58f16de..a5bb7cef78 100644 --- a/.github/actions/docker-compose-stop/action.yml +++ b/.github/actions/docker-compose-stop/action.yml @@ -2,7 +2,7 @@ name: Docker Compose Stop description: Stop Docker Compose services. inputs: - compose-file: + compose_file: description: Docker Compose file to use. required: true flags: @@ -15,7 +15,7 @@ runs: - name: Stop services shell: bash env: - COMPOSE_FILE: ${{ inputs['compose-file'] }} + COMPOSE_FILE: ${{ inputs.compose_file }} FLAGS: ${{ inputs.flags }} run: | docker compose -f "$COMPOSE_FILE" down $FLAGS diff --git a/.github/workflows/run-single-test.yml b/.github/workflows/run-single-test.yml index cb1cbd08fc..a0040bdb41 100644 --- a/.github/workflows/run-single-test.yml +++ b/.github/workflows/run-single-test.yml @@ -136,14 +136,14 @@ jobs: if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) }} uses: ./.github/actions/docker-compose-start with: - compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + compose_file: ${{ env.DOCKER_COMPOSE_FILE }} services: ${{ env.CONTAINERS }} - name: Wait for containerized dependencies to be healthy if: ${{ contains(fromJSON(inputs.test_dbs), matrix.name) }} uses: ./.github/actions/docker-compose-healthy with: - compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + compose_file: ${{ env.DOCKER_COMPOSE_FILE }} services: ${{ env.CONTAINERS }} - uses: actions/setup-go@v6 @@ -163,5 +163,5 @@ jobs: if: ${{ always() && contains(fromJSON(inputs.test_dbs), matrix.name) }} uses: ./.github/actions/docker-compose-stop with: - compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + compose_file: ${{ env.DOCKER_COMPOSE_FILE }} flags: -v diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 62583c633e..c2ca4f5a91 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -342,7 +342,7 @@ jobs: - name: Start containerized dependencies uses: ./.github/actions/docker-compose-start with: - compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + compose_file: ${{ env.DOCKER_COMPOSE_FILE }} services: ${{ env.CONTAINERS }} - uses: actions/setup-go@v6 @@ -365,7 +365,7 @@ jobs: - name: Wait for containerized dependencies to be healthy uses: ./.github/actions/docker-compose-healthy with: - compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + compose_file: ${{ env.DOCKER_COMPOSE_FILE }} services: ${{ env.CONTAINERS }} - name: Run integration test @@ -385,7 +385,7 @@ jobs: if: ${{ always() }} uses: ./.github/actions/docker-compose-stop with: - compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + compose_file: ${{ env.DOCKER_COMPOSE_FILE }} flags: -v # Root job name includes matrix details so it is unique per job variant. @@ -413,7 +413,7 @@ jobs: - name: Start containerized dependencies uses: ./.github/actions/docker-compose-start with: - compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + compose_file: ${{ env.DOCKER_COMPOSE_FILE }} services: ${{ env.CONTAINERS }} cache: true @@ -440,7 +440,7 @@ jobs: - name: Wait for containerized dependencies to be healthy uses: ./.github/actions/docker-compose-healthy with: - compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + compose_file: ${{ env.DOCKER_COMPOSE_FILE }} services: ${{ env.CONTAINERS }} - name: Run functional test @@ -472,7 +472,7 @@ jobs: if: always() uses: ./.github/actions/docker-compose-stop with: - compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + compose_file: ${{ env.DOCKER_COMPOSE_FILE }} flags: -v mixed-brain-test: @@ -488,7 +488,7 @@ jobs: - name: Start PostgreSQL uses: ./.github/actions/docker-compose-start with: - compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + compose_file: ${{ env.DOCKER_COMPOSE_FILE }} services: postgresql - uses: actions/setup-go@v6 @@ -539,7 +539,7 @@ jobs: if: always() uses: ./.github/actions/docker-compose-stop with: - compose-file: ${{ env.DOCKER_COMPOSE_FILE }} + compose_file: ${{ env.DOCKER_COMPOSE_FILE }} flags: -v test-status: From 0fd4c7bc5d0c83d0a7c230e7047331a72c8843c3 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 26 May 2026 20:09:55 -0700 Subject: [PATCH 33/33] this, too --- .../actions/post-test-reporting/action.yml | 24 +++++++++---------- .github/workflows/run-tests.yml | 16 ++++++------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/actions/post-test-reporting/action.yml b/.github/actions/post-test-reporting/action.yml index 08d18faa9c..7b9e02d3e5 100644 --- a/.github/actions/post-test-reporting/action.yml +++ b/.github/actions/post-test-reporting/action.yml @@ -1,18 +1,18 @@ name: Post Test Reporting description: Generate test reports and upload post-test artifacts inputs: - artifact-name-suffix: + artifact_name_suffix: description: Suffix to use for uploaded artifact names required: true - codecov-flag: + codecov_flag: description: Codecov flag for coverage and test result uploads required: false default: "" - debug-log-path: + debug_log_path: description: Optional debug log path to upload required: false default: "" - job-name: + job_name: description: Exact job name to resolve for artifact names required: true runs: @@ -44,8 +44,8 @@ runs: if: ${{ !cancelled() }} shell: bash env: - CODECOV_FLAG: ${{ inputs.codecov-flag }} - ARTIFACT_NAME_SUFFIX: ${{ inputs.artifact-name-suffix }} + CODECOV_FLAG: ${{ inputs.codecov_flag }} + ARTIFACT_NAME_SUFFIX: ${{ inputs.artifact_name_suffix }} run: | flag="$CODECOV_FLAG" if [ -z "$flag" ]; then @@ -74,7 +74,7 @@ runs: id: get_job_id uses: ./.github/actions/get-job-id with: - job_name: ${{ inputs.job-name }} + job_name: ${{ inputs.job_name }} run_id: ${{ github.run_id }} - name: Upload test results to GitHub @@ -82,7 +82,7 @@ runs: uses: actions/upload-artifact@v6 if: ${{ !cancelled() }} with: - name: junit-xml--${{ github.run_id }}--${{ steps.get_job_id.outputs.job_id }}--${{ github.run_attempt }}--${{ inputs.artifact-name-suffix }} + name: junit-xml--${{ github.run_id }}--${{ steps.get_job_id.outputs.job_id }}--${{ github.run_attempt }}--${{ inputs.artifact_name_suffix }} path: ./.testoutput/junit.*.xml include-hidden-files: true retention-days: 28 @@ -91,16 +91,16 @@ runs: uses: actions/upload-artifact@v6 if: ${{ !cancelled() }} with: - name: test-summary-json--${{ github.run_id }}--${{ steps.get_job_id.outputs.job_id }}--${{ github.run_attempt }}--${{ inputs.artifact-name-suffix }} + name: test-summary-json--${{ github.run_id }}--${{ steps.get_job_id.outputs.job_id }}--${{ github.run_attempt }}--${{ inputs.artifact_name_suffix }} path: ./.testoutput/test-summary.json if-no-files-found: ignore retention-days: 28 - name: Upload debug logs uses: actions/upload-artifact@v6 - if: ${{ !cancelled() && inputs.debug-log-path != '' }} + if: ${{ !cancelled() && inputs.debug_log_path != '' }} with: - name: debug-logs--${{ github.run_id }}--${{ steps.get_job_id.outputs.job_id }}--${{ github.run_attempt }}--${{ inputs.artifact-name-suffix }} - path: ${{ inputs.debug-log-path }} + name: debug-logs--${{ github.run_id }}--${{ steps.get_job_id.outputs.job_id }}--${{ github.run_attempt }}--${{ inputs.artifact_name_suffix }} + path: ${{ inputs.debug_log_path }} if-no-files-found: ignore retention-days: 14 diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index c2ca4f5a91..680159e2c1 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -324,8 +324,8 @@ jobs: env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: - job-name: Unit test - artifact-name-suffix: unit-test + job_name: Unit test + artifact_name_suffix: unit-test integration-test: name: Integration test @@ -378,8 +378,8 @@ jobs: env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: - job-name: Integration test - artifact-name-suffix: integration-test + job_name: Integration test + artifact_name_suffix: integration-test - name: Stop containerized dependencies if: ${{ always() }} @@ -463,10 +463,10 @@ jobs: env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: - job-name: Functional test (${{ matrix.name }}, ${{ matrix.display_name }}) - artifact-name-suffix: ${{ matrix.name }}--${{ matrix.display_name }}--functional-test - codecov-flag: functional-test - debug-log-path: ${{ github.workspace }}/.testoutput/debug.log + job_name: Functional test (${{ matrix.name }}, ${{ matrix.display_name }}) + artifact_name_suffix: ${{ matrix.name }}--${{ matrix.display_name }}--functional-test + codecov_flag: functional-test + debug_log_path: ${{ github.workspace }}/.testoutput/debug.log - name: Stop containerized dependencies if: always()