Repository navigation
Cut merge-group CI from ~46 to ~20 min: shard Gradle e2e and test legs, skip test-release in queue, cancel orphaned runs - #1133
Merged
Conversation
The merge-group CI run took ~46 min, and its critical path was the four Gradle capstone legs: each ran the agent suites plus all 43 hosted real-Gradle tests serially (~31 min of test time per leg). - Split each line's agent+hosted leg into three: the agent suites plus gradle_hosted_[345], gradle_hosted_[b-p], and a catch-all that runs gradle_hosted_ with --skip on exactly those words, so a new test always lands in some leg. test_ci_gradle_prefixes.py's HostedShards checks that every hosted test runs in exactly one leg per line and that the catch-all's skip list matches the other legs. - Drop needs: [test, coverage] from yarn-classic-matrix, yarn-berry-e2e, cargo-old-toolchains and cargo-vex-matrix (which keeps e2e-build). They consume nothing from those jobs and started only after the ~31 min windows test leg. Draft skipping is unchanged: the yarn jobs never run on pull_request, cargo-old-toolchains has its own draft guard, and e2e-build gates cargo-vex-matrix. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Dropping `needs: [test, coverage]` from yarn-classic-matrix, yarn-berry-e2e and cargo-old-toolchains also dropped the draft skip they inherited from those jobs, so draft pushes started compiling and running every leg. Gate them on `github.event.pull_request.draft != true` like the other top-level jobs; push, merge_group and schedule events have no pull_request payload and still run them. Co-Authored-By: Claude <noreply@anthropic.com>
Collaborator
Author
|
bugbot run Generated by Claude Code |
…haned merge-group runs - test (macOS / Windows): two legs per OS via scripts/ci-test-shard.py. The Windows leg spent ~10 min linking ~240 test binaries and ~15 min running them in one job (~31 min, the next critical path once the Gradle legs are sharded). Shard 1 runs the unit tests, doctests and a third of the integration targets; shard 2 the rest. The shards together run exactly the old cargo test --workspace selection (test_ci_test_shard.py), and a renamed target fails loudly. - test-release: skipped on merge_group. Every PR already ran it on its head, and it still runs on main after each merge; in the queue it re-spent ~30 min (23 compiling) per entry. ci-ok counts skipped as passing. - merge-queue-janitor.yml: on each merge group, cancel queued or running merge-group runs whose gh-readonly-queue ref was deleted (the queue rebuilt or dropped that entry). Only a definite 404 cancels; it never fails the merge group. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Tanmay Singla (Tanmay182003)
approved these changes
Oct 8, 2026
This was referenced Oct 8, 2026
Collaborator
Author
|
bugbot run Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit a1f2d34. Configure here.
Collaborator
Author
|
Ready for review (burn-down agent).
Already approved. Note #1143 is stacked on this branch. Generated by Claude Code |
Mikola Lysenko (mikolalysenko)
pushed a commit
that referenced
this pull request
Oct 8, 2026
Conflicts in ci.yml only: kept main's (#1133) ungated yarn/cargo matrices and draft gate comments, and re-applied this branch's `needs: clippy` preflight on top. Co-Authored-By: Claude <noreply@anthropic.com>
This was referenced Oct 8, 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-group CI takes ~46 min per entry (#1032's run 37777175251: 12:29→13:15Z; #768's and #1050's runs took about the same), and that sets how fast the merge queue lands PRs. Job timings from that run:
test)Within a Gradle leg,
e2e_redirect_gradle_buildalone took 31 min: 43 hosted tests, each a real Gradle build (~2–3 min apiece).What
Shard the hosted Gradle suite. Each Gradle line's single agent+hosted leg becomes three:
gradle_hosted_[345]*(~10 hosted tests)gradle_hosted_[b-p]*(~16)gradle_hosted_with--skipon exactly the words above (~17), so a newly added test always runs somewhere.The new
HostedShardstests inscripts/tests/test_ci_gradle_prefixes.pyparse the real suite source. For each line they check that every hosted test runs in exactly one leg, and that the catch-all's skip list equals the other legs' words.test_ci_e2e_tiers.py's pinned row table is updated (9 → 17 Gradle rows). Coverage is unchanged: same tests, same Gradle lines, all on ubuntu.Drop
needs: [test, coverage]fromyarn-classic-matrix,yarn-berry-e2e,cargo-old-toolchainsandcargo-vex-matrix(which keepse2e-buildfor its binaries). They consume nothing from those jobs, so they were just waiting ~31 min on the Windows test leg. Those jobs used to inherit the draft skip throughneeds, so 09aded0 gives them their ownif: github.event.pull_request.draft != true(my first push missed this).Shard the
testlegs (macOS + Windows), two per OS, using the newscripts/ci-test-shard.py. The Windows leg spent ~10 min linking ~240 test binaries and ~15 min running them. Shard 1 runs the unit tests, the doctests and a third of the integration targets (fromcargo metadata); shard 2 runs the rest.scripts/tests/test_ci_test_shard.pychecks that the shards together run exactly the oldcargo test --workspaceselection, with no target dropped or doubled. A renamed target fails loudly (--test <missing>is a cargo error). macOS shards run only on main, the queue and nightly, as before.test-releaseskipsmerge_group. Every PR already runs it on its head, and it still runs on main after each merge. In the queue it re-spent ~30 min (23 of them compiling) per entry.ci-okcounts a skipped job as passing.New
merge-queue-janitor.yml. On each merge-group event it cancels queued or running merge-group runs whosegh-readonly-queue/...ref has been deleted, because the queue rebuilt or dropped that entry. Those runs can never merge but kept burning ~200 jobs each, macOS included. Only a definite HTTP 404 on the ref cancels a run; any other lookup error leaves it alone. It is not a required check and never fails. A dry run against the live queue correctly saw the four current entries as live.Expected: per merge-group entry, about 46 → ~20 min. The Gradle legs come down to ~23 min, the test legs to ~15–18 min, and
test-releaseis gone from the queue path. The cost is more ubuntu/Windows jobs per run (~1–5 min setup each). Doubling the macOStestlegs adds ~5 macOS runner-min per main/queue run, which the janitor more than pays back by killing orphans.Validation
python3 -m unittest discover -s scripts/tests: 264 tests OK. I checkedcargo test --workspace --test <cli target> --test <core target>selects across packages and that--docruns cleanly. Both workflow files parse with no duplicate keys. The YAML parses with 17 Gradle e2e rows and the intendedneeds.🤖 Generated with Claude Code
Note
Medium Risk
CI-only changes that alter which tests run when (merge queue vs PR) and how Gradle/test filters partition work; mistakes could miss tests or block merges until caught by the new shard/prefix tests.
Overview
Shortens merge-queue CI by parallelizing the slowest legs and dropping redundant work, targeting roughly 46 → ~20 min per queue entry.
test(macOS/Windows) now runs two shards per OS viascripts/ci-test-shard.pyinstead of one serialcargo test --workspace; shard 1 carries unit tests, doctests, and a lighter share of integration targets.test-releaseis skipped onmerge_group(still on PRs and main) because the queue was re-running the same ~30 min release compile.Gradle hosted e2e splits from one leg per Gradle line into three parallel legs (named
gradle_hosted_*filters plus a catch-all with--skip), withHostedShards/ tier tests guarding full coverage.Job graph:
yarn-classic-matrix,yarn-berry-e2e, andcargo-old-toolchainsno longerneeds: [test, coverage];cargo-vex-matrixonly needse2e-build. Each gets an explicit draftifwhere needed.New
merge-queue-janitor.ymlcancels in-flightmerge_groupworkflow runs whosegh-readonly-queue/...branch ref is gone (404), so orphaned ~200-job runs stop burning runners.Reviewed by Cursor Bugbot for commit a1f2d34. Configure here.
Generated by Claude Code