PR #5 of the 11-PR completion sequence. Rewrites .github/workflows/ci.yml so the pipeline actually exercises what the review said was missing, fixes the Go-version drift (go.mod declares go 1.23.0, CI was pinned to 1.22), and wires in three new gates (staticcheck, govulncheck, gitleaks).
Workflow changes
Go: 1.22 → 1.23.4 (matches backend/go.mod).
Jobs split and named: test-backend, scan-backend, test-frontend, gitleaks.
test-backend runs go vet + go build + go test.
scan-backend installs [email protected]... now pinned to latest-that-works-with-Go-1.23 + govulncheck@latest.
test-frontend runs npm ci + next lint + tsc --noEmit -p tsconfig.check.json + next build.
gitleaks/gitleaks-action@v2 job uses fetch-depth: 0 to scan the full history.
Triggers now include master (the actual default branch). Previous workflow targeted main/develop only, so it literally never ran on the repo's real PRs.
Action versions bumped (checkout@v4, setup-go@v5, setup-node@v4) and caching enabled for both Node and Go modules.
Concurrency group cancels stale runs on the same ref.
.gitleaks.toml (new)
Extends the default ruleset and adds a repo-specific rule so the historical L@kers?$?2010 pattern stays in the detection set even after rotation — any re-introduction via copy-paste from an old branch or stale doc will fail CI. Allowlists docs/SECURITY.md and CHANGELOG.md (where the string is cited as a rotation reference, not a live credential).
U1000 — unused fields/funcs. The project has several deliberate stubs that trip this; a later cleanup PR can delete them.
S1016, S1031 — noisy simplifications.
Everything in the SA (correctness) family stays on.
Correctness fixes surfaced by staticcheck
backend/analytics/token_distribution.go — the "best-effort materialized-view refresh" block no longer dereferences a shadowed err. Scope-tight if err := ... for the subsequent QueryRow.
backend/api/rest/middleware.go — compressionMiddleware was parsing Accept-Encoding and then doing nothing with it. Now it's a literal pass-through with a TODO pointing at gorilla/handlers.CompressHandler.
backend/api/rest/mission_control.go — shadowed err from json.Unmarshal was silently overwritten by fmt.Errorf and then discarded. Replaced with a scoped if uerr := ... so the RPC fallback runs as intended.
backend/indexer/traces/tracer.go — best-effort CREATE TABLE no longer assigns to a shadowed err it never reads.
backend/indexer/track2/block_indexer.go — latestBlock - uint64(i) >= 0 was a tautology on uint64. Replaced with an explicit if uint64(i) > latestBlock { break } guard so count=1000 against a shallow chain doesn't underflow.
backend/tracing/tracer.go — introduces a local ctxKey type + constants so WithValue stops tripping SA1029 (same pattern as PR #4, but for the tracing package).
Verification
go build ./... — clean.
go vet ./... — clean.
go test ./... — all existing tests PASS.
staticcheck ./... — clean except for nine SA1029 hits in api/middleware/auth.go + api/track4/operator_scripts_test.go which are resolved by PR #4. Once PR #4 merges to master and PR #5 rebases, the scan-backend job will be fully green.
Completion criterion advanced
4. CI in good health — "Backend Go version matches go.mod; staticcheck, govulncheck, gitleaks, eslint, and tsc all gate the PR; workflow actually triggers on the default branch."
## Summary
PR #5 of the 11-PR completion sequence. Rewrites `.github/workflows/ci.yml` so the pipeline actually exercises what the review said was missing, fixes the Go-version drift (`go.mod` declares `go 1.23.0`, CI was pinned to `1.22`), and wires in three new gates (`staticcheck`, `govulncheck`, `gitleaks`).
## Workflow changes
- Go: `1.22` → `1.23.4` (matches `backend/go.mod`).
- Jobs split and named: `test-backend`, `scan-backend`, `test-frontend`, `gitleaks`.
- `test-backend` runs `go vet` + `go build` + `go test`.
- `scan-backend` installs `[email protected]`... now pinned to latest-that-works-with-Go-1.23 + `govulncheck@latest`.
- `test-frontend` runs `npm ci` + `next lint` + `tsc --noEmit -p tsconfig.check.json` + `next build`.
- `gitleaks/gitleaks-action@v2` job uses `fetch-depth: 0` to scan the full history.
- Triggers now include `master` (the actual default branch). Previous workflow targeted `main`/`develop` only, so it literally never ran on the repo's real PRs.
- Action versions bumped (`checkout@v4`, `setup-go@v5`, `setup-node@v4`) and caching enabled for both Node and Go modules.
- Concurrency group cancels stale runs on the same ref.
## `.gitleaks.toml` (new)
Extends the default ruleset and adds a repo-specific rule so the historical `L@kers?$?2010` pattern stays in the detection set even after rotation — any re-introduction via copy-paste from an old branch or stale doc will fail CI. Allowlists `docs/SECURITY.md` and `CHANGELOG.md` (where the string is cited as a rotation reference, not a live credential).
## `backend/staticcheck.conf` (new)
Enables `all` with a carefully-scoped disable list:
- `ST1000/1003/1005/1020/1021/1022` — stylistic comment / naming nits.
- `U1000` — unused fields/funcs. The project has several deliberate stubs that trip this; a later cleanup PR can delete them.
- `S1016`, `S1031` — noisy simplifications.
Everything in the `SA` (correctness) family stays on.
## Correctness fixes surfaced by staticcheck
- `backend/analytics/token_distribution.go` — the "best-effort materialized-view refresh" block no longer dereferences a shadowed `err`. Scope-tight `if err := ...` for the subsequent `QueryRow`.
- `backend/api/rest/middleware.go` — `compressionMiddleware` was parsing `Accept-Encoding` and then doing nothing with it. Now it's a literal pass-through with a TODO pointing at `gorilla/handlers.CompressHandler`.
- `backend/api/rest/mission_control.go` — shadowed `err` from `json.Unmarshal` was silently overwritten by `fmt.Errorf` and then discarded. Replaced with a scoped `if uerr := ...` so the RPC fallback runs as intended.
- `backend/indexer/traces/tracer.go` — best-effort `CREATE TABLE` no longer assigns to a shadowed `err` it never reads.
- `backend/indexer/track2/block_indexer.go` — `latestBlock - uint64(i) >= 0` was a tautology on `uint64`. Replaced with an explicit `if uint64(i) > latestBlock { break }` guard so `count=1000` against a shallow chain doesn't underflow.
- `backend/tracing/tracer.go` — introduces a local `ctxKey` type + constants so `WithValue` stops tripping SA1029 (same pattern as PR #4, but for the tracing package).
## Verification
- `go build ./...` — clean.
- `go vet ./...` — clean.
- `go test ./...` — all existing tests PASS.
- `staticcheck ./...` — clean except for nine SA1029 hits in `api/middleware/auth.go` + `api/track4/operator_scripts_test.go` which are resolved by [PR #4](https://gitea.d-bis.org/d-bis/explorer-monorepo/pulls/4). Once PR #4 merges to `master` and PR #5 rebases, the scan-backend job will be fully green.
## Completion criterion advanced
> **4. CI in good health** — "Backend Go version matches `go.mod`; staticcheck, govulncheck, gitleaks, eslint, and tsc all gate the PR; workflow actually triggers on the default branch."
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
PR #5 of the 11-PR completion sequence. Rewrites
.github/workflows/ci.ymlso the pipeline actually exercises what the review said was missing, fixes the Go-version drift (go.moddeclaresgo 1.23.0, CI was pinned to1.22), and wires in three new gates (staticcheck,govulncheck,gitleaks).Workflow changes
1.22→1.23.4(matchesbackend/go.mod).test-backend,scan-backend,test-frontend,gitleaks.test-backendrunsgo vet+go build+go test.scan-backendinstalls[email protected]... now pinned to latest-that-works-with-Go-1.23 +govulncheck@latest.test-frontendrunsnpm ci+next lint+tsc --noEmit -p tsconfig.check.json+next build.gitleaks/gitleaks-action@v2job usesfetch-depth: 0to scan the full history.master(the actual default branch). Previous workflow targetedmain/developonly, so it literally never ran on the repo's real PRs.checkout@v4,setup-go@v5,setup-node@v4) and caching enabled for both Node and Go modules..gitleaks.toml(new)Extends the default ruleset and adds a repo-specific rule so the historical
L@kers?$?2010pattern stays in the detection set even after rotation — any re-introduction via copy-paste from an old branch or stale doc will fail CI. Allowlistsdocs/SECURITY.mdandCHANGELOG.md(where the string is cited as a rotation reference, not a live credential).backend/staticcheck.conf(new)Enables
allwith a carefully-scoped disable list:ST1000/1003/1005/1020/1021/1022— stylistic comment / naming nits.U1000— unused fields/funcs. The project has several deliberate stubs that trip this; a later cleanup PR can delete them.S1016,S1031— noisy simplifications.Everything in the
SA(correctness) family stays on.Correctness fixes surfaced by staticcheck
backend/analytics/token_distribution.go— the "best-effort materialized-view refresh" block no longer dereferences a shadowederr. Scope-tightif err := ...for the subsequentQueryRow.backend/api/rest/middleware.go—compressionMiddlewarewas parsingAccept-Encodingand then doing nothing with it. Now it's a literal pass-through with a TODO pointing atgorilla/handlers.CompressHandler.backend/api/rest/mission_control.go— shadowederrfromjson.Unmarshalwas silently overwritten byfmt.Errorfand then discarded. Replaced with a scopedif uerr := ...so the RPC fallback runs as intended.backend/indexer/traces/tracer.go— best-effortCREATE TABLEno longer assigns to a shadowederrit never reads.backend/indexer/track2/block_indexer.go—latestBlock - uint64(i) >= 0was a tautology onuint64. Replaced with an explicitif uint64(i) > latestBlock { break }guard socount=1000against a shallow chain doesn't underflow.backend/tracing/tracer.go— introduces a localctxKeytype + constants soWithValuestops tripping SA1029 (same pattern as PR #4, but for the tracing package).Verification
go build ./...— clean.go vet ./...— clean.go test ./...— all existing tests PASS.staticcheck ./...— clean except for nine SA1029 hits inapi/middleware/auth.go+api/track4/operator_scripts_test.gowhich are resolved by PR #4. Once PR #4 merges tomasterand PR #5 rebases, the scan-backend job will be fully green.Completion criterion advanced