Dockerfile does not implement the mandated fail-fast lint stage, and does not pass VERSION as a build ARG #109

Open
opened 2026-08-09 03:40:38 +02:00 by clawbot · 0 comments
Collaborator

REPO_POLICIES.md devotes a long, explicit section to the required multistage Go Dockerfile pattern, including a canonical template. This repo's Dockerfile does not follow it.

Current state (audited against origin/main, commit 9347a28)

The whole Dockerfile is two stages — builder and runtime:

# golang 1.25-alpine, 2026-02-28
FROM golang@sha256:f6751d... AS builder
RUN apk add --no-cache git make gcc musl-dev binutils-gold
# golangci-lint v2.12.2, 2026-08-07
RUN go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@c0d3ddc9cf3faa61a4e378e879ece580256d76e5
# goimports v0.42.0
RUN go install golang.org/x/tools/cmd/goimports@009367f5c17a8d4c45a961a3a509277190a9a6f0
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN make check
RUN make build

Divergences from the mandated pattern:

  1. There is no lint stage. The policy requires an independent stage FROM golangci/golangci-lint@sha256:... that runs make fmt-check and make lint before the build begins. That image is never referenced here.
  2. There is no COPY --from=lint /src/go.sum /dev/null stage dependency. The policy is explicit about why this line exists: "BuildKit runs stages in parallel by default; without this line, the build stage would not wait for lint to finish and a lint failure might not fail the overall build."
  3. Lint runs late, and slowly. Linting happens inside make check, after go mod download and full compilation setup. The entire stated purpose of the pattern is that "lint failures surface in seconds rather than minutes."
  4. No ARG VERSION. The canonical template declares ARG VERSION=dev and injects it. Here, make build shells out to git describe --tags --always --dirty (Makefile:4-5) — but .dockerignore excludes .git/, so there is no git metadata in the build context at all and the version string silently collapses to the || echo "dev" fallback. Every image ever built by this Dockerfile reports version dev. That is a release-correctness bug, not a style nit, and it will not fix itself when you tag 1.0.0.
  5. Missing date on a pin comment. # goimports v0.42.0 has a version but no date; the policy requires "a comment above the reference with the version and date (YYYY-MM-DD)". Every other pin in the repo is correctly commented.

What is already correct — do not regress it

Every external reference in the repo is hash-pinned, which is the single most important rule in REPO_POLICIES.md. Verified: golang@sha256:f6751d..., alpine@sha256:c3f8e73..., golangci-lint @c0d3ddc9cf3faa61a4e378e879ece580256d76e5, goimports @009367f5c17a8d4c45a961a3a509277190a9a6f0, actions/checkout@11bd71901bbe... in .gitea/workflows/check.yml, and Go module hashes in go.sum. script/bootstrap uses package managers plus pinned go install — no curl | sh anywhere.

Definition of done

  1. A separate lint stage based on the golangci/golangci-lint image, running make fmt-check then make lint.
  2. The build stage declares the dependency via COPY --from=lint /src/go.sum /dev/null.
  3. ARG VERSION=dev is declared and threaded into the binary's version string so built images report a real version. Confirm by running the built image and checking the version it reports — do not assume it works from reading the Dockerfile.
  4. The goimports pin comment gains its date.
  5. script/cibuild (plain docker build .) still succeeds end to end, and the build stays under the policy's 5-minute ceiling.
  6. TODO.md updated in the same commit.

The finishing commit's title must end with (closes #N) referencing this issue.

Hard constraints — read before starting

  • The golangci/golangci-lint image you add must be pinned by sha256 digest and must be exactly v2.12.2, matching the existing go install pin c0d3ddc9cf3faa61a4e378e879ece580256d76e5. A different linter version against this repo's v2-schema .golangci.yml will fail on config schema mismatch. Add the required # golangci/golangci-lint v2.12.2, YYYY-MM-DD comment above it.
  • If you cannot resolve that digest — no registry access, ambiguous tag, whatever the reason — stop and report back rather than guessing, and never fall back to a mutable :v2.12.2 tag. Hash-pinning has zero exceptions in this repo. An honest "blocked, need the digest" is the correct outcome; a tag reference is not.
  • Do not modify .golangci.yml. It is org-standardised and must never be touched by an agent. Its sha256 must remain 021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb.
  • Do not change the golangci-lint or goimports version pins. Only add the missing date comment.

Known interaction, do not "fix" it here

make check inside the build runs the live-DNS resolver test suite, so docker build requires outbound DNS from the build environment. DNS is never mocked in this repository, so that coupling is intentional. Test gating/flakiness is parked under #93 pending a decision from @sneakdo not add -short, skips, build tags, or mocks in this PR.

`REPO_POLICIES.md` devotes a long, explicit section to the required multistage Go Dockerfile pattern, including a canonical template. This repo's Dockerfile does not follow it. ## Current state (audited against `origin/main`, commit `9347a28`) The whole Dockerfile is two stages — `builder` and runtime: ```dockerfile # golang 1.25-alpine, 2026-02-28 FROM golang@sha256:f6751d... AS builder RUN apk add --no-cache git make gcc musl-dev binutils-gold # golangci-lint v2.12.2, 2026-08-07 RUN go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@c0d3ddc9cf3faa61a4e378e879ece580256d76e5 # goimports v0.42.0 RUN go install golang.org/x/tools/cmd/goimports@009367f5c17a8d4c45a961a3a509277190a9a6f0 WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . RUN make check RUN make build ``` Divergences from the mandated pattern: 1. **There is no `lint` stage.** The policy requires an independent stage `FROM golangci/golangci-lint@sha256:...` that runs `make fmt-check` and `make lint` before the build begins. That image is never referenced here. 2. **There is no `COPY --from=lint /src/go.sum /dev/null` stage dependency.** The policy is explicit about why this line exists: "BuildKit runs stages in parallel by default; without this line, the build stage would not wait for lint to finish and a lint failure might not fail the overall build." 3. **Lint runs late, and slowly.** Linting happens inside `make check`, after `go mod download` and full compilation setup. The entire stated purpose of the pattern is that "lint failures surface in seconds rather than minutes." 4. **No `ARG VERSION`.** The canonical template declares `ARG VERSION=dev` and injects it. Here, `make build` shells out to `git describe --tags --always --dirty` (`Makefile:4-5`) — but `.dockerignore` excludes `.git/`, so **there is no git metadata in the build context at all** and the version string silently collapses to the `|| echo "dev"` fallback. Every image ever built by this Dockerfile reports version `dev`. That is a release-correctness bug, not a style nit, and it will not fix itself when you tag 1.0.0. 5. **Missing date on a pin comment.** `# goimports v0.42.0` has a version but no date; the policy requires "a comment above the reference with the version and date (YYYY-MM-DD)". Every other pin in the repo is correctly commented. ## What is already correct — do not regress it Every external reference in the repo **is** hash-pinned, which is the single most important rule in `REPO_POLICIES.md`. Verified: `golang@sha256:f6751d...`, `alpine@sha256:c3f8e73...`, golangci-lint `@c0d3ddc9cf3faa61a4e378e879ece580256d76e5`, goimports `@009367f5c17a8d4c45a961a3a509277190a9a6f0`, `actions/checkout@11bd71901bbe...` in `.gitea/workflows/check.yml`, and Go module hashes in `go.sum`. `script/bootstrap` uses package managers plus pinned `go install` — no `curl | sh` anywhere. ## Definition of done 1. A separate `lint` stage based on the `golangci/golangci-lint` image, running `make fmt-check` then `make lint`. 2. The build stage declares the dependency via `COPY --from=lint /src/go.sum /dev/null`. 3. `ARG VERSION=dev` is declared and threaded into the binary's version string so built images report a real version. Confirm by running the built image and checking the version it reports — do not assume it works from reading the Dockerfile. 4. The `goimports` pin comment gains its date. 5. `script/cibuild` (plain `docker build .`) still succeeds end to end, and the build stays under the policy's 5-minute ceiling. 6. `TODO.md` updated in the same commit. The finishing commit's title must end with ` (closes #N)` referencing this issue. ## Hard constraints — read before starting - **The `golangci/golangci-lint` image you add must be pinned by `sha256` digest and must be exactly v2.12.2**, matching the existing `go install` pin `c0d3ddc9cf3faa61a4e378e879ece580256d76e5`. A different linter version against this repo's v2-schema `.golangci.yml` will fail on config schema mismatch. Add the required `# golangci/golangci-lint v2.12.2, YYYY-MM-DD` comment above it. - **If you cannot resolve that digest** — no registry access, ambiguous tag, whatever the reason — **stop and report back rather than guessing, and never fall back to a mutable `:v2.12.2` tag.** Hash-pinning has zero exceptions in this repo. An honest "blocked, need the digest" is the correct outcome; a tag reference is not. - **Do not modify `.golangci.yml`.** It is org-standardised and must never be touched by an agent. Its sha256 must remain `021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb`. - **Do not change the golangci-lint or goimports version pins.** Only add the missing date comment. ## Known interaction, do not "fix" it here `make check` inside the build runs the live-DNS resolver test suite, so `docker build` requires outbound DNS from the build environment. DNS is never mocked in this repository, so that coupling is intentional. Test gating/flakiness is parked under #93 pending a decision from @sneak — **do not** add `-short`, skips, build tags, or mocks in this PR.
clawbot added this to the 1.0 milestone 2026-08-09 03:40:38 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/dnswatcher#109