check / check (push) Successful in 2m45s
golangci-lint now runs only inside a container, never on the host. script/lint builds a hash-pinned root Dockerfile.lint; the nix-shell and host golangci-lint paths are gone. A per-run CACHEBUST build-arg is folded into the lint step's cache key, so the linter re-executes on every run and an unchanged tree cannot return a cached success having linted nothing; script/lint fails a build that did not run the linter. Dockerfile's lint stage runs golangci-lint directly, since make lint now builds a container and there is no Docker inside a build. It is the same image and config. golangci-lint config verify is left out: it fetches its schema over an unpinned live HTTPS call, which REPO_POLICIES.md forbids. Model: opus-4-8
56 lines
2.0 KiB
Bash
Executable File
56 lines
2.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# script/lint: run golangci-lint over the whole tree.
|
|
#
|
|
# The linter is never installed on the host: it runs only inside the
|
|
# Dockerfile.lint build, one way, everywhere. A clean build is a clean
|
|
# lint. See Dockerfile.lint for why the lint step cannot be cached.
|
|
set -eu
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
|
|
|
main() {
|
|
cd "$ROOT"
|
|
|
|
# A value no other run repeats. Dockerfile.lint folds it into the
|
|
# lint step's cache key, so the linter re-executes every run instead
|
|
# of an unchanged tree returning a cached success having linted
|
|
# nothing.
|
|
cachebust="$(date +%s)-$$"
|
|
|
|
tmp="$(mktemp -d "${TMPDIR:-/tmp}/pixa-lint.XXXXXX")"
|
|
trap 'rm -rf "$tmp"' EXIT INT TERM
|
|
|
|
# --progress=plain so the lint step's own output reaches the log we
|
|
# check below; --output=type=cacheonly because we want the linter's
|
|
# verdict, not an image left in the local store. The build status
|
|
# travels through a file: a pipeline's exit status is tee's, not the
|
|
# build's.
|
|
(
|
|
set +e
|
|
docker build \
|
|
--progress=plain \
|
|
--build-arg CACHEBUST="$cachebust" \
|
|
--output=type=cacheonly \
|
|
-f Dockerfile.lint . 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}"
|
|
|
|
# The linter's start line must appear as build output, not only in
|
|
# the build's echo of the RUN instruction. A step served from cache
|
|
# prints the instruction and none of its output; a step that runs
|
|
# prints a "#<n> <elapsed> ..." output line. Requiring that output
|
|
# line means a future edit dropping the CACHEBUST reference from
|
|
# Dockerfile.lint fails here rather than passing having linted
|
|
# nothing.
|
|
if ! grep -Eq '^#[0-9]+ +[0-9]+\.[0-9]+ +pixa-lint: running golangci-lint' \
|
|
"$tmp/build.log"; then
|
|
echo "script/lint: golangci-lint did not execute (cached step?)." >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
main "$@"
|