ci(build-image): bust cache for the three agent installers each run

The hourly cron's whole point per its header comment is to "pick up
new claude-code/codex/opencode releases", but `cache-from: type=gha`
matches each `RUN curl … install.sh | bash` by its (invariant)
instruction string, so the GHA layer cache served the same baked-in
binaries indefinitely — scheduled runs were ~30-60s of cache replay
that never refreshed the agents. claude-code 2.1.156 had been out
for a while and `:latest` was still on an older release.

Pass the per-build timestamp (`steps.ts.outputs.tag`, already
computed for the date-tagged image) as `AGENT_INSTALL_CACHEBUST`,
and reference it via an `ARG` placed right before the three
installer RUNs. That invalidates exactly those layers (and the
sanity-check RUN that follows) while keeping the heavy apt /
chromium / docker / nodejs layers above the ARG cached. Local
`images/build.sh` builds leave the empty default and behave as
before.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Evgeny Boger 2026-05-29 13:15:49 +00:00
parent 25d75e7181
commit 9240afbbd4
2 changed files with 22 additions and 0 deletions

View file

@ -100,6 +100,17 @@ jobs:
# microsandbox's `tar_ingest.rs:427` already accepts the
# `application/vnd.oci.image.layer.v1.tar+zstd` media type.
outputs: type=registry,push=true,compression=zstd,compression-level=3,force-compression=true
# Cache-bust the three agent-installer RUN layers each run
# by passing the per-build timestamp as a build-arg the
# Dockerfile references right before those RUNs. Without
# this, `cache-from: type=gha` matches the invariant
# `RUN curl … install.sh | bash` instruction strings and
# the hourly cron silently reused the same baked-in
# agent binaries instead of fetching new releases (the
# whole point of the schedule). The heavy apt/chromium/
# docker/node layers above the ARG stay cached.
build-args: |
AGENT_INSTALL_CACHEBUST=${{ steps.ts.outputs.tag }}
# `cache-from`/`cache-to` keep layer rebuilds fast when only
# the agent-version layers at the top of the Dockerfile
# change (the common hourly case).

View file

@ -179,6 +179,17 @@ RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
RUN sudo -u chrome -H npx -y chrome-devtools-mcp@1.0.1 --help >/dev/null 2>&1 \
|| echo "==> pre-warm skipped (will lazy-fetch chrome-devtools-mcp at first MCP call)"
# Cache-bust for the three agent installers below. The workflow
# passes the hourly timestamp tag as the value so each scheduled
# build invalidates exactly these RUN layers (and the sanity check
# that follows) while leaving the heavy apt/chromium/docker/node
# layers cached. Without this the GHA layer cache reuses the
# `curl … install.sh | bash` layers indefinitely, so hourly cron
# runs never picked up new claude-code/codex/opencode releases.
# Local `images/build.sh` builds leave the default empty value and
# get the normal Docker layer-cache behaviour.
ARG AGENT_INSTALL_CACHEBUST=
# Claude Code official installer.
RUN curl -fsSL https://claude.ai/install.sh | bash