Repository navigation
ci: let the merge queue take a pull request run of the same tree (needs opt-in) - #255
Merged
Merged
Conversation
The merge queue built, tested and booted every pull request again even when a run at the pull request's head had just done so for an identical tree: run 40616429413 for #249 had the same build key and the same full tree as its queue commit, and the queue spent another 12 minutes on it. In a merge queue run only, lookup-build.py now also accepts a pull request run's packages and verification when the run is kernel CI on a pull request event in this repository at the head the queue merges (the queue commit's second parent, approved after its last push), passed at its first attempt and was never re-run, has exactly one live package and one live verification artifact for the key, and its verification record names a merge commit whose tree is the queue commit's tree, CI files and expected results included. The package job downloads that exact package artifact by its ID. The queue uploads no reusable package, metadata or verification record on this path, so the push after the merge still trusts only the branch and the queue. Anything missing, ambiguous or unreadable leaves the usual lookup. This changes what the required check attests for those pull requests: the record is the pull request run's own word, not authenticated per job or per package, and the trusted build moves to the push after the merge. Signed-off-by: Marcelo Alcantara <maralc@gmail.com>
When the merge queue takes a pull request run's results, the push after the merge takes the usual lookup, so it builds and tests only what no branch or queue run already has for the key. Signed-off-by: Marcelo Alcantara <maralc@gmail.com>
A run "at the head being merged" proved less than it seemed. Anyone who can push a branch can open a second pull request from the same head onto a branch of their own, whose workflows GitHub then runs on the merge. That run has the same head, so it passed every check, and it could upload a verification record claiming any commit with the queue's tree. Take the pull request number from the queue ref, and use what GitHub recorded for the run instead of what the run says about itself: exactly one call of kernel-ci-jobs.yml, made from the run's own workflow file (ref refs/pull/<number>/merge, path ending in the commit it ran), whose commit has exactly the queue commit's tree. The record must name that commit. A call to another ref, commit or repository keeps that target in its path and does not count. Also fall back to the usual lookup on a truncated API response (http.client.HTTPException), which escaped the handler before. Signed-off-by: Marcelo Alcantara <maralc@gmail.com>
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.
Policy change. It changes what
ci / resultattests in the merge queue for some pull requests, and it reverses the README's rule that no pull request run is a source of results. Merged by a maintainer after the end-to-end test below; @chriskearney FYI, and a revert restores full queue builds. Separate from #254 (the safe speed-ups), which it doesn't depend on.Merge precondition (met 2026-10-28): a scratch-repo probe of GitHub's
referenced_workflowsencoding (see Evidence) showed that only a local call is recorded asref: refs/pull/<N>/mergewithpath: …@<sha>, and always for the run's own PR. Remote, pinned, nested and attack-shaped calls were all rejected. An independent review rates this safe to merge.Summary
The merge queue builds, KUnit-tests and boots every pull request again, even when that pull request's own run just did all of it for the identical tree. For #249, PR run 40616429413 and queue run 40621870017 had the same build key and the same full tree (
2caf83b9…). The queue still spent package 9m24s + boot 1m57s on its critical path, plus KUnit, on Namespace.The commit comes from GitHub's own record of the run (
referenced_workflows), not from the run's self-reportedverified.json. A run of the same head in another pull request (say, onto a branch with tampered workflows) recordsrefs/pull/<other>/merge. A retargeted run records a merge commit with the other base's CI, so its tree differs. Full-tree equality covers.github,tools/aurora-ciand the expected-results files, so a base change in CI files alone means a full build. A later queue entry carries the entries ahead of it, so its tree normally differs and it builds.What this accepts
kernel-verified-<key>, or which package bytes it verified. Any code at the reviewed head that ran in that run (host suites, kernel build scripts) could have written them.refs/pull/<N>/mergefor forks too.A 72-hour cap on the age of a reused PR run would bound drift; it's a follow-up, not a fix for forgery.
Evidence
Lookup against the real drm/asahi: g15: t6031: build the J516C board data without a board file #249 queue commit
e3ffe88, read-only: PR drm/asahi: g15: t6031: build the J516C board data without a board file #249 →('40616429413', '12787597313')in 3.9 s (12787597313is that run's onlykernel-package-3b408bd…). The same evidence for PR soc: apple: sep: publish catacomb files by atomic replacement #250 →('', '').145 unit tests pass (7 package-inspection tests skip locally), actionlint clean,
check-commits.pyclean, CI self-test (incl. zizmor) green.New tests reject:
pull_request_target; other repository; missing, expired or duplicate packages; an incomplete run listing.[],null.IncompleteRead) and every other lookup error fall back to the usual lookup.Mutation check: dropping the
refcomparison fails the side-PR and pinned-commit cases.GitHub's run record, probed in a private scratch repo (
maralcbr/refwf-probe, 64 runs; available on request):mainand onto an attacker-controlledsidebranch../…, also when skipped (if: false)ref: refs/pull/<N>/merge,path: …@<merge sha>; the job'sGITHUB_SHAis that sha@<sha>, also when skippedpath: …@<sha>, noref@mainref: refs/heads/main,path: …@main@refs/heads/main,@refs/pull/1/mergeor@pull/1/merge, directly or nestedpath: …@<PR 1 merge>, norefEnd to end in a real merge queue: a scratch copy,
omacom/linux-aurora-ci-scratch(deleted after the test; run IDs below are from it), with this PR and ci: stop the plan job fetching the kernel's history; split the host tests #254 onintegration/aurora. It uses the same ruleset except approvals, the same Namespace profile, and scratch PRs with a comment-only kernel change:kernel-ci.ymlrun on the current baseci:buildlabel run (kernel-ci-label.yml)pull_request_runempty)compile-1anddevicetree-1, with no package, verification or metadata.Not run: a fork PR end to end. The record shape for a fork PR is the one checked on drm/asahi: g15: t6031: build the J516C board data without a board file #249 above.
Timings, from #249:
When it doesn't apply (later queue entries, CI-only base moves, no full run of the PR at its head), the queue builds as with #254.
Merge Danger
Door: two-way
Revert restores full queue builds. Packages and records taken while it was live were never re-uploaded as trusted, so nothing lingers.
Blast Radius: merge-gate
A bad kernel could pass the queue on PR-run evidence and fail only on the push after merge.
Safety review: an independent review found that a writer could forge evidence through a second PR from the same head onto a branch of their own. That's fixed in
5e17ebcby binding to GitHub's record of the run, and the scratch-repo probe found no way around that binding.