script/docker has the same layer-cache hole as script/cibuild, so make docker can hand a developer an unearned green #124
Reference in New Issue
Block a user
Delete Branch "%!s()"
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?
Flagged by the implementer of PR #122 while fixing #115, and correctly left out of scope there.
script/dockerbuilds the image with no cache control:The Dockerfile does
COPY . .thenRUN make check, so on a byte-identical tree the check layer is served from the Docker layer cache and the suite never runs — exactly the defect #115 fixed inscript/cibuild.Why this is worth fixing even though it is not the CI gate
script/cibuildis what CI runs, and #115 has closed that hole. Butmake dockeris what a developer or agent runs locally to convince themselves the image builds and the checks pass. It is arguably the more dangerous of the two:make dockerfor a suspicious duration the way they now watchscript/cibuild.script/cibuildgenuinely re-runs the suite whilescript/dockermay not. Two commands that look interchangeable and are not is a trap, and the person who falls into it will have no reason to suspect anything.The severity is lower than #115 only because this is not the gate of record. The mechanism is identical.
Definition of done
script/dockercannot report a successful build without actually executingmake check, even on a byte-identical tree with a warm cache.ARG CHECK_EPOCHimmediately above the check step and passes--build-arg CHECK_EPOCH="$(date +%s)". Note the load-bearing detail that PR uncovered: the value must be expanded into theRUNcommand, not merely declared above it. BuildKit does not treatARGas a layer and keys each instruction on the command string after expansion, so a bareARGabove an unchangedRUN make checkleaves the instruction byte-identical and the layer still comes backCACHED— the bug reintroduced in a form that passes code review.go mod downloadmust remain above the invalidation line. Do not reach for a blanket--no-cache.script/projectname, so this script stays byte-identical across repos apart from the cache fix.script/dockerremains POSIXsh(#!/bin/sh,set -eu, no bashisms) and keeps the$(cd "$(dirname "$0")/.." && pwd -P)root-location idiom. Verify withsh -n.script/dockertwice in a row on an unchanged tree and confirm the second run still executes the suite (notCACHED, not sub-second). Then plant a deliberate always-failing test, runscript/docker, and confirm the build fails with that specific predicted message. Delete it, confirmgit statusis clean and no leftover is committed, and confirm the tree builds green again. Report both timings and the negative control verbatim. A cached layer cannot produce a failure predicted in advance — that is the only conclusive proof, and a code-reading argument is explicitly not sufficient here.make checkgreen;TODO.mdupdated in the same commit.The finishing commit's title must end with
(closes #N)referencing this issue.Hard constraints
golangoralpinesha256digests, golangci-lintc0d3ddc9cf3faa61a4e378e879ece580256d76e5, or goimports009367f5c17a8d4c45a961a3a509277190a9a6f0.make checkfrom the Dockerfile, narrowing it to lint-only, or adding-short/skip flags would delete the guarantee rather than fix it.TESTING.mdforbids-shortand skip flags by name..golangci.yml— sha256 must remain021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb.parallel golangci-lint is runningor names paths outside your worktree, and retry. IsolatingGOLANGCI_LINT_CACHEprevents cross-contamination but does not prevent lock collisions.Sequencing
Land after PR #122, which introduces the
ARG CHECK_EPOCHline this builds on. Starting before it merges means guessing at the mechanism and conflicting on theDockerfile.Also note #109 restructures the same
Dockerfilefor a fail-fastlintstage and anARG VERSION. Keep this PR minimal; whichever lands later rebases.Upstream
script/dockeris byte-identical across repos, so this belongs in the shared template alongside thescript/cibuildfix (prompts#26). Fixing it here does not depend on the upstream change landing, but the two should end up consistent.