ci(guard): accept Dependabot security updates into main (#571) - #572
Merged
Merged
Conversation
Dependabot security updates always target the default branch, so the main source guard rejected every one of them. Move the decision into scripts/main-branch-guard.zsh and also allow a same-repository dependabot/* branch whose pull-request author is dependabot[bot]. The workflow checks out only that script from the base branch, so it never runs pull-request code, and needs contents: read for that. The new Main Branch Guard job runs tests/main-branch-guard.zsh.
ss-o
commented
Sep 27, 2026
ss-o
left a comment
Member
Author
There was a problem hiding this comment.
Self-review of head f9db222.
No defects found. What I checked:
- Trust boundary: under
pull_request_target,actions/checkoutwith noref:checks out the base branch, and the sparse pattern limits it toscripts/main-branch-guard.zsh, so no pull-request code runs.persist-credentials: falsekeeps the token out of.git/config. Untrusted values (head_ref, head repository, author login) reach the script only throughenv:, never interpolated intorun:. - Decision logic: the repository check runs first and also fails when
REPOSITORYis empty;dependabot/*in a[[ == ]]pattern matches nested paths such asdependabot/github_actions/actions/checkout-5(covered by a test); the author must equaldependabot[bot]exactly, soapp/dependabot, a person, and an empty login all fail (covered). - Log output: ref names cannot contain newlines, so a branch name cannot start a new workflow-command line in the
::error::output. - Test coverage: 12 cases, and three mutations (drop the author check, widen the branch pattern, drop the repository check) each fail the test.
Residual risks, not defects:
- The new guard path runs for the first time on the next pull request into
mainafter this merges, becausepull_request_targetuses the workflow frommain. That run needs watching; a failure there blocks every pull request intomain. - The guard now depends on
apt-get updateandapt-get install zshthroughsetup-zsh, which the inline version did not. An apt outage would fail this required check until a rerun succeeds. - After merge,
mainmust be merged forward intonext.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Dependabot security updates always target the default branch (
main) and ignoretarget-branch: next, so the Main Branch Source Guard rejected every one of them. This hotfix implements the exception that z-shell/.github#698 specifies inrunbooks/branch-protection.md.scripts/main-branch-guard.zshnow holds the decision. It checks the same-repository head first, then allowsnext,hotfix-*, or adependabot/*branch whose pull-request author (github.event.pull_request.user.login) isdependabot[bot]. The error message names all three sources..github/workflows/main-branch-guard.ymlchecks out only that script, from the base branch (noref:override underpull_request_target,persist-credentials: false, non-cone sparse checkout), sets up Zsh withz-shell/.github/actions/setup-zsh, and runs the script. Permissions change from{}tocontents: readfor the checkout.tests/main-branch-guard.zshcovers 12 cases. The allowed cases arenext,hotfix-*, and two Dependabot branches bydependabot[bot]. The rejected cases are adependabot/branch by a person, byapp/dependabot, or with an empty author; the bot on a non-Dependabot branch; fork heads; an ordinary topic branch; and an empty ref. The newMain Branch Guardjob inzsh-n.ymlruns it.AGENTS.mdadds the Dependabot source to the branch model.The runbook states the known limitations, which this guard does not close: a routine Dependabot update retargeted to
mainpasses, and so do commits another user pushes onto an opendependabot/*branch, because the pull-request author does not change.First live run happens after merge
pull_request_targetruns the workflow frommain, so this pull request is still judged by the current inline guard (it allowshotfix-*). The new checkout, Zsh setup, and script run for the first time on the next pull request intomainafter this merges; that run needs to be watched. If it fails, the required check blocks every pull request intomain, and the repair needs a reviewed ruleset bypass for that one pull request.The
setup-zshpin uses the# maincomment like the other organization callers. The interim pinact exception covers reusable workflows only, so it would need attention if zi enables pinact.After merge,
mainmust be merged forward intonextas the branch model requires.Related issues
Closes #571
Refs z-shell/.github#487
Type of change
fix- bug fix (non-breaking)feat- new feature (non-breaking)feat!/fix!- breaking changeperf- performance improvementrefactor- code change with no functional impactdocs- documentation onlytest- test addition or correctionbuild- build system or dependency changeci- CI/workflow changestyle- formatting with no behavior changechore- maintenance / dependency bumprevert- revert of an earlier changeChecklist
next; only same-repository hotfixes targetmainnexttomainpromotion uses a merge commit and records both parent SHAs (not a promotion)Co-authored-bytrailer credits a real human, never a bot, AI agent, or automationzsh -n zi.zsh/ Trunk checks)Verification
On
f9db222:zsh -f tests/main-branch-guard.zsh: passed.zsh -nandzcompileon both new files: passed.actionlint1.7.8 on both workflows: passed.trunk checkon the changed files: no issues.scripts/main-branch-guard.zsh, and the guard runs from that checkout.