From e9544679d0bf7e1e6fae4a7173c30a522b30a043 Mon Sep 17 00:00:00 2001 From: sneak Date: Sun, 4 Oct 2026 09:33:49 +0000 Subject: [PATCH] Run the checks again on every script/cibuild (closes #54) On an unchanged tree docker served every check step of the Dockerfile from its build cache, so a second script/cibuild ran no lint, tests or build and still succeeded. script/cibuild now passes the current time as the CHECK_EPOCH build argument. The lint and build stages each declare it after their module download and before `COPY . .`. A build argument whose value changes makes every RUN step after its declaration miss the cache, so the checks run on each build while the base images, the apk install and the module downloads stay cached. Model: opus-5-5 --- Dockerfile | 8 ++++++++ README.md | 3 ++- TODO.md | 8 ++++++++ script/cibuild | 6 +++++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index df5ea97..8e852de 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,11 @@ WORKDIR /src COPY go.mod go.sum ./ RUN go mod download +# script/cibuild sets CHECK_EPOCH to the current time, so the RUN steps +# below run again on each build, an unchanged tree included, while the +# steps above stay cached. ARG is per stage: the build stage declares it too. +ARG CHECK_EPOCH + COPY . . RUN make fmt-check @@ -25,6 +30,9 @@ WORKDIR /build COPY go.mod go.sum ./ RUN go mod download +# As in the lint stage: the RUN steps below run again on each script/cibuild. +ARG CHECK_EPOCH + COPY . . RUN make test diff --git a/README.md b/README.md index 29d497d..f89b5a6 100644 --- a/README.md +++ b/README.md @@ -523,7 +523,8 @@ them. We provide: - `script/docker` — build the Docker image tagged with the project name - `script/cibuild` — CI entrypoint: `docker build --ulimit memlock=-1:-1 .` (memguard needs mlock; the Dockerfile runs the - checks) + checks), with a new `CHECK_EPOCH` build argument on every run so the + checks run again on an unchanged tree - `script/precommit` — pre-commit checks: `go mod tidy` verification, then `script/check` - `script/install-precommit` — install the git pre-commit hook that diff --git a/TODO.md b/TODO.md index f04fe2f..d89b291 100644 --- a/TODO.md +++ b/TODO.md @@ -25,6 +25,14 @@ Bring the repo into policy compliance in one commit: # Completed Steps +- 2026-10-04: `script/cibuild` runs the checks again on an unchanged + tree (https://git.eeqj.de/sneak/secret/issues/54). It passes the + current time as the `CHECK_EPOCH` build argument, which both the lint + and the build stage of the `Dockerfile` declare after their module + download, so the `RUN` steps below the argument run again on each + build while the base images and module downloads stay cached. Before, + a second run on the same tree took every check from the build cache + and reported success having run nothing. - 2026-10-04: A failed unlocker add no longer leaves a partial unlocker directory (https://git.eeqj.de/sneak/secret/issues/48). `secret unlocker add pgp` resolves the GPG key's fingerprint once, for diff --git a/script/cibuild b/script/cibuild index 3316194..58bf15f 100755 --- a/script/cibuild +++ b/script/cibuild @@ -4,13 +4,17 @@ # The Gitea workflow runs this on push. The memlock ulimit lets the tests # that lock large secrets in memory (memguard mlocks them) run; under the # lower limit of a plain `docker build .` they are skipped. +# A cached build checks nothing: a new CHECK_EPOCH on every run makes the +# Dockerfile's check steps run again on an unchanged tree, while its base +# images and module downloads stay cached. set -eu ROOT="$(cd "$(dirname "$0")/.." && pwd -P)" main() { cd "$ROOT" - docker build --ulimit memlock=-1:-1 . + docker build --ulimit memlock=-1:-1 \ + --build-arg CHECK_EPOCH="$(date +%s)" . } main "$@" -- 2.54.0