From 93681569ab893c5f1751981b071d392b13d8cf98 Mon Sep 17 00:00:00 2001 From: Holger Selover-Stephan Date: Fri, 31 Jul 2026 13:34:24 +0200 Subject: [PATCH] ci: gate gofmt in golangci-lint, add `make fmt` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nothing enforced formatting before this: .golangci.yml had no `formatters` section and no workflow ran gofmt, so six files drifted unnoticed until #329. This closes the loop so it can't recur silently. Enabling the gofmt formatter means `golangci-lint run` reports a formatting diff as an issue and exits non-zero — which gates both `make lint` locally and the CI lint job (golangci-lint-action runs `run` by default), so no workflow change is needed. Generated code is excluded via `exclusions.generated: strict`: genqlient's output carries the standard "Code generated by … DO NOT EDIT." header, and a formatting complaint there isn't hand-fixable since `make generate` rewrites the file. Verified — drift injected into internal/api/gen/generated.go is seen by `gofmt -l` but correctly ignored by the linter. `make fmt` (golangci-lint fmt) applies the fixes, so a failing gate has an obvious remedy. Verified end to end: clean tree passes; injected drift fails `make lint`; `make fmt` repairs it byte-for-byte; `make lint` passes again. Co-Authored-By: Claude Opus 5 --- .golangci.yml | 13 +++++++++++++ CLAUDE.md | 3 ++- Makefile | 6 +++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index b2dcc35..148b747 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -17,6 +17,19 @@ linters: # deferred response-body closes - (io.ReadCloser).Close +# Formatting is a gate, not a convention. Nothing enforced gofmt before this, +# so six files had drifted unnoticed (#329) — `golangci-lint run` now reports a +# diff as an issue, which fails both `make lint` and the CI lint job. +# Run `make fmt` (golangci-lint fmt) to apply the fixes. +formatters: + enable: + - gofmt + exclusions: + # internal/api/gen/generated.go is written by genqlient; a formatting + # complaint there is not actionable by hand, since `make generate` + # rewrites it. + generated: strict + issues: max-issues-per-linter: 0 max-same-issues: 0 diff --git a/CLAUDE.md b/CLAUDE.md index 44bedca..bb51496 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -32,7 +32,8 @@ don't batch to end-of-session. ```sh make build # version-stamped binary at bin/hadron (ldflags from `git describe`) make test # go test ./... -make lint # golangci-lint run +make lint # golangci-lint run (gofmt is gated here — a diff fails the build) +make fmt # golangci-lint fmt — apply the formatting `make lint` gates on make generate # regenerate genqlient code from the committed schema snapshot make schema # re-export the schema from ../hadron-server, then generate make schema-check # fail if the committed snapshot is stale vs ../hadron-server (drift detector) diff --git a/Makefile b/Makefile index d08832b..1eae3f0 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ HADRON_SERVER_DIR ?= ../hadron-server # (typeDefs.ts is a self-contained SDL string, so those are the only deps). SDL_EXPORT ?= pnpm -s tsx scripts/export-graphql-sdl.mjs -.PHONY: build test lint generate schema schema-check tools-manifest tools-manifest-check clean +.PHONY: build test lint fmt generate schema schema-check tools-manifest tools-manifest-check clean build: go build -ldflags "$(LDFLAGS)" -o $(BIN) ./cmd/hadron @@ -26,6 +26,10 @@ test: lint: golangci-lint run +# Apply the formatting `make lint` gates on (gofmt, per .golangci.yml). +fmt: + golangci-lint fmt + # Regenerate genqlient code from the committed schema snapshot. generate: go tool genqlient