From 26008e4a9dc0c785d018b0a31db4d26ff12bf124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Fr=C3=A8rejean?= Date: Mon, 22 Jun 2026 15:59:57 +0200 Subject: [PATCH] ci: pin and cache the MySQL image to survive Docker Hub outages The PHP 8.5 PHPUnit job intermittently failed at 'Start services' when Docker Hub timed out pulling the mysql image, cascading into empty test reports. Pin db to mysql:8.4 (LTS, dependabot-trackable) and add a composite action that restores the image from the Actions cache, only pulling from Docker Hub on a miss. Wired into both jobs since the static-analysis job also starts db as a dependency. --- .docker/compose.yml | 2 +- .github/actions/cache-mysql-image/action.yml | 39 ++++++++++++++++++++ .github/workflows/ci.yml | 4 ++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 .github/actions/cache-mysql-image/action.yml diff --git a/.docker/compose.yml b/.docker/compose.yml index 8135759..9161361 100644 --- a/.docker/compose.yml +++ b/.docker/compose.yml @@ -34,7 +34,7 @@ services: SS_PHPUNIT_FLUSH: 1 db: - image: mysql:8 + image: mysql:8.4 ports: - "${DB_PORT}:3306" volumes: diff --git a/.github/actions/cache-mysql-image/action.yml b/.github/actions/cache-mysql-image/action.yml new file mode 100644 index 0000000..1d312af --- /dev/null +++ b/.github/actions/cache-mysql-image/action.yml @@ -0,0 +1,39 @@ +name: Cache MySQL image +description: >- + Restore the db service image from the Actions cache, falling back to a single + pull-and-save on a miss. Keeps a Docker Hub rate limit or registry outage from + failing CI on every run, since the image only has to be fetched once per + cache lifetime instead of on every job. + +inputs: + compose-file: + description: Compose file that declares the db service whose image to cache. + default: .docker/compose.yml + +runs: + using: composite + steps: + # Resolve the image straight from the compose file so this stays correct + # if the pinned version changes — compose.yml is the single source of truth. + - id: image + shell: bash + run: | + ref="$(docker compose -f '${{ inputs.compose-file }}' config --images db)" + echo "ref=$ref" >> "$GITHUB_OUTPUT" + echo "key=$(printf '%s' "$ref" | tr -c '[:alnum:].' '-')" >> "$GITHUB_OUTPUT" + + - id: cache + uses: actions/cache@v4 + with: + path: /tmp/db-image.tar + key: db-image-${{ steps.image.outputs.key }} + + - if: steps.cache.outputs.cache-hit == 'true' + shell: bash + run: docker load --input /tmp/db-image.tar + + - if: steps.cache.outputs.cache-hit != 'true' + shell: bash + run: | + docker pull '${{ steps.image.outputs.ref }}' + docker save '${{ steps.image.outputs.ref }}' --output /tmp/db-image.tar diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 724e28b..7ea4f40 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,8 @@ jobs: steps: - uses: actions/checkout@v6 - run: make .docker/.env + - uses: ./.github/actions/cache-mysql-image + name: Cache MySQL image - run: $COMPOSE up -d --build --wait app name: Start services - run: make analyse @@ -39,6 +41,8 @@ jobs: steps: - uses: actions/checkout@v6 - run: make .docker/.env + - uses: ./.github/actions/cache-mysql-image + name: Cache MySQL image - run: $COMPOSE up -d --build --wait name: Start services - run: mkdir -p reports