Skip to content

ci: open a PR automatically when a newer Go patch ships - #30

Open
kshahbw wants to merge 3 commits into
mainfrom
ci/auto-bump-go
Open

ci: open a PR automatically when a newer Go patch ships#30
kshahbw wants to merge 3 commits into
mainfrom
ci/auto-bump-go

Conversation

@kshahbw

@kshahbw kshahbw commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

BLUF

Weekly cron that opens a Go patch-bump PR when one is available. Closes the gap that let five stdlib CVEs sit unnoticed for three days and then land on an unrelated feature PR.

The gap

ci.yml triggers only on push: [main] and pull_request. So when a Go standard-library CVE is published, nothing runs — the repo stays green because nothing asked it a question.

That's what happened this week: main last ran CI on 2026-08-11 and passed. Five stdlib CVEs landed against 1.26.5. Nobody knew until #27 (an unrelated 10DLC feature PR) ran on the 14th, and its author had to stop and diagnose a failure they hadn't caused. Fixed in #28.

What this does

Every Monday, compare the go directive in go.mod against go.dev's release list. If the pinned series has a newer patch, open a PR.

Patch releases only, deliberately. A minor bump (1.26 → 1.27) can change language and toolchain behavior and deserves a human decision, so the query is filtered to the series already in go.mod.

Scripted with git and gh rather than a third-party action, following the Homebrew formula bump in release.yml (#16 replaced an action with a script for the same reason).

Verified before opening this PR

Not just written — actually exercised against the live API:

CURRENT=1.26.5  SERIES=1.26  LATEST=1.26.6  -> would open PR? YES
branch would be: chore/bump-go-1.26.6

Duplicate guard, tested against the currently-open #28:

guard fires: branch exists -> workflow would exit 0 without opening a duplicate PR

The include=all subtlety. Without that flag go.dev returns only the two newest minor series, so the pinned series would drop off the list the moment a new Go minor shipped and bumps would stop silently — the worst failure mode for a safety net. Confirmed older series still resolve with it set:

series 1.25 -> go1.25.13
series 1.24 -> go1.24.13

Also guards against going backwards (sort -V) in case go.dev ever reorders its list, and fails loudly rather than opening an empty PR if the sed doesn't match.

Known limitation — read before merging

The generated PR will not have CI runs on it. GitHub deliberately suppresses workflow runs on pull requests opened with GITHUB_TOKEN, so workflows can't trigger themselves. The generated body says so and tells the reader to close/reopen or push an empty commit.

That matters here specifically: the reason to take a bump is usually a govulncheck finding, and only CI confirms it.

The clean fix is to mint a token from the existing GitHub App — the one dispatch-docsite already uses in release.yml — and add cli to its repositories: list. App-token PRs do trigger workflows. I didn't do that here because the app is currently scoped to api-specs only and widening it is your call, not mine.

Not included

Two adjacent gaps I found but left alone, happy to do either:

  1. No scheduled govulncheck. This workflow only reacts to a Go release. A CVE with no patch yet still goes unnoticed. Adding schedule: to ci.yml would cover that — about four lines.
  2. ci.yml:58 installs govulncheck@latest, so the scanner changes under you between runs and the security job can start failing with no repo change. Pinning it would make CI reproducible.

CI runs only on push-to-main and pull_request, so a Go standard-library CVE
stays invisible until somebody opens a PR. Five stdlib CVEs landed against
1.26.5 on 2026-08-11 and went unnoticed for three days, then surfaced on an
unrelated feature PR whose author had to stop and diagnose a failure they
had not caused.

Weekly cron compares the go directive in go.mod against go.dev's release
list and opens a bump PR when the pinned series has a newer patch.

Patch releases only. A minor bump can change language and toolchain
behavior, so it stays a human decision; the query is filtered to the series
already pinned in go.mod.

Uses include=all when querying go.dev. Without it the endpoint returns only
the two newest minor series, so the pinned series would drop off the list
the moment a new Go minor shipped and bumps would stop silently. Verified
that 1.25 and 1.24 still resolve with the flag set.

Skips when a branch for the target version already exists, so a re-run
while a bump PR is open is a no-op. Verified against the currently open
chore/bump-go-1.26.6.

Scripted with git and gh rather than a third-party action, following the
Homebrew formula bump in release.yml.

Known limitation, documented in the generated PR body: GitHub suppresses
workflow runs on pull requests opened with GITHUB_TOKEN, so the bump PR
arrives without CI. Minting a token from the existing GitHub App and adding
cli to its repositories list would remove that step.
@kshahbw
kshahbw requested review from a team as code owners August 14, 2026 14:43
@bwappsec

bwappsec commented Aug 14, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

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.

3 participants