Skip to content

chore(ci): modernize GitHub Actions + migrate golangci-lint to v2 (fixes the go1.25 lint)#24

Merged
kamir merged 2 commits into
mainfrom
chore/modernize-ci-golangci-v2
Jun 17, 2026
Merged

chore(ci): modernize GitHub Actions + migrate golangci-lint to v2 (fixes the go1.25 lint)#24
kamir merged 2 commits into
mainfrom
chore/modernize-ci-golangci-v2

Conversation

@kamir

@kamir kamir commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

What

One PR that modernizes CI for kshark-core: bump five GitHub Actions and migrate the golangci-lint config to v2, which is the actual fix for the red Build & Test > Lint step.

Action bumps

Applied across .github/workflows/build-and-release.yml, docs.yml, security.yml (only the uses: version pins changed, no workflow restructuring):

Action From To Supersedes
actions/checkout v4 v6 #15
goreleaser/goreleaser-action v5 v7 #13
golangci/golangci-lint-action v6 v9 #12
actions/setup-go v5 v6 #11
actions/deploy-pages v4 v5 #10

These five dependabot PRs each touched the same shared workflow files and would cascade-conflict if merged one-by-one, so they are rolled into this PR. It supersedes #15, #13, #12, #11, #10.

golangci-lint v2 migration (the lint fix)

The Lint step failed on every PR with:

can't load config: the Go language version (go1.24) used to build golangci-lint is lower than the targeted Go version (1.25.0)

go.mod targets go 1.25.0. golangci-lint v1 (last release v1.64.8, built with go1.24) refuses to lint a module that targets go1.25. golangci-lint v2 is built with go1.25 and reads a v2-format config, so the fix is both the golangci-lint-action@v9 bump above and a .golangci.yml migration from v1 to v2 format (v2 will not read the v1 config).

.golangci.yml was converted with the official migrator (golangci-lint migrate), which preserves the v1 linter intent. In v2 the default set already includes errcheck, govet, staticcheck, unused and ineffassign, so only the additional v1 linters are listed under enable. Net enabled set matches v1: errcheck, govet, staticcheck (gosimple folded in, typecheck dropped as a config entry), unused, ineffassign, misspell, gocritic, revive, plus bodyclose, gosec, noctx, and the gofmt formatter. No new linters were added and no linter was disabled wholesale.

Verified locally with golangci-lint v2.6.0 (built with go1.25.3):

  • golangci-lint config verify -> valid v2 config.
  • golangci-lint run ./... -> exits 0. The go1.24 < go1.25 error is gone and the config loads.

Findings handled vs deferred

The v1 lint step never ran green in CI (it always died on the go-version error), so v2 surfaced a batch of pre-existing findings on main. Handled in this PR:

  • gofmt: tree-wide alignment applied (matches the go1.25 / go1.26 gofmt).
  • staticcheck SA4017: fixed a real dead no-op loop in trend_test.go (a time.Before comparison whose result was discarded in an empty if body).

Deferred to a follow-up code cleanup, scoped with commented exclusions in .golangci.yml (per linter/rule, not by disabling linters):

  • errcheck: unchecked io.Copy / SetReadDeadline / SetWriteDeadline / fmt.Sscanf / ReadString on probe and bundle paths, and the usual setup/teardown calls in _test.go.
  • gosec: G115 (int narrowing of protocol byte fields), G401/G505 (MySQL native-password auth is sha1 by protocol), G402 (deliberate TLS probing with InsecureSkipVerify), G306 (report-file perms), G404 (jitter randomness). Inherent to a network-diagnostic probe tool.
  • noctx: direct net/tls/exec calls without a context, inherent to the probe paths of a diagnostic CLI; plus _test.go.
  • staticcheck style/quickfix nits: QF1002/QF1003/QF1011/QF1012/S1039/ST1005/ST1023 (tagged switch, omit inferred type, Fprintf, non-capitalized error strings).
  • gocritic exitAfterDefer in CLI entrypoints.

These are tracked as a follow-up; the exclusions keep the v1 linter set enabled and let lint pass on the existing code without mass-suppression.

Verification

  • golangci-lint run ./... -> 0 issues (v2 config, go1.25 toolchain).
  • go build ./... -> ok.
  • go vet ./... -> ok.
  • go test ./... -race -> all packages pass.
  • gofmt -l -> clean.

Bump five GitHub Actions to the versions requested by the open dependabot
PRs, and migrate the golangci-lint config to v2 format, which is the fix
for the red "Build & Test > Lint" step.

Action bumps (across build-and-release.yml, docs.yml, security.yml):
- actions/checkout v4 -> v6
- actions/setup-go v5 -> v6
- golangci/golangci-lint-action v6 -> v9
- goreleaser/goreleaser-action v5 -> v7
- actions/deploy-pages v4 -> v5

The Lint step failed on every PR with "the Go language version (go1.24)
used to build golangci-lint is lower than the targeted Go version
(1.25.0)". go.mod targets go 1.25.0; golangci-lint v1 (built with go1.24)
refuses to lint it. golangci-lint v2 is built with go1.25 and reads a
v2-format config, so the action bump to v9 plus a .golangci.yml v2
migration are both required.

The .golangci.yml was converted with `golangci-lint migrate`, which
preserves the v1 linter intent (errcheck, govet, staticcheck with gosimple
folded in, unused, ineffassign, misspell, gocritic, revive, plus bodyclose,
gosec, noctx and the gofmt formatter). One real finding was fixed: a dead
no-op loop in trend_test.go (staticcheck SA4017). gofmt alignment was
applied tree-wide. The remaining pre-existing findings, which were never
enforced because the v1 lint never ran green, are scoped with commented
exclusions and listed in the PR for a follow-up cleanup.

Supersedes the five action-bump dependabot PRs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
setup-go v6 sets GOTOOLCHAIN=local, so the pinned go-version 1.23 no longer
auto-upgrades to the 1.25 the module requires, and the Download dependencies step
fails with 'go.mod requires go >= 1.25.0 (running go 1.23.12; GOTOOLCHAIN=local)'.
Pin the CI Go to 1.25 so build + lint run on the module's target version.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kamir kamir merged commit ff4bf48 into main Jun 17, 2026
1 of 2 checks passed
@kamir kamir deleted the chore/modernize-ci-golangci-v2 branch June 17, 2026 14:18
kamir added a commit that referenced this pull request Jun 17, 2026
Follow-up to #24. CI used golangci-lint version: latest, which drifted to a newer
release whose gosec G703 (path-traversal) + G704 (SSRF) taint rules fail on patterns
kshark guards at runtime (file reads in diff.go/util.go; the SSRF-checked httpGet in
validate_blueprint.go). #24 validated v2.6.0 locally as green; pin CI to v2.6.0 so it
matches. Bump deliberately + re-validate. Only golangci-lint is pinned; goreleaser stays latest.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kamir added a commit that referenced this pull request Jun 17, 2026
Follow-up to #24. CI used golangci-lint version: latest, which drifted to a newer
release whose gosec G703 (path-traversal) + G704 (SSRF) taint rules fail on patterns
kshark guards at runtime (file reads in diff.go/util.go; the SSRF-checked httpGet in
validate_blueprint.go). #24 validated v2.6.0 locally as green; pin CI to v2.6.0 so it
matches. Bump deliberately + re-validate. Only golangci-lint is pinned; goreleaser stays latest.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant