# Lint phase. The tools are invoked directly rather than through `make # lint` or `script/lint`, which are themselves a docker build and would # recurse into a daemon that does not exist in a build step. # # golangci-lint does not check formatting under the canonical config, so # gofmt runs here too. # # golangci/golangci-lint:v2.12.2, 2026-11-02 FROM golangci/golangci-lint@sha256:5cceeef04e53efe1470638d4b4b4f5ceefd574955ab3941b2d9a68a8c9ad5240 AS lint WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . RUN test -z "$(gofmt -l .)" || { echo "gofmt needed on:"; gofmt -l .; exit 1; } RUN golangci-lint run --config .golangci.yml ./... # Test phase, invoked directly for the same reason. The Debian image is # used because the race detector needs glibc. # # golang:1.26.2-trixie, 2026-11-02 FROM golang@sha256:4a7137ea573f79c86ae451ff05817ed762ef5597fcf732259e97abeb3108d873 AS test WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go test -count=1 -timeout 90s -race -cover ./... || \ { echo "--- Rerunning with -v for details ---"; \ go test -count=1 -timeout 90s -race -v ./...; exit 1; } # Development environment, and the last stage: a plain `docker build .` # names no target and so builds this one. Nothing is wanted from the two # phases above; the copies are what make BuildKit build them first, so # this image cannot be produced unless lint and test passed. A stage # appended after this one would drop all three out of a plain build. # # golang:1.26.2-trixie, 2026-11-02 FROM golang@sha256:4a7137ea573f79c86ae451ff05817ed762ef5597fcf732259e97abeb3108d873 COPY --from=lint /src/go.sum /dev/null COPY --from=test /src/go.sum /dev/null WORKDIR /src # script/bootstrap installs the tools for formatting Markdown. Debian is # used here because the node it installs needs glibc. COPY script/ script/ COPY package.json yarn.lock go.mod go.sum ./ RUN script/bootstrap RUN go mod download COPY . . RUN script/build # The version is computed on the host and passed in, because # .dockerignore excludes .git. ARG VERSION=dev LABEL org.opencontainers.image.version="${VERSION}"