Force check layers to execute on every cibuild run (closes #89) #96
Reference in New Issue
Block a user
Delete Branch "fix/cibuild-check-cache-89"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The problem
script/cibuildran a baredocker build .. The Dockerfile doesCOPY . .and then runs the checks, so on an unchanged tree every check layer was a
cache hit — the suite never executed and the build still exited 0.
Issue #89 measured a second run at
0.624s with every check layer
CACHED. A green fromscript/cibuilddid notmean the checks passed, only that they had passed at some point in the past.
The fix
ARG CHECK_EPOCHis declared in every stage that runs a check, below thedependency layers and immediately above the first check, and
script/cibuildpasses a fresh
$(date +%s)on each invocation. A changed build arginvalidates every layer below its declaration, so the checks always execute
while the base images,
go mod downloadand theyarn installinmdfmtstay cached.
All three check-running stages are covered.
ARGis scoped per stage, so astage without its own declaration keeps serving a cached pass and is
indistinguishable from a working fix at the exit code:
lintmake fmt-check-go,make lintmdfmtscript/prettier --checkbuildermake testThe
mdfmtstage already exists onnext— it landed with#69 in
5683d0f— so it is patchedhere rather than left for later.
--no-cachewas deliberately not used: it would also discardgo mod downloadand the yarn install, for no additional guarantee.
Evidence: two consecutive runs on an unchanged tree
Cache pre-warmed, then
script/cibuildrun twice back to back withgit status --porcelainempty between them. Both exited 0.Neither run completes in 0.624s, and both took essentially identical wall
time — the signature of the checks actually running each time.
Full step inventory for run 2 (the unchanged-tree repeat), derived from
BUILDKIT_PROGRESS=plain. Every check layer isEXECUTED; no check layer isCACHED:Verbatim proof the checks produced fresh output in both runs:
The dependency layers stayed cached exactly as required:
go mod download(#11, #26) and
yarn install --frozen-lockfile(#14).Evidence: the checks are load-bearing
A gofmt violation was appended to
cmd/mfer/main.goandscript/cibuildre-run:The change was then reverted.
script/cibuildcannot exit 0 without the checkshaving run and passed.
Build time
Well under the 5 minute budget:
--no-cache, everything rebuiltMeasured with
/usr/bin/time -pon linux/arm64, Docker 29.2.1, BuildKit v0.24.0.Notes
.gitea/workflows/check.ymlinvokesscript/cibuild, so CI picks this upwith no workflow change.
PR #88 is not backfill-invalidated;
both were separately verified with explicit cache control.
README.mdedit is confined to the four-line Build Status paragraph, tominimise collision with
PR #95, which is in review on
fix/gpg-subprocess-timeouts. That branch was not touched.script/docker(make docker) still runs a plaindocker buildand so can still serve cached checks. It is a local convenience target, not a
CI entrypoint; #89 is specifically
about
script/cibuild. Say the word and I will extend it there too.Closes #89
Force check layers to execute on every cibuild runto Force check layers to execute on every cibuild run (closes #89)Closed at sneak's instruction, 2026-09-05: this was opened by an agent running on another machine outside the managed fleet, under superseded rules. Reopen if the content is wanted.
Model: fable-5-1
Pull request closed