Lint and test as phases of the Dockerfile (closes #38)
check / check (push) Failing after 3s
check / check (push) Failing after 3s
Lint and test are now phases of the one Dockerfile, as the current repo policy requires: a lint phase on the pinned golangci-lint image and a test phase on the pinned Go image, and the build stage depends on both, so a plain docker build . fails when either fails. Dockerfile.lint is gone. REPO_POLICIES.md and script/lint, test, docker and cibuild are byte-identical to the current sneak/prompts copies, so every docker build in script/ is uncached and tagged. make test now needs Docker on the host; formatting is checked on the host only. Judgement calls: the test phase installs gcc and musl-dev unpinned for -race; no -count=1, since a build stage holds no earlier result. Model: opus-5-5
This commit was merged in pull request #43.
This commit is contained in:
+4
-4
@@ -3,9 +3,9 @@
|
||||
# repo. Idempotent: every install is guarded by a check, so tools that
|
||||
# are already there are left alone. Base tooling comes from nix, apt,
|
||||
# brew, or apk, detected in that order, and nothing is assumed to be
|
||||
# present. The linter is not installed here: it only ever runs inside
|
||||
# the image built from Dockerfile.lint, so Docker is what is needed for
|
||||
# it, and that is checked for rather than installed.
|
||||
# present. The linter is not installed here: linting and testing run
|
||||
# only as phases of the Dockerfile, so Docker is what is needed for
|
||||
# them, and that is checked for rather than installed.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
@@ -60,7 +60,7 @@ main() {
|
||||
go mod download
|
||||
|
||||
if missing docker; then
|
||||
echo "bootstrap: docker is not installed; make lint needs it" >&2
|
||||
echo "bootstrap: docker is not installed; make lint and make test need it" >&2
|
||||
fi
|
||||
|
||||
echo "bootstrap complete"
|
||||
|
||||
+17
-6
@@ -1,8 +1,10 @@
|
||||
#!/bin/sh
|
||||
# script/cibuild: run the CI build. The linter needs an image of its
|
||||
# own, so it runs first; the Dockerfile then runs the formatting check,
|
||||
# the tests and the build, so a green run here means make check is
|
||||
# green.
|
||||
# script/cibuild: run the CI build. It bootstraps first: a CI runner
|
||||
# checks out and runs this and nothing else, and script/fmt-check runs
|
||||
# the formatter on the host, which a pristine checkout cannot do.
|
||||
# --no-cache for the same reason as script/docker: the gate phases the
|
||||
# final stage depends on are RUN steps, and a cached one is a check that
|
||||
# did not run.
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
@@ -10,8 +12,17 @@ ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
"$SCRIPT_DIR/lint"
|
||||
docker build .
|
||||
"$SCRIPT_DIR/bootstrap"
|
||||
"$SCRIPT_DIR/check"
|
||||
# Own line: a failing command substitution inside an argument does
|
||||
# not trip `set -e`, so the inline form degrades silently to an
|
||||
# empty constant. The VERSION build argument takes precedence over
|
||||
# the version a build stage derives from the .git in the context.
|
||||
version="$(git describe --tags --always --dirty 2>/dev/null || true)"
|
||||
[ -n "$version" ] || version="unknown"
|
||||
docker build --no-cache \
|
||||
--build-arg VERSION="$version" \
|
||||
-t "$("$SCRIPT_DIR/projectname")" .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
+11
-1
@@ -1,6 +1,8 @@
|
||||
#!/bin/sh
|
||||
# script/docker: build the Docker image tagged with the project name.
|
||||
# Identical in all repos; the tag comes from script/projectname.
|
||||
# --no-cache because the gate phases the final stage depends on are RUN
|
||||
# steps, and a cached one is a check that did not run.
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
@@ -8,7 +10,15 @@ ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
docker build -t "$("$SCRIPT_DIR/projectname")" .
|
||||
# Own line: a failing command substitution inside an argument does
|
||||
# not trip `set -e`, so the inline form degrades silently to an
|
||||
# empty constant. The VERSION build argument takes precedence over
|
||||
# the version a build stage derives from the .git in the context.
|
||||
version="$(git describe --tags --always --dirty 2>/dev/null || true)"
|
||||
[ -n "$version" ] || version="unknown"
|
||||
docker build --no-cache \
|
||||
--build-arg VERSION="$version" \
|
||||
-t "$("$SCRIPT_DIR/projectname")" .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
+11
-6
@@ -1,9 +1,13 @@
|
||||
#!/bin/sh
|
||||
# script/lint: run the linter. Linting only ever happens inside the
|
||||
# image built from Dockerfile.lint, which pins the linter by hash, so
|
||||
# the answer is the same on every machine and in CI. The linter runs as
|
||||
# a build step of that image, so a complaint fails the build and no
|
||||
# container is left behind.
|
||||
# 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.
|
||||
#
|
||||
# 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
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
@@ -11,7 +15,8 @@ ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
docker build --progress=plain -f Dockerfile.lint \
|
||||
docker build --no-cache \
|
||||
--target lint \
|
||||
-t "$("$SCRIPT_DIR/projectname")-lint" .
|
||||
}
|
||||
|
||||
|
||||
+10
-4
@@ -1,13 +1,19 @@
|
||||
#!/bin/sh
|
||||
# script/test: run the test suite (vet first, verbose rerun on failure).
|
||||
# script/test: run the test suite. Testing is a phase of the Dockerfile
|
||||
# and this builds that phase alone, on the same terms as script/lint:
|
||||
# --target because a phase that is not the last stage is built only when
|
||||
# named, --no-cache because a cached test layer is a test that did not
|
||||
# run, and a tag so each build replaces the previous image.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
go vet ./...
|
||||
go test -timeout 90s ./... || go test -timeout 90s -v ./...
|
||||
docker build --no-cache \
|
||||
--target test \
|
||||
-t "$("$SCRIPT_DIR/projectname")-test" .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user