diff --git a/.github/workflows/build-depends.yml b/.github/workflows/build-depends.yml index d6679e47c79d..d3600b3806cc 100644 --- a/.github/workflows/build-depends.yml +++ b/.github/workflows/build-depends.yml @@ -11,6 +11,10 @@ on: description: "Path to built container at registry" required: true type: string + base-image-digest: + description: "Short hash of the CI base image manifest for cache busting" + required: true + type: string runs-on: description: "Runner label to use (e.g., ubuntu-24.04 or ubuntu-24.04-arm)" required: true @@ -33,6 +37,7 @@ jobs: outputs: cache-hit: ${{ steps.cache-check.outputs.cache-hit }} cache-key: ${{ steps.setup.outputs.cache-key }} + cache-key-prefix: ${{ steps.setup.outputs.cache-key-prefix }} host: ${{ steps.setup.outputs.HOST }} dep-opts: ${{ steps.setup.outputs.DEP_OPTS }} steps: @@ -62,7 +67,9 @@ jobs: echo "DEP_HASH=${DEP_HASH}" >> "${GITHUB_OUTPUT}" DOCKERFILE_HASH="${{ hashFiles('contrib/containers/ci/ci.Dockerfile', 'contrib/containers/ci/ci-slim.Dockerfile') }}" PACKAGES_HASH="${{ hashFiles('depends/packages/*', 'depends/Makefile') }}" - CACHE_KEY="depends-${DOCKERFILE_HASH}-${{ inputs.runs-on }}-${{ inputs.build-target }}-${DEP_HASH}-${PACKAGES_HASH}" + CACHE_KEY_PREFIX="depends-${DOCKERFILE_HASH}-${{ inputs.base-image-digest }}-${{ inputs.runs-on }}-${{ inputs.build-target }}" + CACHE_KEY="${CACHE_KEY_PREFIX}-${DEP_HASH}-${PACKAGES_HASH}" + echo "cache-key-prefix=${CACHE_KEY_PREFIX}" >> "${GITHUB_OUTPUT}" echo "cache-key=${CACHE_KEY}" >> "${GITHUB_OUTPUT}" echo "Cache key: ${CACHE_KEY}" shell: bash @@ -124,7 +131,7 @@ jobs: path: depends/built/${{ needs.check-cache.outputs.host }} key: ${{ needs.check-cache.outputs.cache-key }} restore-keys: | - depends-${{ hashFiles('contrib/containers/ci/ci.Dockerfile', 'contrib/containers/ci/ci-slim.Dockerfile') }}-${{ inputs.build-target }}- + ${{ needs.check-cache.outputs.cache-key-prefix }}- - name: Build depends run: | diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 67b2b595fc3f..9d3e62774963 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,6 +29,7 @@ jobs: use-blacksmith: ${{ steps.select-runner.outputs.use_blacksmith }} backlog-count: ${{ steps.select-runner.outputs.backlog_count }} decision-reason: ${{ steps.select-runner.outputs.decision_reason }} + base-image-digest: ${{ steps.base-image.outputs.digest }} steps: - name: Check skip environment variables id: skip-check @@ -58,6 +59,26 @@ jobs: run: | python3 .github/workflows/select_dynamic_runner.py + - name: Get base image digest + id: base-image + if: ${{ steps.skip-check.outputs.skip == 'false' }} + run: | + # Fetch the canonical manifest digest for ubuntu:noble so the + # depends cache key changes when Canonical pushes base image + # updates (which may bump compiler versions). + # Falls back to "unknown" on failure so CI is not blocked. + TOKEN="$(curl -fsSL --max-time 10 \ + 'https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/ubuntu:pull' \ + | jq -r '.token')" || true + if [ -n "$TOKEN" ] && [ "$TOKEN" != "null" ]; then + DIGEST="$(curl -fsSL --max-time 10 \ + -H "Authorization: Bearer $TOKEN" \ + -H 'Accept: application/vnd.docker.distribution.manifest.list.v2+json' \ + 'https://registry-1.docker.io/v2/library/ubuntu/manifests/noble' \ + -o /dev/null -D - | grep -i docker-content-digest | awk '{print $2}' | tr -d '\r' | sed 's/^sha256://')" || true + fi + echo "digest=${DIGEST:-unknown}" >> "$GITHUB_OUTPUT" + cache-sources: name: Cache depends sources needs: [check-skip] @@ -98,6 +119,7 @@ jobs: with: build-target: aarch64-linux container-path: ${{ needs.container.outputs.path }} + base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }} runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} depends-linux64: @@ -112,6 +134,7 @@ jobs: with: build-target: linux64 container-path: ${{ needs.container.outputs.path }} + base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }} runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} depends-linux64_multiprocess: @@ -124,6 +147,7 @@ jobs: with: build-target: linux64_multiprocess container-path: ${{ needs.container.outputs.path }} + base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }} runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }} depends-linux64_nowallet: @@ -134,6 +158,7 @@ jobs: with: build-target: linux64_nowallet container-path: ${{ needs.container.outputs.path }} + base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }} runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} depends-mac: @@ -144,6 +169,7 @@ jobs: with: build-target: mac container-path: ${{ needs.container.outputs.path }} + base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }} runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} depends-win64: @@ -154,6 +180,7 @@ jobs: with: build-target: win64 container-path: ${{ needs.container.outputs.path }} + base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }} runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} lint: