Make the image build multi-stage and cache-proof (closes #4)
All checks were successful
check / check (push) Successful in 23s
All checks were successful
check / check (push) Successful in 23s
The image build reported a green it had not earned. `script/cibuild` is a bare `docker build .`, and with `COPY . .` followed by `RUN make check`, an unchanged tree served that layer from cache: the suite never ran and the build still exited 0, while the script's header comment asserted the opposite. CHECK_EPOCH, passed by `script/cibuild` and `script/docker`, changes the cache key of the check and build layers on every invocation. It is guarded, because an unset ARG is the empty string and therefore a stable key: without the guard a plain `docker build .` — the command the policy names, and the one anyone debugging types — would still get the false green. A missing argument is now a hard failure rather than a silent degradation to the behaviour the epoch was added to prevent. The Dockerfile is now two stages: `fmt-check` and `lint` run first, and the check stage takes a `COPY --from=lint` dependency on them, so a formatting mistake fails the build in seconds instead of racing the suite to the finish. Both stages stay pinned to the same digest. The remaining fixes are one-liners that had made the target unusable: `script/projectname` still printed the pre-rename name, so `make docker` tagged its image after a name this project dropped in May; `script/bootstrap` installed without fetching apt's package lists, which cannot work on a Debian base; and `.dockerignore` had drifted far enough from `.gitignore` to ship a ~100 MB compiled binary and any agent worktree under `.claude/` into the build context. The second of those is a correctness problem, not a size one — vitest globs a copied worktree's tests alongside the real ones and runs the suite twice over. `.gitignore` itself stays in the context, because prettier reads it as a default ignore file and dropping it would change what `make fmt-check` sees.
This commit was merged in pull request #28.
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
#!/bin/sh
|
||||
# script/docker: build the Docker image tagged with the project name.
|
||||
# Identical in all repos; the tag comes from script/projectname.
|
||||
# CHECK_EPOCH is passed for the same reason script/cibuild passes it: the
|
||||
# Dockerfile refuses to build without it, so that no path to an image can
|
||||
# quietly serve the check and build layers from cache.
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
@@ -8,7 +11,8 @@ ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
docker build -t "$("$SCRIPT_DIR/projectname")" .
|
||||
docker build --build-arg CHECK_EPOCH="$(date +%s)" \
|
||||
-t "$("$SCRIPT_DIR/projectname")" .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user