4e433158cd
---ci--- project: atelier phase: 3 milestone: v0.4 status: complete phase_role: execution phase_tag: v0.3.3 requirements: covered: [ATELIER-102, ATELIER-103, ATELIER-104, ATELIER-105] partial: [] ---/ci---
4.8 KiB
4.8 KiB
Go Tooling — Derived Application
Applies Atelier's domain principles to Go tooling specifically. Derives from
domains/docs; introduces no new P-rules (D-063). Seelanguages/go.mdfor the language first-principles stub.
go vet and golangci-lint (DevOps P2 Automation, C2 Clarity)
go vetis the stdlib baseline: it catchesprintfformat mismatches, lock-copy-by-value, and unreachable code. Run on every build.golangci-lintaggregates vet + dozens of linters: enableerrcheck(no_ = err),govet,staticcheck,ineffassign,unused,gofmt,goimports. Each enabled linter has a one-line# reason:in.golangci.yml.errcheckenforceserrors/P2(fail loudly): a discarded error is a silent failure.errcheckfails the build on_ = doX().goimportsovergofmt:goimportsadds missing imports and removes unused ones, in addition to formatting. The format is not debated in review (Clarity C2).
# .golangci.yml
linters:
enable:
- errcheck # reason: Errors P2 — no swallowed errors
- govet
- staticcheck
- ineffassign
- unused
- gofmt
- goimports
linters-settings:
errcheck:
check-blank: true # fail on _ = fn()
go test -race (Concurrency P6 No Silent Races)
go test -racein CI, always: the race detector instruments memory accesses and fails on data races. It is the primary enforcement ofconcurrency/P6(no silent races).-raceadds overhead; run it in a separate CI job: the race build is ~2x slower; keep the fast unit-test job and add a race job.-racerequires tests that actually exercise the concurrent path: a test that callsGet/Setserially finds no race. Write tests that spawn goroutines hitting the same map.- Applies
concurrency/P6: a race detected is a bug fixed; a race undetected is a heisenbug in production. The detector is the safety net.
# CI race job
go test -race -count=1 ./...
Module Discipline (DevOps P1 Reproducibility)
go mod tidyon every change that touches imports: removes unused deps and adds missing ones. Ago.modwith stale entries breaks reproducibility.go.sumcommitted and verified:go mod verifychecks the checksums of the module cache againstgo.sum. A driftedgo.sumis a supply-chain signal.- Pinned major versions in
go.mod:require github.com/x/y v1.2.3pins the minor; av1.2.4patch may auto-update. For applications, consider ago.modproxy that pins to exact commits. go mod vendorfor hermetic CI: vendoringvendor/into the repo means CI builds without network. The trade-off is repo size; the win is reproducibility (DevOps P1).
# CI build gate
go mod tidy
go mod verify
go build ./...
go test -race ./...
Reproducible Builds (DevOps P1 Reproducibility, C3 Simplicity)
- One Go toolchain version, pinned:
goenvorasdfpins the Go version per repo; a.go-versionfile declares it. A CI job that uses "latest" Go drifts. CGO_ENABLED=0for static binaries: a static binary runs in a scratch container with no libc dependency. Set in CI for all release builds.-trimpathand-ldflags='-s -w'for reproducible output: strips the build path from the binary and removes debug info. Two builds of the same commit produce byte-identical binaries.
# Reproducible release build
CGO_ENABLED=0 go build -trimpath -ldflags='-s -w' -o app ./cmd/app
Documentation in the Pipeline (Documentation P1 Documentation is Code, DevOps P9 Documentation in the Pipeline)
go docfrom comments: package comments and exported-symbol comments are the API docs;go docandpkg.go.devrender them. Missing comments on exported symbols failrevive/golint(Documentation P1).// Examplefunctions are run bygo test: anExampleUserfunction with// Output:is a tested artifact; a stale output fails the build.README.mdanddocs/are built bymkdocsor similar: the pipeline validates links and renders; a broken link fails CI (Documentation P1).
// GetUser fetches a user by id.
//
// Example:
//
// u, err := GetUser(id)
// if err != nil { ... }
func GetUser(id UserId) (*User, error) { /* ... */ }
func ExampleGetUser() {
u, err := GetUser("abc")
fmt.Println(u, err)
// Output: <nil> not found
}
Cross-References
domains/devops/ci-cd.md— the pipeline gates that host vet/lint/test.domains/devops/first-principles.md— DevOps P1 Reproducibility, P2 Automation.domains/concurrency/first-principles.md— Concurrency P6 No Silent Races (-race).domains/documentation/first-principles.md— Documentation P1 Documentation is Code.languages/go-types.md— the type rules staticcheck enforces reference this doc.languages/go-testing.md— thego testflags (-race,-count) detailed here.