Go Toolchain Best Practices
Reproducible builds, CI integration, and toolchain pinning.
Search across all documentation pages
Reproducible builds, CI integration, and toolchain pinning.
These rules keep go command workflows consistent from laptops through CI to release artifacts.
GOPRIVATE, GOPROXY, and GOTOOLCHAIN values in CI and developer docs.go mod tidy, go test ./..., and linters on every dependency bump before merge.go.mod and document GOTOOLCHAIN policy. Teammates and CI should resolve the same compiler; use auto only when you accept automatic downloads.go mod tidy after any import or dependency change. Keeps require lines minimal and go.sum accurate.go.sum whenever go.mod changes. Checksums are part of the reproducible build contract.GOPRIVATE for every internal module prefix. Prevents leaking private paths to the public proxy and sum DB.proxy.golang.org. Speeds CI and survives upstream outages.go build artifacts, not go run, in production. run recompiles every invocation and hides the binary path.-trimpath and -ldflags="-s -w" for release binaries. Shrinks size and strips host paths from stacks.-o bin/<name>. Avoids collisions when building multiple commands in one pipeline step.CGO_ENABLED=0 unless you truly need cgo. Pure Go matrices are simpler on one Linux builder.go version and go env in release logs. Speeds debugging when CI and laptop builds diverge.go test ./... (or ./... with -race in CI) on every PR. The default gate before merge.go vet ./... before optional linters. Zero-config baseline from the stdlib.golangci-lint (or staticcheck) with a committed config. Team-wide rules beyond vet.go test -count=1 while debugging flakes; fix root cause before merge. Do not rely on disabled test cache in production CI forever.go fix -diff after Go upgrades, then apply with review. Modernizers catch idioms training data may miss.GOMODCACHE and GOCACHE in CI. go mod download warm steps pay off on every job.-mod=readonly in CI when not vendoring. Fails builds that mutate go.mod silently.vendor/. Drift breaks -mod=vendor pipelines.go clean -modcache in routine CI. Only clear caches when corruption is proven.go mod download. Catch token expiry before compile steps.//go:generate directives. go run tool@version beats undocumented local binaries.go generate drift (git diff --exit-code). Generated output stays in sync with sources.-tags for production builds. Default go test may skip tagged files CI never exercises.go mod download, go test ./..., go vet ./..., and optionally golangci-lint run.
Add -race when runners have enough CPU and RAM.
Vendor when policy requires in-repo third-party source or builds must not reach module proxies.
Otherwise prefer proxy plus cached GOMODCACHE.
Set go 1.26.x in go.mod and GOTOOLCHAIN=go1.26.x in CI.
Let patch auto-download only if the team agrees.
During upgrade branches, locally with go fix -diff, then commit reviewed changes.
Not on every unrelated PR.
Athens caches downloads inside your network.
GOPRIVATE still marks which paths must never hit the public index.
Yes.
Keep slow integration suites behind integration tags and run them nightly or on main.
GOPRIVATE, GOPROXY, GONOSUMDB, GOTOOLCHAIN, and any auth setup for Git hosts.
Not secrets themselves - reference the secret store.
Cache GOCACHE, split -race to a dedicated job, and use -shuffle=on only when hunting order bugs.
Avoid -a unless debugging cache issues.
Yes.
Enforce with gofmt -l or golangci-lint gofmt/goimports linters in CI.
Binary per target, go version string embedded via -ldflags, and SBOM input from go list -m -json all.
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).
Reviewed by Chris St. John·Last updated Jul 19, 2026