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

cd backend/go
golangci-lint run ./...
If golangci-lint is not installed:
brew install golangci-lint

Enabled Linters

The pragmatic linter set is configured in backend/go/.golangci.yml:
LinterPurpose
govetCatches suspicious constructs (misaligned printf args, unreachable code)
staticcheckGold-standard Go static analyzer — correctness, performance, and simplifications (absorbs gosimple in v2)
unusedDetects dead code: unexported functions, types, and variables never used
gofumptEnforces the project formatter (consistent with VS Code on-save behaviour) — runs as a formatter in v2
errcheckFlags unchecked error returns in non-test code
gocriticCommon 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

A lint-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.
lint-go:
  name: Lint Go Backend
  needs: detect-changes
  if: needs.detect-changes.outputs.go == 'true'
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: golangci/golangci-lint-action@v6
      with:
        version: v1.64
        working-directory: backend/go

Suppressing False Positives

Use //nolint:<linter> with a comment explaining why:
result, _ := someFunc() //nolint:errcheck // error is always nil when input is validated upstream
Avoid blanket //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 a needs dependency:
deploy-go-backend:
  needs: [detect-changes, lint-go]