build: re-vendor canonical files from prompts dd4027b (closes #257)
check / check (push) Successful in 5m46s
check / check (push) Successful in 5m46s
The canonical files are fetched whole from sneak/prompts at dd4027b; .golangci.yml keeps the livednstest deny entry and .dockerignore adds /bin. Lint and test are phases of the Dockerfile (golangci-lint v2.14.0; tests on the Debian Go 1.25.7 image with the same flags), and the build stage depends on both and stamps the version the canonical way. Dockerfile.lint is gone; the prettier stages of Dockerfile.fmt moved into the Dockerfile, so Markdown formatting still runs in Docker. Every scripted docker build passes --no-cache; script/cibuild bootstraps, runs script/check, then builds the image. script/fmt-check absorbs fmt-check-go and fmt-check-markdown. The canonical .gitignore has no bin/ entry. The new linter raised no findings. Model: opus-5-5
This commit is contained in:
+8
-8
@@ -3,12 +3,12 @@
|
||||
# this repo. Idempotent: every install is guarded by a check so already
|
||||
# installed tools are skipped. Base tooling comes from nix, apt, brew,
|
||||
# or apk (detected in that order); assumes nothing is present.
|
||||
# goimports is not installed here: script/fmt and script/fmt-check-go
|
||||
# run it with `go run` at a pinned commit.
|
||||
# goimports is not installed here: script/fmt and script/fmt-check run
|
||||
# it with `go run` at a pinned commit.
|
||||
# The linter is NOT installed here: golangci-lint runs via docker only
|
||||
# (script/lint), pinned by image digest, so its only prerequisite is a
|
||||
# working docker. Nor is prettier: script/fmt and
|
||||
# script/fmt-check-markdown run it in a container from Dockerfile.fmt.
|
||||
# working docker. Nor is prettier: script/fmt and script/fmt-check run
|
||||
# it in a stage of the Dockerfile.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
@@ -67,12 +67,12 @@ main() {
|
||||
if missing make; then pkg_install gnumake make make make; fi
|
||||
if missing go; then pkg_install go golang go go; fi
|
||||
|
||||
# Linting and the markdown formatter run via docker only. Warn,
|
||||
# don't fail: building and testing work without it.
|
||||
# Testing, linting and the markdown formatter run via docker only.
|
||||
# Warn, don't fail: make build works without it.
|
||||
if missing docker; then
|
||||
echo "bootstrap: WARNING: docker not found; install it to" \
|
||||
"run make lint, make fmt, make fmt-check, make check" \
|
||||
"and make docker." >&2
|
||||
"run make test, make lint, make fmt, make fmt-check," \
|
||||
"make check and make docker." >&2
|
||||
fi
|
||||
|
||||
go mod download
|
||||
|
||||
+17
-12
@@ -1,14 +1,10 @@
|
||||
#!/bin/sh
|
||||
# script/cibuild: run the CI build. The Dockerfile's lint stage runs
|
||||
# the Go half of make fmt-check and golangci-lint; its builder stage
|
||||
# runs make test and make build. The markdown half of make fmt-check
|
||||
# runs after that build, as its own build of Dockerfile.fmt, because
|
||||
# there is no docker inside a docker build.
|
||||
#
|
||||
# --no-cache-filter=lint,builder runs both stages on every invocation;
|
||||
# otherwise an unchanged tree is served from the layer cache and passes
|
||||
# without linting or querying live DNS. script/fmt-check-markdown busts
|
||||
# its own cache the same way.
|
||||
# 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)"
|
||||
@@ -16,8 +12,17 @@ ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
docker build --no-cache-filter=lint,builder .
|
||||
"$SCRIPT_DIR/fmt-check-markdown"
|
||||
"$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 "$@"
|
||||
|
||||
+6
-8
@@ -1,10 +1,8 @@
|
||||
#!/bin/sh
|
||||
# script/docker: build the Docker image tagged with the project name.
|
||||
# The tag comes from script/projectname.
|
||||
#
|
||||
# --no-cache-filter=lint,builder runs the lint stage and the builder
|
||||
# stage (make test) on every invocation; otherwise an unchanged tree is
|
||||
# served from the layer cache without linting or querying live DNS.
|
||||
# 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)"
|
||||
@@ -14,11 +12,11 @@ main() {
|
||||
cd "$ROOT"
|
||||
# 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 arg takes precedence over what
|
||||
# the build would derive from the .git in its context.
|
||||
# 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-filter=lint,builder \
|
||||
docker build --no-cache \
|
||||
--build-arg VERSION="$version" \
|
||||
-t "$("$SCRIPT_DIR/projectname")" .
|
||||
}
|
||||
|
||||
+7
-14
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
# script/fmt: format all files (writes). Go with gofmt and goimports on
|
||||
# the host, markdown with the prettier pinned by Dockerfile.fmt.
|
||||
# the host, markdown with prettier in the Dockerfile's fmt stage.
|
||||
#
|
||||
# goimports runs with `go run` at a pinned commit, never from PATH, so
|
||||
# every machine formats with the same version and nothing installs it.
|
||||
@@ -8,21 +8,15 @@
|
||||
# The markdown pass is a `docker build --output type=local` rather than a
|
||||
# `docker run -v`, so it needs no bind mount and behaves the same against
|
||||
# a remote daemon; the formatted documents come back out of the build and
|
||||
# are copied over the tree here.
|
||||
#
|
||||
# Unlike script/fmt-check-markdown this does not bust the cache: it is
|
||||
# not a gate, and any edit to a document changes the COPY layer above the
|
||||
# prettier step, so a cached result is a result over this exact tree.
|
||||
# are copied over the tree here. --output writes files and makes no
|
||||
# image, so there is nothing to tag.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
# goimports v0.42.0, 2026-08-07. Must match script/fmt-check-go.
|
||||
# goimports v0.42.0, 2026-08-07. Must match script/fmt-check.
|
||||
GOIMPORTS_REF="golang.org/x/tools/cmd/goimports@009367f5c17a8d4c45a961a3a509277190a9a6f0"
|
||||
|
||||
# Must match the export stage name in Dockerfile.fmt.
|
||||
stage=fmt-out
|
||||
|
||||
die() {
|
||||
echo "script/fmt: $*" >&2
|
||||
exit 1
|
||||
@@ -36,10 +30,9 @@ main() {
|
||||
tmp="$(mktemp -d "${TMPDIR:-/tmp}/dnswatcher-fmt.XXXXXX")"
|
||||
trap 'rm -rf "$tmp"' EXIT INT TERM
|
||||
|
||||
docker build \
|
||||
--target "$stage" \
|
||||
--output "type=local,dest=$tmp/out" \
|
||||
-f Dockerfile.fmt .
|
||||
docker build --no-cache \
|
||||
--target fmt-out \
|
||||
--output "type=local,dest=$tmp/out" .
|
||||
|
||||
# An empty export means prettier was handed nothing, which must not
|
||||
# read as "already formatted".
|
||||
|
||||
+27
-4
@@ -1,14 +1,37 @@
|
||||
#!/bin/sh
|
||||
# script/fmt-check: check formatting (read-only). Same tools and scope
|
||||
# as script/fmt, but fails instead of writing: the Go on the host, the
|
||||
# markdown with prettier in a container.
|
||||
# as script/fmt, but fails instead of writing and names what it would
|
||||
# change: the Go on the host, the markdown with prettier in the
|
||||
# Dockerfile's fmt-check stage.
|
||||
#
|
||||
# --no-cache because a cached check layer is a check 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)"
|
||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
# goimports v0.42.0, 2026-08-07. Must match script/fmt.
|
||||
GOIMPORTS_REF="golang.org/x/tools/cmd/goimports@009367f5c17a8d4c45a961a3a509277190a9a6f0"
|
||||
|
||||
main() {
|
||||
"$SCRIPT_DIR/fmt-check-go"
|
||||
"$SCRIPT_DIR/fmt-check-markdown"
|
||||
cd "$ROOT"
|
||||
files="$(gofmt -s -l .)"
|
||||
if [ -n "$files" ]; then
|
||||
echo "gofmt: files not formatted:" >&2
|
||||
echo "$files" >&2
|
||||
exit 1
|
||||
fi
|
||||
files="$(go run "$GOIMPORTS_REF" -l .)"
|
||||
if [ -n "$files" ]; then
|
||||
echo "goimports: files not formatted:" >&2
|
||||
echo "$files" >&2
|
||||
exit 1
|
||||
fi
|
||||
docker build --no-cache \
|
||||
--target fmt-check \
|
||||
-t "$("$SCRIPT_DIR/projectname")-fmt-check" .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/bin/sh
|
||||
# script/fmt-check-go: fail unless every Go source is formatted the way
|
||||
# script/fmt would leave it, and name the files that are not. Read-only.
|
||||
#
|
||||
# Its own script because the Dockerfile's lint stage runs this half
|
||||
# alone: there is no docker inside a docker build to run the markdown
|
||||
# half in.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
# goimports v0.42.0, 2026-08-07. Must match script/fmt.
|
||||
GOIMPORTS_REF="golang.org/x/tools/cmd/goimports@009367f5c17a8d4c45a961a3a509277190a9a6f0"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
files="$(gofmt -s -l .)"
|
||||
if [ -n "$files" ]; then
|
||||
echo "gofmt: files not formatted:" >&2
|
||||
echo "$files" >&2
|
||||
exit 1
|
||||
fi
|
||||
files="$(go run "$GOIMPORTS_REF" -l .)"
|
||||
if [ -n "$files" ]; then
|
||||
echo "goimports: files not formatted:" >&2
|
||||
echo "$files" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,29 +0,0 @@
|
||||
#!/bin/sh
|
||||
# script/fmt-check-markdown: fail unless every .md is formatted the way
|
||||
# script/fmt would leave it. Read-only.
|
||||
#
|
||||
# prettier is never installed on the host: it runs in a container built
|
||||
# from Dockerfile.fmt, pinned by package.json and yarn.lock.
|
||||
# --no-cache-filter is here for the reason script/lint gives: a cached
|
||||
# build checks nothing.
|
||||
#
|
||||
# Its own script because script/cibuild runs this half alone, after the
|
||||
# Dockerfile's lint stage has checked the Go.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
# Must match the markdown check stage name in Dockerfile.fmt.
|
||||
stage=fmt-check
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
docker build \
|
||||
--progress=plain \
|
||||
--no-cache-filter="$stage" \
|
||||
--target "$stage" \
|
||||
-f Dockerfile.fmt \
|
||||
.
|
||||
}
|
||||
|
||||
main "$@"
|
||||
+12
-17
@@ -1,28 +1,23 @@
|
||||
#!/bin/sh
|
||||
# script/lint: run the linter. golangci-lint is never installed or run
|
||||
# on the host: it runs via docker only, one way, everywhere. This
|
||||
# builds Dockerfile.lint, which COPYs the repo into the digest-pinned
|
||||
# golangci-lint image and lints as a build step, so a successful build
|
||||
# means a clean lint.
|
||||
# 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.
|
||||
#
|
||||
# --no-cache-filter=lint forces the lint stage (source copy + linter
|
||||
# run) to execute on every invocation. Without it an unchanged tree
|
||||
# returns success in well under a second having linted nothing. The
|
||||
# deps stage (base image + go mod download) stays cached, and no global
|
||||
# cache invalidation is performed. --progress=plain keeps the linter's
|
||||
# own output visible.
|
||||
# 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"
|
||||
docker build \
|
||||
--progress=plain \
|
||||
--no-cache-filter=lint \
|
||||
docker build --no-cache \
|
||||
--target lint \
|
||||
-f Dockerfile.lint \
|
||||
.
|
||||
-t "$("$SCRIPT_DIR/projectname")-lint" .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
+10
-26
@@ -1,35 +1,19 @@
|
||||
#!/bin/sh
|
||||
# script/test: run the test suite.
|
||||
#
|
||||
# -count=1 disables Go's test cache, and is load-bearing here. This
|
||||
# suite queries live DNS on every run by policy (TESTING.md); a cached
|
||||
# result is a replay of an earlier run's output with no query made at
|
||||
# all. On an unchanged tree the whole suite would return success in
|
||||
# under a second having resolved nothing, which makes the repeated-run
|
||||
# green that is used as evidence for flakiness fixes worthless. Do not
|
||||
# remove it.
|
||||
#
|
||||
# Conditional verbose rerun per REPO_POLICIES.md: run quiet first so
|
||||
# CI and docker build logs stay readable, and rerun with -v only on
|
||||
# failure. The rerun also carries -count=1 (a cached replay of the
|
||||
# failure would show nothing new), and the exit status is forced to 1
|
||||
# no matter how the rerun ends: the first failure already proved the
|
||||
# suite broken, so a flaky test that passes the second time must not
|
||||
# turn the build green.
|
||||
#
|
||||
# -timeout 90s is a deliberate backstop above the 60s hard cap on
|
||||
# suite duration. Do not lower it.
|
||||
# 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 test -count=1 -race -timeout 90s -cover ./... || {
|
||||
echo "--- Rerunning with -v for details ---" >&2
|
||||
go test -count=1 -race -timeout 90s -v ./... || true
|
||||
exit 1
|
||||
}
|
||||
docker build --no-cache \
|
||||
--target test \
|
||||
-t "$("$SCRIPT_DIR/projectname")-test" .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user