ci: action majors, the Go toolchain switch, and dependabot auto-merge cause 5 - #304
Conversation
…ns mid-build Eight actions: setup-go 5→7, setup-node 4→7, setup-python 5→7, docker/metadata-action 5→6, docker/setup-buildx-action 3→4, docker/build-push-action 5→7, docker/login-action 3→4, dependabot/fetch-metadata 2→3. Dependabot proposed five of these (#254-#258) and five is also open-pull-requests-limit, so the other three were never proposed at all. The queue was saturated. Worth remembering that a quiet Dependabot can mean "nothing to do" or "no room to say so." setup-go is the one that changes behavior, so it was traced rather than assumed. v5 reads the `go` line and installed go1.26.0; Go's own toolchain switching then fetched go1.26.5 on the first build, because `toolchain go1.26.5` says to. The right compiler was used — `go version` reported 1.26.5 — but it arrived at build time, over the network, once per job, and the tar warnings about gotoolchain_*.txt "File exists" in every job log were that download racing the module cache restore. v6+ parses `toolchain` directly and exports GOTOOLCHAIN=local, so 1.26.5 installs up front and nothing switches. Verified against the v7 sources, not the PR discussion: installer.ts parseGoVersionFile matches /^toolchain go(1\.\d+...)/m and prefers it unless GOTOOLCHAIN is already `local`, and main.ts calls setGoToolchain() to set exactly that. The comment in go.mod is updated, including the new failure mode — under GOTOOLCHAIN=local a toolchain version setup-go cannot install fails the build rather than quietly falling back to one that works. Checked for each of the others instead of trusting the release notes: - buildx v4 removed the deprecated `config`, `config-inline` and `install` inputs. Not used here. - build-push-action v7 removed DOCKER_BUILD_NO_SUMMARY and DOCKER_BUILD_EXPORT_RETENTION_DAYS. Neither appears in .github/. - setup-python v7 removed the `pip-install` input. Not used. - setup-node v6 limited automatic caching to npm. No `cache:` input is set on the Node or Python steps, so it cannot apply. - All eight need runner >= v2.327.1 for their Node 24 runtime; ubuntu-latest satisfies that. Node 20 -> 22 in the sdk-metrics job while it was open. 20 reached end of life in April 2026 and sdks/javascript declares `node >=16`, so nothing held the pin down except never having revisited it. Closes #254, closes #255, closes #256, closes #257, closes #258
…te the merge Cause 5 of "46 Dependabot PRs opened, 0 merged." Fixing #288 made .github/dependabot.yml valid. Dependabot re-evaluated it within minutes and opened 14 PRs across ecosystems it had never touched, and the `automerge` label arrived on every one of them — the label plumbing works. And still nothing merged, because the step finally ran instead of being skipped, and failed: failed to create review: GraphQL: GitHub Actions is not permitted to approve pull requests. (addPullRequestReview) can_approve_pull_request_reviews is false at the repository level. The step body was `gh pr review --approve` then `gh pr merge --auto --squash`, under `bash -e`, so the failing first line aborted before the line that does the work. The approval was never needed. Branch protection on main requires status checks and has required_pull_request_reviews: null — nothing is waiting on a review. Deleting the line is the fix. Enabling "Allow GitHub Actions to create and approve pull requests" would instead grant every workflow in the repository the ability to satisfy a review requirement, to buy something no rule asks for. Causes 1 and 4 both kept the `if:` condition false, so the step was skipped and this one could not produce a symptom until they were gone. That is the shape worth recording: a fix that should have worked and didn't usually means a second cause, not a wrong diagnosis. All five are now enumerated in the workflow header in the order they were found, with why each hid the next. Closes #305
|
Pushed a second commit: cause 5 of the dependabot auto-merge problem (#305), found while this PR was open. Merging #289 made And still nothing merged. The step stopped being skipped and started failing:
The approval was never needed: branch protection on That is five independent causes for one symptom, and the shape is the useful part — causes 1 and 4 both left the |
Both #305's and #306's changelog entries belong in Unreleased; the conflict was only that they were written against the same anchor. Cause five first, as the later finding. Also fixes the numbering slip in dependabot-automerge.yml: the inline step comment still said "cause 4" and "causes 1 and 3" from before the header was renumbered to five.
Supersedes and closes #254, #255, #256, #257, #258 — plus three majors Dependabot never proposed.
Why one PR instead of five
Dependabot opened five of these. Five is also
open-pull-requests-limitfor thegithub-actionsecosystem, so three further outdated majors were never proposed at all — the queue was saturated. Enumerating everyuses:pin against its latest release found them:actions/setup-goactions/setup-nodeactions/setup-pythondocker/metadata-actiondocker/setup-buildx-actiondocker/build-push-actiondocker/login-actiondependabot/fetch-metadataA quiet Dependabot can mean "nothing to do" or "no room to say so." This was the second.
setup-go actually changes behavior
The only bump here with a real mechanism change, so it was traced rather than assumed.
Before (v5): reads the
goline → installs go1.26.0. Go's own toolchain switching then downloads go1.26.5 on the first build, becausetoolchain go1.26.5says to. The right compiler got used —go version go1.26.5 linux/amd64in the logs — but it arrived at build time, over the network, once per job. Thosetar: ... gotoolchain_local.txt: Cannot open: File existswarnings in every job log are that download racing the module-cache restore.After (v6+): parses
toolchaindirectly and exportsGOTOOLCHAIN=local, so 1.26.5 installs up front and nothing switches. Same compiler, one fewer moving part, no log noise.Verified against the v7 sources rather than the PR discussion, since the discussion on actions/setup-go#460 records a behavior change that was then partly reverted:
installer.tsparseGoVersionFilematches/^toolchain go(1\.\d+(?:\.\d+|rc\d+)?)/mand prefers it unlessGOTOOLCHAINis alreadylocalmain.tscallssetGoToolchain(), which sets exactly that — and calls it afterresolveVersionInput(), so the toolchain line still wins on the first readThe
go.modcomment is updated to describe this, including the new failure mode it introduces: underGOTOOLCHAIN=localthere is no safety net — a toolchain version setup-go cannot install now fails the build outright instead of quietly switching to one that works. That is the better behavior for a filesystem, but it should be written down.The other seven, checked rather than assumed
Each release's removals were grepped for in this repo:
config,config-inlineandinstallinputs → not used hereDOCKER_BUILD_NO_SUMMARYandDOCKER_BUILD_EXPORT_RETENTION_DAYS→ neither appears anywhere in.github/pip-installinput → not usedcache:input is set on the Node or Python steps#handling inside list values → thetags:list has no#in any valueubuntu-latestsatisfiesOne thing found while in here
The
sdk-metricsjob pinned Node 20, which reached end of life in April 2026 — so CI kept installing a runtime that no longer gets security fixes.sdks/javascriptdeclaresnode >=16, so nothing was holding the pin down except never having revisited it. Now 22, the active LTS.Gates
go build ./...·go vet ./...·gofmt -l .clean ·go test ./internal/config/ok (the doc and changelog gates live there). The actions themselves are verified by this PR's own CI running on them.