Run lint and tests as Dockerfile phases built with --no-cache (closes #202)
check / check (push) Failing after 3s

script/check, cibuild, docker, lint, test, setup and install-precommit
are now the sneak/prompts main copies, unchanged: lint and test each
build their Dockerfile phase with --no-cache. The lint phase runs
golangci-lint from the image REPO_POLICIES.md names, with libvips-dev
from apt-get; the test phase runs the tests with a 90-second timeout;
the build stage depends on both. script/bootstrap installs the C
compiler and image libraries only with --cgo, which the test phase and
build stage pass, and refreshes the apt lists before its first apt
install. Dockerfile.lint and CHECK_EPOCH are gone, and make
docker-versioned and docker-test call the scripts. Without VERSION the
build stage still uses git describe, per issue 166.

Model: opus-5-5
This commit was merged in pull request #218.
This commit is contained in:
2026-10-05 03:41:50 +02:00
parent 55cf7f4fac
commit a941a80bf9
13 changed files with 175 additions and 156 deletions
+13 -27
View File
@@ -1,37 +1,23 @@
#!/bin/sh
# script/lint: run golangci-lint over the whole tree. This is the only
# way the linter is run, everywhere; it is never installed on the host.
# script/lint: run the linter. Linting is a phase of the Dockerfile and
# this builds that phase alone; the linter is never installed or run on
# a developer host, where a shared result cache and a host-global lock
# make its answer untrustworthy.
#
# Inside a container it runs the linter. Anywhere else it builds
# Dockerfile.lint, whose last step runs this script again inside that
# container.
#
# Dockerfile.lint and the Dockerfile lint stage set container=docker
# (the systemd convention for marking a container) to say where we are.
# /.dockerenv cannot: it is missing inside build steps, and present on
# hosts that are themselves containers.
# The phase is not the last stage in the file, so it is built only when
# --target names it. --no-cache because a cached lint layer is a lint
# that did not run. The tag makes each build replace the previous image
# instead of leaving a dangling one behind.
set -eu
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
main() {
cd "$ROOT"
if [ "${container:-}" = docker ]; then
# `golangci-lint config verify` is not run: it fetches its JSON
# schema over an unpinned live HTTPS call, which REPO_POLICIES.md
# forbids.
echo "Running linter..."
golangci-lint run --config .golangci.yml ./...
else
# A new CACHEBUST on every run means the lint step is never
# served from cache (see Dockerfile.lint). The cacheonly output
# leaves no image behind.
docker build \
--progress=plain \
--build-arg CACHEBUST="$(date +%s)-$$" \
--output=type=cacheonly \
-f Dockerfile.lint .
fi
docker build --no-cache \
--target lint \
-t "$("$SCRIPT_DIR/projectname")-lint" .
}
main "$@"