Seed from go-template-repo, renamed to simplexcalc
The template's files at a77fd30, without its history or LICENSE, after script/rename simplexcalc. Model: opus-5-5
This commit is contained in:
Executable
+89
@@ -0,0 +1,89 @@
|
||||
#!/bin/sh
|
||||
# script/cibuild: run the CI build. The Dockerfile runs the checks
|
||||
# (gofmt, config verify, lint, test), so a successful build implies a
|
||||
# green repo. The Gitea workflow runs this on push.
|
||||
#
|
||||
# Only if the checks actually ran, though, and a green `docker build` is
|
||||
# no evidence that they did:
|
||||
#
|
||||
# 1. On an unchanged tree every layer comes from cache and the build
|
||||
# exits 0 in under a second having executed nothing. Hence the two
|
||||
# --no-cache-filter flags.
|
||||
#
|
||||
# 2. BuildKit silently ignores a --no-cache-filter naming a stage that
|
||||
# does not exist, so a rename restores that green no-op.
|
||||
#
|
||||
# 3. BuildKit builds only the final stage's dependency graph. A stage
|
||||
# nothing references is never built, and with no --target the final
|
||||
# stage is whichever is last in the file — so appending a stage, or
|
||||
# moving a reference into a stage that is itself unreachable, drops
|
||||
# the checks out of the build while every reference to them is still
|
||||
# there to read.
|
||||
#
|
||||
# Rather than predict any of that from the Dockerfile's text, this asks
|
||||
# the finished build what it did: script/assert-step-ran requires that
|
||||
# the log contain a lint step and a test step that ran, and that each
|
||||
# wrote the line its own tool writes on success. Every trap above ends
|
||||
# with the step absent from the log or served from cache, and both fail
|
||||
# that assertion. See that script for what it does not cover.
|
||||
#
|
||||
# 4. A step that ran is not a step that saw the repo. .dockerignore, or
|
||||
# a COPY narrower than the tree, removes files from the build
|
||||
# context, and the linter then reports `0 issues.` over what is left
|
||||
# while `go test ./...` never compiles the package that went missing.
|
||||
# So each source-consuming stage inventories what reached it, and
|
||||
# script/assert-context-complete compares that inventory against the
|
||||
# git index — a source .dockerignore cannot reach.
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
dockerfile=Dockerfile
|
||||
lint_stage=lint
|
||||
test_stage=builder
|
||||
|
||||
# `ok <pkg> 1.234s`: go test prints `(cached)` in place of the duration
|
||||
# when it replays a result, so requiring the duration requires a package
|
||||
# that was really exercised.
|
||||
test_ran='^ok[[:space:]]+[^[:space:]]+[[:space:]]+[0-9]+[.][0-9]+s'
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
|
||||
tmp="$(mktemp -d "${TMPDIR:-/tmp}/$("$SCRIPT_DIR/projectname")-cibuild.XXXXXX")"
|
||||
trap 'rm -rf "$tmp"' EXIT INT TERM
|
||||
|
||||
# --progress=plain is load-bearing: the assertions below read the
|
||||
# steps' own output out of this log, and the tty renderer discards
|
||||
# all but the tail of it. The exit status travels through a file
|
||||
# because a pipeline's status is the last command's; `set +e` is
|
||||
# what lets the recording line run at all, since errexit would
|
||||
# otherwise abandon the subshell on a failing build. A missing file
|
||||
# reads as failure.
|
||||
(
|
||||
set +e
|
||||
docker build \
|
||||
--progress=plain \
|
||||
--no-cache-filter="$lint_stage" \
|
||||
--no-cache-filter="$test_stage" \
|
||||
-f "$dockerfile" . 2>&1
|
||||
echo "$?" >"$tmp/status"
|
||||
) | tee "$tmp/build.log"
|
||||
|
||||
status="$(cat "$tmp/status" 2>/dev/null || echo 1)"
|
||||
[ "${status:-1}" -eq 0 ] || exit "${status:-1}"
|
||||
|
||||
script/assert-step-ran "$tmp/build.log" "$lint_stage" \
|
||||
'^RUN golangci-lint run' '^0 issues[.]$' 'the linter'
|
||||
script/assert-step-ran "$tmp/build.log" "$test_stage" \
|
||||
'^RUN go test' "$test_ran" 'the tests'
|
||||
|
||||
# Both stages, separately: each has its own COPY, so an intact
|
||||
# context in one is no evidence about the other.
|
||||
script/repo-source-manifest >"$tmp/expected"
|
||||
script/assert-context-complete "$tmp/build.log" "$lint_stage" "$tmp/expected"
|
||||
script/assert-context-complete "$tmp/build.log" "$test_stage" "$tmp/expected"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user