From 7f839e161718355b1b41b88017938b4e4e1493df Mon Sep 17 00:00:00 2001 From: Alumos <1281610535@qq.com> Date: Thu, 12 Nov 2026 22:26:56 +0800 Subject: [PATCH] ci: read-only Go build mount for CI and release images Pull request and tag runs restore the main branch's Go build mount without extracting or writing caches that no other ref can read; the main-branch warmer is the only writer. Module and pnpm mounts are dropped because their layers are already cached. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/cache.yaml | 15 ++++++++------- .github/workflows/ci.yaml | 28 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.github/workflows/cache.yaml b/.github/workflows/cache.yaml index 8d552f5..0781c4b 100644 --- a/.github/workflows/cache.yaml +++ b/.github/workflows/cache.yaml @@ -100,21 +100,22 @@ jobs: persist-credentials: false - uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 id: buildx - - name: Cache BuildKit mounts + # The only writer of the Go build mount that CI and release image builds restore. + - name: Cache the Go build mount id: mount-cache uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: buildkit-mounts - key: buildkit-mounts-${{ matrix.arch }}-${{ hashFiles('go.sum', 'web/pnpm-lock.yaml') }}-${{ hashFiles('**/*.go', 'web/src/**') }} + key: buildkit-go-build-${{ matrix.arch }}-${{ hashFiles('go.sum') }}-${{ hashFiles('**/*.go') }} restore-keys: | - buildkit-mounts-${{ matrix.arch }}-${{ hashFiles('go.sum', 'web/pnpm-lock.yaml') }}- - buildkit-mounts-${{ matrix.arch }}- - - name: Inject BuildKit mounts + buildkit-go-build-${{ matrix.arch }}-${{ hashFiles('go.sum') }}- + buildkit-go-build-${{ matrix.arch }}- + - name: Inject the Go build mount uses: reproducible-containers/buildkit-cache-dance@5422eac04292c961a382e0f584ea0f03ad9da723 # v3.4.0 with: builder: ${{ steps.buildx.outputs.name }} - dockerfile: Dockerfile - cache-dir: buildkit-mounts + cache-map: | + {"buildkit-mounts/go-build": "/root/.cache/go-build"} skip-extraction: ${{ steps.mount-cache.outputs.cache-hit }} - name: Build image layers uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index abe0051..fce526c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -207,25 +207,25 @@ jobs: node-version-file: .node-version - uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 id: buildx - # Layer caching cannot keep RUN --mount=type=cache directories, so every image rebuilt Go and - # frontend dependencies from scratch. Persist those mounts per architecture and source state. - - name: Cache BuildKit mounts - id: mount-cache - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + # Layer caching cannot keep RUN --mount=type=cache directories, so every image recompiled Go + # from scratch. Only the Go build cache matters on a code change (module and pnpm downloads + # are cached layers). Pull request and tag caches are invisible to other refs, so this job + # only reads what the main-branch warmer (cache.yaml) saved and never extracts or writes back. + - name: Restore the Go build mount + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: buildkit-mounts - key: buildkit-mounts-${{ matrix.arch }}-${{ hashFiles('go.sum', 'web/pnpm-lock.yaml') }}-${{ hashFiles('**/*.go', 'web/src/**') }} + key: buildkit-go-build-${{ matrix.arch }}-${{ hashFiles('go.sum') }}-${{ hashFiles('**/*.go') }} restore-keys: | - buildkit-mounts-${{ matrix.arch }}-${{ hashFiles('go.sum', 'web/pnpm-lock.yaml') }}- - buildkit-mounts-${{ matrix.arch }}- - - name: Inject BuildKit mounts + buildkit-go-build-${{ matrix.arch }}-${{ hashFiles('go.sum') }}- + buildkit-go-build-${{ matrix.arch }}- + - name: Inject the Go build mount uses: reproducible-containers/buildkit-cache-dance@5422eac04292c961a382e0f584ea0f03ad9da723 # v3.4.0 with: builder: ${{ steps.buildx.outputs.name }} - # The mounts are discovered from the Dockerfile, so new cache mounts are persisted too. - dockerfile: Dockerfile - cache-dir: buildkit-mounts - skip-extraction: ${{ steps.mount-cache.outputs.cache-hit }} + cache-map: | + {"buildkit-mounts/go-build": "/root/.cache/go-build"} + skip-extraction: true - name: Build image for the native runner uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 with: @@ -237,8 +237,8 @@ jobs: VERSION=${{ env.BUILD_VERSION }} REVISION=${{ github.sha }} SOURCE_URL=${{ github.server_url }}/${{ github.repository }} + # Layers come from the main-branch warmer; exporting them here would only fill this ref's scope. cache-from: type=gha,scope=container-${{ matrix.arch }} - cache-to: type=gha,mode=max,scope=container-${{ matrix.arch }} # The tested image is transported through docker save/load before publication. provenance: false - name: Test runtime, persistence and maintenance commands