fix(ci): scope merge-queue runs to the changed subtrees - #574
Merged
Conversation
Every merge-queue entry built all 24 matrix rows regardless of what the pull request touched. detect resolves its diff base from `github.event.before`. That field exists on push events but not on merge_group, so queue entries fell through the case statement's default arm with an empty BEFORE_SHA and set run_all=true. The change-aware scheduling that keeps ordinary pull requests small was inert for exactly the event that gates merging. merge_group carries the queue base as `github.event.merge_group.base_sha`. The queue head is the base plus the queued commits, so diffing from it yields the pull request's own changes, and for a batched entry every pull request in the batch. Measured on two recent queue runs, both 24 rows: the slowest row was 669s and 643s, while wall clock was 885s and 2132s. The difference is rows waiting for a runner, not work. Twelve rows started immediately and the rest waited 26 to 31 minutes, which is runner starvation rather than a max-parallel cap. This does not add capacity; it removes demand, which is the half we control here. Both degraded paths stay on the safe side: a missing base_sha, or one absent from history, falls back to the full matrix rather than selecting nothing. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe Bazel workflow now handles ChangesBazel merge-group scheduling
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
FamousDirector
approved these changes
Jul 30, 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.
Why
Merge queue throughput is the complaint, and the queue was doing far more work
than it needed to: every entry built all 24 matrix rows regardless of what the
pull request changed.
detectresolves its diff base fromgithub.event.before. That field ispopulated on
pushevents but does not exist onmerge_group, so queue entrieshit the case statement's default arm with an empty
BEFORE_SHAand setrun_all=true. The change-aware scheduling that keeps ordinary pull requestssmall was inert for precisely the event that gates merging.
Confirmed from a real queue run's detect log:
Measurements
Two recent
merge_groupruns, both 24 rows:The slowest row is ~650s in both. The gap between an 885s run and a 2132s run
is almost entirely rows queued waiting for a runner. Full queue-wait
distribution for the slow run:
Twelve rows start at once, then a 26-minute cliff. That shape is runner
starvation, not a
max-parallelcap: a binding cap of 8 would produce tiersroughly one row-duration apart, not a bimodal split at 12.
This change adds no capacity. It removes demand, which is the half we control
from inside the repository.
What changed
A
merge_grouparm in the case statement usinggithub.event.merge_group.base_sha. The queue head is the base plus the queuedcommits, so diffing from it yields the pull request's own changes, and for a
batched entry every pull request in that batch.
Testing
Validated by simulating a queue-shaped history against the real repository: a
branch at
origin/mainplus one commit touching a single subtree, run throughthe exact case logic.
Both degraded paths fall back to the full matrix rather than selecting nothing,
so a payload change or a shallow checkout cannot silently skip validation.
This pull request touches the workflow itself, so its own runs select the full
matrix by design. The effect shows on the next queue entry that does not touch
workflow files.
Notes
max-parallelis deliberately left alone. The data above shows it is not thebinding constraint, and it exists to stop ~20 runners pulling
actions/checkoutat once and tripping GitHub's action-download rate limit(HTTP 429 in "Set up job"). Removing it risks trading slow for flaky without
addressing the wait.
The remaining constraint is hosted-runner concurrency at the organisation
level, which cannot be changed from this repository.
References
None
Dependencies
None.
Summary by CodeRabbit