diff --git a/docs/superpowers/specs/2026-04-28-issue-18-ci-vet-staticcheck-design.md b/docs/superpowers/specs/2026-04-28-issue-18-ci-vet-staticcheck-design.md new file mode 100644 index 0000000..b0839e5 --- /dev/null +++ b/docs/superpowers/specs/2026-04-28-issue-18-ci-vet-staticcheck-design.md @@ -0,0 +1,76 @@ +# Design: Issue #18 — Add `go vet` and `staticcheck` to CI + +## Context +Issue #18 requires expanding PR CI validation for this Go repository beyond existing `gofmt` and `go test` checks. + +Current state: +- CI is defined in `.gitea/workflows/ci.yml`. +- Existing jobs: `fmt` (`gofmt -l .`) and `test` (`go test ./...`). +- No `go vet` or `staticcheck` step exists. + +## Goal +Add practical baseline static analysis to pull request CI by: +- Running `go vet ./...`. +- Running `staticcheck ./...`. +- Pinning `staticcheck` version in CI for deterministic behavior. + +## Non-goals +- Adding `golangci-lint`. +- Refactoring application code unrelated to CI wiring. +- Changing workflow triggers. + +## Approved approach +Use separate CI jobs for `vet` and `staticcheck` while keeping existing `fmt` and `test` jobs unchanged. + +### Why this approach +- Keeps changes surgical and easy to review. +- Makes failures explicit per check (better debugging signal than a combined lint step). +- Preserves current CI behavior while extending validation coverage. + +## Implementation design +Modify `.gitea/workflows/ci.yml` only. + +### Job: `vet` +- `runs-on: linux` +- Steps: + 1. `actions/checkout@v4` + 2. `actions/setup-go@v5` with `go-version-file: go.mod` + 3. `run: go vet ./...` + +### Job: `staticcheck` +- `runs-on: linux` +- Steps: + 1. `actions/checkout@v4` + 2. `actions/setup-go@v5` with `go-version-file: go.mod` + 3. Install pinned staticcheck version: + - `go install honnef.co/go/tools/cmd/staticcheck@2025.1.1` + 4. Run staticcheck: + - `$(go env GOPATH)/bin/staticcheck ./...` + +## Failure behavior +- CI must fail if `go vet ./...` exits non-zero. +- CI must fail if `staticcheck ./...` exits non-zero. +- Existing `fmt` and `test` failure behavior remains unchanged. + +## Verification plan +Local verification before PR creation: +- `gofmt -l .` +- `go test ./...` +- `go vet ./...` +- `staticcheck ./...` (if tool is available locally) + +CI verification through PR run: +- Confirm `fmt`, `test`, `vet`, and `staticcheck` jobs execute on pull requests. +- Confirm non-zero from `vet`/`staticcheck` marks workflow failed. + +## Risks and mitigations +- Risk: pinned staticcheck version not present in runner cache. + - Mitigation: install in-job via `go install` each run. +- Risk: staticcheck findings on current code block CI. + - Mitigation: if encountered, address only findings required to satisfy issue scope. + +## Acceptance mapping +- CI fail on vet errors → `vet` job runs `go vet ./...`. +- CI fail on staticcheck errors → `staticcheck` job runs pinned staticcheck binary. +- Existing checks preserved → `fmt` and `test` jobs remain in workflow. +- No `golangci-lint` → not introduced in workflow.