Fail a bare docker build instead of serving cached gates (closes #39)
check / check (push) Failing after 3s

Each Dockerfile stage that runs gates now checks, right after its
ARG CHECK_EPOCH, that the value is not empty, and stops with a message
naming script/cibuild and script/docker. A plain `docker build .` can
no longer report a green from cached gate layers.

script/cibuild and script/docker now append the process id to the
epoch, the form script/lint already uses, so two runs started in the
same second still get different values.

README says both. TODO.md corrects the steady-state CACHED count
recorded for issue 32 from twelve to thirteen.

Model: opus-5-5
This commit is contained in:
2026-10-04 16:45:06 +00:00
parent 313aa0fc12
commit b3497407f2
5 changed files with 51 additions and 25 deletions
+17 -12
View File
@@ -28,6 +28,10 @@
# Completed Steps
- a bare `docker build .` fails with a message naming `script/cibuild` and
`script/docker` instead of serving the gates from cache (2026-10-04,
https://git.eeqj.de/sneak/sfdupes/issues/39)
- `make fmt` and `make fmt-check` run prettier over all Markdown, in Docker, and
CI checks it; all Markdown reformatted (2026-10-04,
https://git.eeqj.de/sneak/sfdupes/issues/19)
@@ -298,18 +302,19 @@
bug, not a fix. Verified by running each script twice back to back on an
unchanged tree under `BUILDKIT_PROGRESS=plain`: all three gates executed on
all four runs, each with a fresh epoch in the log (`script/cibuild` 78.8s then
61.1s; `script/docker` 61.1s then 53.4s), and twelve steps were still served
`CACHED` in the steady state — both `go mod download`s, `apk add`, `adduser`,
the `chown`, every `go.mod`/`go.sum` and source copy, the linter copy out of
the lint stage, and the binary copy into the runtime stage. The lint stage
still gates the build stage: with a deliberate `unused` finding planted in the
tree, the build failed at `make lint` in 36.1s and the build-stage
`make check` never started. The build stage also still drops to the
unprivileged `builder` user before `make check`, which the suite depends on
rather than merely prefers: forcing the same image to run the tests as root
fails `TestScanHardlinkRunFailsTogether`, because root reads straight through
the `chmod(0)` the test uses to prove hard links are read once. This is the
local fix only; propagating it to the canonical templates is `prompts` #26
61.1s; `script/docker` 61.1s then 53.4s), and thirteen steps were still served
`CACHED` in the steady state — the lint stage's `WORKDIR /src`, both
`go mod download`s, `apk add`, `adduser`, the `chown`, every `go.mod`/`go.sum`
and source copy, the linter copy out of the lint stage, and the binary copy
into the runtime stage. The lint stage still gates the build stage: with a
deliberate `unused` finding planted in the tree, the build failed at
`make lint` in 36.1s and the build-stage `make check` never started. The build
stage also still drops to the unprivileged `builder` user before `make check`,
which the suite depends on rather than merely prefers: forcing the same image
to run the tests as root fails `TestScanHardlinkRunFailsTogether`, because
root reads straight through the `chmod(0)` the test uses to prove hard links
are read once. This is the local fix only; propagating it to the canonical
templates is `prompts` #26
- check the installed golangci-lint version in `script/bootstrap` instead of
only its presence (2026-08-09, branch `bootstrap-version-check`, closes #24):
`missing golangci-lint` meant any linter already on `PATH` satisfied the