Skip to content

ci: open fix PRs for reachable Go vulnerabilities on release branches - #4547

Draft
reinkrul wants to merge 2 commits into
masterfrom
ci/govulncheck-release-branch-fix-prs
Draft

reinkrul wants to merge 2 commits into
masterfrom
ci/govulncheck-release-branch-fix-prs

Conversation

@reinkrul

@reinkrul reinkrul commented Sep 14, 2026

Copy link
Copy Markdown
Member

Part of #4545. Builds on #4546 (which removed the proactive Dependabot updates this replaces).

Extends govulncheck-cron-schedule.yaml: on a V5.4/V6.2 finding, instead of only Slack-alerting, it now also opens a PR with the fix, when the finding is reachable and a fixed version exists. Master's path is unchanged (Slack alert only - its own Dependabot config handles the fix there).

How it works (3 jobs):

  • govulncheck_job (existing, matrixed over master/V5.4/V6.2): the text-format run still triggers the job failure. On failure for a release branch, a second JSON-format run extracts which module/version to bump. A new step reduces that to actionable findings - one per (advisory, module), skipping stdlib/toolchain findings (need a Go version bump, not go get), findings with no fixed version yet, and advisories that already have an open PR (keyed on branch + advisory ID, so the same CVE on both release lines still gets one PR each). Actionable findings are uploaded as a per-branch artifact. If a branch failed but nothing was actionable, it gets its own Slack alert here instead.
  • prepare_fix_matrix: merges the per-branch artifacts into one list, since a uses: action step can't be looped over a variable number of findings within a single job.
  • open_fix_prs: a dynamic matrix, one leg per finding. Checks out the branch, go get/go mod tidy the fix, and opens the PR via peter-evans/create-pull-request with sign-commits: true - it signs the commit as github-actions[bot] through the GitHub API rather than a local git commit/git push, which every branch here requires (org-wide signed-commits ruleset) and the runner has no bot signing key for. Slack gets a message per PR actually opened, linking to it.

Permissions: govulncheck_job needs pull-requests: read (to check for an existing fix PR) in addition to contents: read. open_fix_prs needs contents: write + pull-requests: write. prepare_fix_matrix needs none.

Not yet verified against a live finding - there's no known-vulnerable module on V5.4/V6.2 right now to exercise this against. Plan to verify with workflow_dispatch once merged, ideally against a branch with a real (or deliberately introduced) vulnerable dependency, before relying on this for real.

Passes actionlint (with shellcheck) cleanly.

V5.4/V6.2 no longer get proactive Dependabot bumps (#4546), so the
existing govulncheck cron - which only Slack-alerted before - now also
opens a PR with the fix when a finding is reachable and a fixed version
exists. Master keeps the plain Slack alert; its own weekly Dependabot
PRs are the fix path there.

The fix is built entirely through the GitHub API (blob/tree/commit/ref)
rather than a local `git commit` + `git push`: every branch requires
signed commits org-wide, and the runner has no signing key for a bot
identity. Commits created via the API are signed by GitHub itself.

Duplicate PRs are avoided by keying on (branch, advisory ID), so the
same CVE affecting both release lines still gets one PR per branch, and
two distinct CVEs on the same module don't collide.

Assisted by AI
The previous commit built the signed commit by hand through the GitHub
Git Data API (blob/tree/commit/ref) to work around the org-wide signed-
commits ruleset. peter-evans/create-pull-request's `sign-commits: true`
does the same thing (signs as github-actions[bot] via the GITHUB_TOKEN,
no bot signing key needed) as a maintained action instead.

A `uses:` action step can't be looped over a variable number of
findings within one job, though, so the fix now runs as a dynamic
matrix: govulncheck_job still detects and extracts actionable findings
per branch (one artifact each), prepare_fix_matrix merges those into a
single list, and open_fix_prs runs create-pull-request once per
finding. Slack now reports per-PR-opened instead of a single combined
summary; a branch with a failure but nothing actionable (already an
open PR, no fixed version yet, or a toolchain/stdlib finding) still
gets its own alert from the detection job.

Assisted by AI
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