Repository navigation
ci: refuse merge_group and unexpected events in every fleet pipeline - #166
Merged
Merged
Conversation
oschaaf
force-pushed
the
ci/event-guard-fleet-pipelines
branch
from
October 22, 2026 22:46
9e68386 to
9ca32b5
Compare
… every fleet pipeline
… in the shape gate
oschaaf
force-pushed
the
ci/event-guard-fleet-pipelines
branch
from
October 22, 2026 23:04
9e68386 to
e4eba3f
Compare
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 23, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 23, 2026
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
Every fleet pipeline other than
pipeline-pr.ymlnow opens with a hosted jobevent-guard. It refuses:merge_groupis allowed in none of them);refs/heads/gh-readonly-queue/and any ref outside the pipeline's allowed refs (off-ref pushes and dispatches);workflow_dispatchmade bygithub-actions[bot](a dispatch made with a workflow token);The
changesjob ofpipeline-pr.ymlalso gets two steps before the fork guard step: it refuses a push on any ref other thanrefs/heads/masterandrefs/heads/ci-dev(the queue's temporary branch included) and a dispatch made bygithub-actions[bot]. The gate pins both steps.Every fleet job reaches
event-guardthroughneeds(root jobs need it directly; in the release pipelines the rootref-guardjob does), so a refusal skips the whole fleet.Why
In a
merge_grouprun the callerci.ymlcomes from the queued tree, so a queued tree can call any allow-listed fleet pipeline, and it can producepushandworkflow_dispatchevents of its own. This narrows that boundary. It does not close it: the policy stays that no fork or Dependabot pull request is added to the merge queue, and theci-devcopies of the pipelines gain the guards only whenci-devis next pushed from amaster-based branch that carries them.Pipelines, allowed events and refs
pipeline-full.yml:push,workflow_dispatch,pull_request;refs/heads/master,refs/heads/ci-dev,refs/pull/*/merge(caller: push to master, dispatch withfull: true,ci:fulllabel)pipeline-nightly.yml:schedule,workflow_dispatch;refs/heads/masterpipeline-tidy-sweep.yml:workflow_dispatch;refs/heads/masterpipeline-release-module.yml,gate-cpanel-smoke.yml,gate-iis-msi-upgrade.yml:push,workflow_dispatch;refs/tags/*,refs/heads/master(dry runs)Gate
The workflow-shape gate has a rule
event-guard: the job text and both lists are pinned per pipeline, and every fleet job must reach the job throughneeds. Job keys (if,needs,runs-on,continue-on-error,uses) match quoted or with whitespace before the colon. Each job'sif:is normalised (multi-line forms joined, a plain value continuing on every line indented more than its key, a#-led line in a block scalar kept as content; lowercased, whitespace collapsed, the space before a function's(removed). For every job on aneedspath between the guard and a fleet job (and fleet jobs whoseif:the routing-guard rule does not pin), anif:that containsalways(,failure(,cancelled(,success((unless the wholeif:is a baresuccess()),||,!(any negation,!=included) or== falsemust be exactlyneeds.event-guard.result == 'success' && (<inner>), with<inner>one balanced parenthesised group that does not mentionevent-guard; the job must needevent-guard, and a block scalar holding the condition must strip its final newline. Otherwise the gate rejects the job by name. This also rejects some safe forms, such asneeds.event-guard.result != 'failure'. Any otherif:is accepted as today (GitHub addssuccess()implicitly unless the expression names a status function). The gate also refuses YAML anchors and aliases on a job or a job-level key other thansteps:andenv:, and any<<:merge key, since it cannot resolve them. The release lane's fan-in jobs and hosted twins on the vendor, linux, nginx, el8 and el10 paths now needevent-guardand carry their conditions in that form.Landing order
Stacked on the queue fork guard branch (
ci/queue-fork-guard); lands after that PR. These pipelines cannot be exercised on the dev ref; they are validated by the next push run, nightly, a release dry run and a dispatch of each gate workflow.