Skip to content

Add govulncheck CI job, Dependabot, and raise Go toolchain to 1.26.7 - #131

Merged
LarsLaskowski merged 4 commits into
mainfrom
claude/issue-106-9nsmbp
Aug 24, 2026
Merged

Add govulncheck CI job, Dependabot, and raise Go toolchain to 1.26.7#131
LarsLaskowski merged 4 commits into
mainfrom
claude/issue-106-9nsmbp

Conversation

@LarsLaskowski

@LarsLaskowski LarsLaskowski commented Aug 24, 2026

Copy link
Copy Markdown
Owner

📖 Description

CI built, vetted, tested, and linted, but nothing scanned the Go toolchain or module dependencies for known vulnerabilities, and .github/dependabot.yml didn't exist — even though the sonarqube job already carried a github.actor != 'dependabot[bot]' guard clearly written in anticipation of Dependabot being enabled.

This PR started as #106 alone, then grew to include its companion #107 once CI showed why the two were meant to be done together (see "How this PR grew" below).

Part 1 — CI vulnerability scanning + Dependabot (#106):

  • Adds a govulncheck job to .github/workflows/ci.yml that runs go tool govulncheck ./... on every push/PR to main, plus a weekly schedule (0 6 * * 1) so a newly-published CVE against an unchanged codebase is surfaced without waiting for the next commit. govulncheck does reachability analysis, so false-positive noise is low.
  • govulncheck is installed as a go.mod tool dependency (go get -tool golang.org/x/vuln/cmd/govulncheck@v1.7.0, Go 1.24+), not go install ...@latest/@version — see "How this PR grew" for why. This also means Dependabot's gomod ecosystem tracks and bumps it automatically.
  • Adds .github/dependabot.yml with two ecosystems: github-actions (keeps the existing SHA pins moving forward) and gomod (keeps gopkg.in/yaml.v3 and now golang.org/x/vuln current), both weekly.
  • Documents both in docs/ARCHITECTURE.md's CI summary and docs/CONTRIBUTING.md's pre-PR checklist.

Part 2 — Raise the Go toolchain (#107):

  • go.mod's go 1.22 directive raised to go 1.26.7 — Go 1.22 fell out of the two-most-recent-majors support window (currently 1.26 and 1.27, verified against the Go module proxy's toolchain list), so it receives no further security patches. Since PiMonitor ships as a single statically-linked binary, this is a dependency-security property, not just a build detail. It also happens to be what unlocks the tool directive mechanism used in Part 1 (Go 1.24+).
  • golangci-lint bumped from v2.12.2 to v2.13.1 in CI and docs/CONTRIBUTING.md: v2.12.2 was built with Go 1.25 and refuses to lint a go.mod targeting a newer Go version, so this was necessary to keep make lint working — anticipated in go.mod targets Go 1.22, which no longer receives upstream security fixes #107's own checklist.
  • Updated the documented "Requires Go 1.22+" claim in README.md and docs/CONTRIBUTING.md, and added a policy note to docs/CONTRIBUTING.md explaining the go directive tracks a supported release going forward, so this doesn't silently recur.
  • No language features adopted opportunistically — this is a mechanical version bump, per go.mod targets Go 1.22, which no longer receives upstream security fixes #107's explicit instruction.
  • go list -deps ./cmd/pimonitor confirms none of the new tool-only requires (golang.org/x/vuln, x/tools, x/mod, etc.) reach the shipped binary — they exist purely for go tool govulncheck.

How this PR grew from #106 to also include #107

I initially opened this PR scoped to #106 only. CI then failed on three rounds:

  1. SonarCloud Quality Gate flagged githubactions:S8545 ("Dependency versions are not predictable") on go install .../govulncheck@latest.
  2. Pinning to @v1.7.0 (still go install) did not clear it — S8545 flags go install pkg@version in CI generally, since it isn't verified against this repo's own go.sum, regardless of which version is pinned.
  3. Switched to a go.mod tool dependency instead (go get -tool .../govulncheck@v1.7.0, needs Go 1.24+) and go tool govulncheck ./... in CI — a real go.sum-checksummed, lock-file-enforced install, which is what S8545 actually wants, and a bonus: Dependabot's gomod ecosystem can now track and bump it automatically, closing a gap the original issue explicitly flagged as unresolved ("it must be a tool dependency, which this project does not otherwise have").

Separately, the govulncheck job itself correctly found 31 real, reachable CVEs in the Go 1.22 standard library (net/http, crypto/tls, crypto/x509, net/url, etc.) — none fixable by touching gopkg.in/yaml.v3, since they're in the toolchain itself. Issue #107 — already filed, and explicitly written as "companion to the issue adding govulncheck... consider doing them in that order" — was exactly this. Rather than leave the newly-added job permanently red pending separate follow-up work, I confirmed with the repo owner and folded #107 into this PR.

🎫 Issues

Closes #106
Closes #107

👩‍💻 Reviewer Notes

  • The sonarqube job's if: github.actor != 'dependabot[bot]' guard was already present and is unchanged; this PR is what makes it actually matter, since Dependabot PRs will now exist.
  • Worth confirming after merge that a Dependabot PR goes green on build-test-lint, govulncheck, and cross-compile, and that .github/dependabot.yml shows up under Insights → Dependency graph → Dependabot.
  • golangci-lint v2.13.1 vs. the previously-pinned v2.12.2: ran locally against the full repo with the new Go 1.26.7 toolchain — 0 issues.
  • go.mod/go.sum now carry golang.org/x/vuln and its transitive deps under a tool directive — these are build-tool-only (see go list -deps note above), not a change to the runtime dependency policy in CLAUDE.md/ARCHITECTURE.md (still just gopkg.in/yaml.v3 in the shipped binary).

📑 Test Plan

This is CI/toolchain configuration, so there is no Go test to add. Verification performed instead:

  • go build ./..., go vet ./..., go test ./... -race -cover, and golangci-lint run (v2.13.1) all pass locally against the Go 1.26.7 toolchain, both before and after switching to the tool-dependency form of govulncheck.
  • Cross-compile checked locally for both CI targets: GOOS=linux GOARCH=arm64 and GOOS=linux GOARCH=arm GOARM=6, both CGO_ENABLED=0 — both succeed.
  • go list -deps ./cmd/pimonitor confirms the new tool-only requires don't reach the shipped binary.
  • All modified/added YAML files (ci.yml, dependabot.yml) parse as valid YAML.
  • go tool govulncheck ./... could not be run to completion in this sandbox, on any commit: this environment's outbound network policy blocks vuln.go.dev (the tool's vulnerability database), returning 403. The job itself is correctly wired and did run for real on GitHub's runners against the Go 1.22 toolchain (that's how the 31 findings that motivated the toolchain bump were discovered, and how the two SonarCloud rounds were diagnosed) — final end-to-end confirmation that Go 1.26.7 clears the findings and that go tool govulncheck satisfies SonarCloud happens when this commit's CI runs in Actions.

✅ Checklist

General

  • I have added/updated tests for my changes — N/A, CI-config/toolchain-only change, no Go behavior changed, no Go test to add (see Test Plan).
  • go vet ./... and golangci-lint run are clean.
  • I have tested my changes.
  • I have read the CONTRIBUTING documentation and followed the project's code style guidelines.
  • I have updated ARCHITECTURE.md if this changes a documented design decision.

REST API / configuration / packaging

Not applicable — no REST API, config schema, or packaging changes.

⏭ Next Steps

None outstanding — this PR now covers both #106 and its companion #107 together, as the original issue suggested.

claude added 3 commits August 24, 2026 17:12
CI built, vetted, tested, and linted but never scanned the Go toolchain
or module dependencies for known vulnerabilities, and no Dependabot
config existed to keep SHA-pinned Actions or gopkg.in/yaml.v3 current
(the sonarqube job's dependabot[bot] guard was already prepared for
Dependabot, but the config was never committed).

Add a govulncheck job (reachability-based, so noise is low) that runs
on every push/PR plus a weekly schedule so a newly-published CVE
against an unchanged codebase gets caught without waiting for the next
commit. Add .github/dependabot.yml for the github-actions and gomod
ecosystems. Document both in ARCHITECTURE.md's CI summary and add
govulncheck to CONTRIBUTING.md's pre-PR checklist.
SonarCloud's Quality Gate failed the PR with a MAJOR security finding
(githubactions:S8545, "Dependency versions are not predictable") on
the "go install ...@latest" line: an unpinned/floating dependency
install in CI is a supply-chain risk, the same class of issue the
repo's SHA-pinned Actions already guard against.

Pin to v1.7.0 (the version @latest resolved to) instead. The
vulnerability database itself is fetched fresh over the network at
scan time regardless of the installed tool's version, so this keeps
the main benefit (current CVE data) while making the build
reproducible.
Go 1.22 fell out of the two-most-recent-majors support window, so it
receives no further security patches. Since PiMonitor ships as a
single statically-linked binary with the standard library baked in,
the toolchain version is a dependency-security property: the new
govulncheck CI job (added alongside this) found 31 real, reachable
CVEs in net/http, crypto/tls, crypto/x509, net/url and others that are
only fixed in Go 1.23-1.25 — none of them fixable by updating
gopkg.in/yaml.v3, since they're in the standard library itself.

Go 1.26.7 is the newest patch of the older of the two currently
supported majors (1.26 and 1.27), verified against the Go module
proxy's toolchain list. No language features were adopted opportunistically;
this is a mechanical version bump per docs/CONTRIBUTING.md's now-documented
policy of tracking a supported release.

golangci-lint v2.12.2 was built with Go 1.25 and refuses to lint a
go.mod targeting a newer Go version ("the Go language version used to
build golangci-lint is lower than the targeted Go version"), so it is
bumped to v2.13.1 (built with Go 1.26.7) to match, as anticipated by
issue #107.

Closes #107.
@LarsLaskowski LarsLaskowski changed the title Add govulncheck CI job and Dependabot configuration Add govulncheck CI job, Dependabot, and raise Go toolchain to 1.26.7 Aug 24, 2026
SonarCloud's Quality Gate still failed after pinning to
"go install .../govulncheck@v1.7.0" (githubactions:S8545, "Dependency
versions are not predictable. Use a lock-file enforcing command
instead."): the rule flags any `go install pkg@version` in CI
regardless of pinning, since it isn't verified against this repo's own
go.sum.

Go 1.24+ (available now that go.mod targets 1.26.7) supports `tool`
dependencies: `go get -tool golang.org/x/vuln/cmd/govulncheck@v1.7.0`
records it under a `tool` directive with a real go.sum-checksummed
require entry, and `go tool govulncheck ./...` runs that exact,
verified build - a genuine lock-file-enforcing command. This also
means Dependabot's gomod ecosystem can now track and bump govulncheck
automatically, closing the gap the original issue noted ("it must be a
tool dependency, which this project does not otherwise have").

The added golang.org/x/vuln/x/tools/x/mod/etc. requires are tool-only:
`go list -deps ./cmd/pimonitor` confirms none of them reach the
shipped binary.
@sonarqubecloud

Copy link
Copy Markdown

@LarsLaskowski
LarsLaskowski merged commit 01cbb2d into main Aug 24, 2026
6 checks passed
@LarsLaskowski
LarsLaskowski deleted the claude/issue-106-9nsmbp branch August 24, 2026 17:55
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.

go.mod targets Go 1.22, which no longer receives upstream security fixes CI has no vulnerability scanning and no Dependabot configuration

2 participants