Linting with golangci-lint
The Go backend uses golangci-lint for static analysis. It runs locally for fast developer feedback and in CI as a non-blocking quality signal alongside the deploy job.Running Locally
Enabled Linters
The pragmatic linter set is configured inbackend/go/.golangci.yml:
| Linter | Purpose |
|---|---|
govet | Catches suspicious constructs (misaligned printf args, unreachable code) |
staticcheck | Gold-standard Go static analyzer — correctness, performance, and simplifications (absorbs gosimple in v2) |
unused | Detects dead code: unexported functions, types, and variables never used |
gofumpt | Enforces the project formatter (consistent with VS Code on-save behaviour) — runs as a formatter in v2 |
errcheck | Flags unchecked error returns in non-test code |
gocritic | Common code smells with a low false-positive rate |
errcheck is excluded on *_test.go files — test helper calls frequently return errors that are already visible through assertion failures.
CI Integration
Alint-go job runs in .github/workflows/backend-flyio-deploy.yml whenever files under backend/go/** change. It uses the official golangci/golangci-lint-action@v6 action pinned to v1.64.
The job runs in parallel with deploy-go-backend — a lint failure does not block a deploy. This is intentional while the baseline is being cleaned up.
Suppressing False Positives
Use//nolint:<linter> with a comment explaining why:
//nolint without a linter name.
Migration Path to Blocking CI
Once the baseline lint warnings are resolved, make lint a required check before deploy by adding aneeds dependency:
Related
- backend/go/.golangci.yml — full linter configuration
- .github/workflows/backend-flyio-deploy.yml — CI workflow
- Quick Start — getting the Go backend running locally