All checks were successful
check / check (push) Successful in 1m9s
The `(Debian-based)` parenthetical broke the required `# image:vX.Y.Z, YYYY-MM-DD` form and asserted a base change that never happened (v2.12.1 was Debian too); the tag before the digest left three FROM lines in one file using two conventions. Digest unchanged, in both Dockerfile and Dockerfile.lint. The golang and alpine pin comments already matched the required form. script/verify-lint-image-pin parses these two FROM lines to keep them identical and still matches the tagless form; its advice line drops the now-meaningless "tag and digest". With no tag in either reference a tag-only disagreement cannot arise; a tag reintroduced on one side is caught as a plain mismatch.
85 lines
3.0 KiB
Bash
Executable File
85 lines
3.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# script/verify-lint-image-pin: fail unless the golangci-lint image
|
|
# referenced by Dockerfile.lint and the one referenced by the main
|
|
# Dockerfile's lint stage are the same image at the same digest. Our own
|
|
# extension to scripts-to-rule-them-all, not one of its entrypoints.
|
|
#
|
|
# The linter version is pinned in two independent files. That is the
|
|
# shape #42 turned into a build failure rather than tolerate: nothing
|
|
# else keeps the two in sync, and a bump applied to one file alone would
|
|
# leave `make lint` and the fail-fast lint stage of `make docker`
|
|
# linting the same tree against different rulesets, both green. This is
|
|
# the single guard that stops it, run as a gate in both files.
|
|
#
|
|
# It deliberately restates neither pin. A hardcoded expected digest here
|
|
# would be a third copy — one more thing to bump, and the same drift one
|
|
# file further out. It compares the two files to each other and knows
|
|
# nothing about which version is correct.
|
|
#
|
|
# A reference that cannot be read is a hard failure, not a skip: a
|
|
# comparison of two empty strings succeeds, which would turn this guard
|
|
# into exactly the unearned green it exists to prevent.
|
|
set -eu
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
|
|
|
LINT_DOCKERFILE="Dockerfile.lint"
|
|
MAIN_DOCKERFILE="Dockerfile"
|
|
|
|
# Echo the single golangci-lint image reference in the named Dockerfile.
|
|
# Scans every argument of every FROM instruction rather than assuming a
|
|
# field position, so `FROM --platform=... img AS stage` reads correctly.
|
|
# Exits non-zero, with a diagnosis, unless there is exactly one.
|
|
lint_image_ref() {
|
|
file="$1"
|
|
|
|
if [ ! -f "$file" ]; then
|
|
echo "verify-lint-image-pin: $file: not found" >&2
|
|
return 1
|
|
fi
|
|
|
|
refs="$(
|
|
awk '
|
|
toupper($1) == "FROM" {
|
|
for (i = 2; i <= NF; i++) {
|
|
if ($i ~ /^golangci\/golangci-lint[:@]/) {
|
|
print $i
|
|
}
|
|
}
|
|
}
|
|
' "$file"
|
|
)"
|
|
|
|
count="$(printf '%s' "$refs" | grep -c . || true)"
|
|
if [ "$count" -ne 1 ]; then
|
|
echo "verify-lint-image-pin: $file: expected exactly one" \
|
|
"golangci/golangci-lint FROM reference, found $count" >&2
|
|
return 1
|
|
fi
|
|
|
|
printf '%s\n' "$refs"
|
|
}
|
|
|
|
main() {
|
|
cd "$ROOT"
|
|
|
|
lint_ref="$(lint_image_ref "$LINT_DOCKERFILE")"
|
|
main_ref="$(lint_image_ref "$MAIN_DOCKERFILE")"
|
|
|
|
if [ "$lint_ref" != "$main_ref" ]; then
|
|
echo "verify-lint-image-pin: the linter image is pinned twice and" \
|
|
"the two pins disagree:" >&2
|
|
echo "verify-lint-image-pin: $LINT_DOCKERFILE: $lint_ref" >&2
|
|
echo "verify-lint-image-pin: $MAIN_DOCKERFILE: $main_ref" >&2
|
|
echo "verify-lint-image-pin: bump both FROM lines together so" \
|
|
"script/lint and the Dockerfile lint stage keep running the" \
|
|
"same linter" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "verify-lint-image-pin: $LINT_DOCKERFILE and $MAIN_DOCKERFILE" \
|
|
"agree on $lint_ref"
|
|
}
|
|
|
|
main "$@"
|