Repository navigation
ci: refuse merge-queue runs that contain fork or Dependabot pull requests - #165
Merged
Merged
Conversation
…e foreign head repositories
oschaaf
enabled auto-merge
October 22, 2026 19:18
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.
What
A merge-queue run builds the queued commits on the fleet runners, and the
pull_requestevent is the only place fork and Dependabot pull requests are routed to hosted labels. This adds a hosted refusal formerge_groupruns.The
changesjob (hosted) gets a first step,Refuse fork and Dependabot PRs in the merge queue, that runs only onmerge_group. It resolves every pull request in the group (the last(#N)of each commit subject inbase_sha..head_sha, plus the number inhead_ref), looks each one up withgh api(5 tries, 2/4/8/16 s backoff) and fails closed:dependabot[bot], or its head repository is gone or is not this repository;(#N), or thehead_refcannot be parsed;vendornow needschanges, and every other fleet job already needsvendororchanges, so a refusal skips the whole fleet andCI gategoes red. Thechangesjob getspull-requests: read.The classifier is
tools/ci/queue_fork_guard.sh. The step reads it from the default branch (git show "origin/${DEFAULT_BRANCH}:..." | bash), never from the queued tree, withset -euo pipefailso a missing script fails the step. This pull request's own merge-group run uses the pipeline already on the default branch (the caller pins it there), so no bootstrap path is needed.The workflow-shape gate check
queue-guard-reads-default-branchrequires the step as the first step after the checkout in thechangesjob, fixes its keys,if:, env andrun:block, rejects any other spelling that reads the script (truncated, globbed, braced,find,source) and env that could redirect it (BASH_ENV,PATH,GIT_*), and requiresvendorto haveneeds: changesand noif:; each rejection has a fixture.Assumption
The PR-number rule relies on the queue's squash merge method (one
(#N)commit per pull request). A different method must change the classifier first.Scope
The guard protects runs that go through
pipeline-pr.yml. A queued tree can still change the callerci.ymlto call another allow-listed fleet pipeline (full, nightly, release and the other reusable workflows, and the@ci-devrefs), and those carry no guard. Closing that is a separate change; until it lands, no fork or Dependabot pull request is added to the merge queue (policy).Testing
tools/ci/test_queue_fork_guard.sh(fakeghandsleep, temporary git repository with squash-style commits): same-repo group of three, fork in the middle, Dependabot, foreign head repository, deleted head repository, no PR number, unparseable head ref, API 500 (exactly 5 calls, backoff 2/4/8/16), empty range, PR number only inhead_ref(looked up once). Registered in CI.tools/ci/test_check_workflow_shape.shcovers the new check with one fixture per rejection and the accepted form.tools/ci/check-workflow-shape.sh,actionlint,shellcheckand the public-tree hygiene gate pass.