# Lint image, built by script/lint: golangci-lint runs as a build step, so # a successful build is a clean lint. Works with a remote docker daemon, # where bind mounts are impossible. # golangci/golangci-lint:v2.12.2 (Debian-based), 2026-08-30 FROM golangci/golangci-lint:v2.12.2@sha256:5cceeef04e53efe1470638d4b4b4f5ceefd574955ab3941b2d9a68a8c9ad5240 AS deps WORKDIR /src COPY go.mod go.sum ./ RUN go mod download # This stage must stay the last one and the one that runs golangci-lint, # and its name must match $stage in script/lint. FROM deps AS lint COPY . . # Inventory of the sources that actually arrived here. script/lint reads # these lines out of the build log and compares them against the git # index, so a .dockerignore entry or a narrowed COPY that hides a # package fails the run instead of yielding a clean report over a tree # the linter never saw. Keep it immediately after `COPY . .`, and keep # `echo context-manifest-begin` as its first command: # script/assert-context-complete matches the step by that prefix. RUN echo context-manifest-begin; \ { find . -type f -name '*.go'; \ for f in go.mod go.sum .golangci.yml .golangci.yaml; do \ if [ -f "$f" ]; then echo "./$f"; fi; \ done; } \ | sed 's|^\./||' | LC_ALL=C sort | sed 's|^|context-file: |'; \ echo context-manifest-end RUN golangci-lint config verify --config .golangci.yml RUN golangci-lint run --config .golangci.yml ./...