Repository navigation
ci: shard the gauntlet across 5 runners (GH #400) - #403
Merged
Merged
Conversation
GAUNTLET_SHARD=i/N splits hook_test_files() by greedy byte-size bin-packing (largest first) so test-gates.sh and test-subagent-git-guard.sh land on different runners; validate and lint run only in shard 1. Unset keeps today's behaviour. The required 'gauntlet (run-gauntlet.sh)' check becomes an if: always() aggregator that fails unless every shard succeeded. PR runs cancel superseded ones; pushes to develop never cancel.
…let aggregator goes red" This reverts commit 585e20e.
Owner
Author
CI resultsRun 37134095322 (first green run, from
Before: median ~302 s wall (last 10 successful PR runs: 217-308 s). After: 137 s, and 138 s on the green re-run 37134676789. Runner time goes up from about 5.3 min to about 6.9 min per run (setup is repeated on 5 shards). Wall time is what a merge waits on. Red proof: run 37134386190 had a throwaway commit making |
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.
Closes #400.
What
scripts/run-gauntlet.sh:GAUNTLET_SHARD=i/Nruns 1/N of the test files.hook_test_files()splits them by greedy bin-packing on byte size (largest first, each file to the lightest shard, lowest index on a tie), then prints the shard in glob order. Validate and lint run only in shard 1 (others printSKIP). Unset = today's behaviour. The var is read into a plainshardand unset, so test files never see it. A malformed value (3,0/2,3/2,a/2, ...) exits 2 before anything runs..github/workflows/validate.yml: the old gauntlet job becomes a 5-way matrixgauntlet shard N(fail-fast: false, same steps,GAUNTLET_SHARD: ${{ matrix.shard }}/${{ strategy.job-total }}). A newgauntlet (run-gauntlet.sh)job (needsthe matrix,if: always()) fails unlessneeds.gauntlet-shard.result == success, so a failed, cancelled or skipped shard turns it red. Its name is the required context, so branch protection is unchanged.concurrencycancels a superseded run only forpull_request; each push to develop has its own group (the sha).GAUNTLET_JOBSstill defaults to 1 underCI), one runner per shard, so the 8 s timing rows never share a CPU.test-cost-ledger-module.shneedsclaudeand SKIPs without it, and the tests usetrash.Serial timings (this machine, one file at a time, load avg ~5.6)
Total 374 s over 54 files. Heaviest:
Measured seconds per shard under the byte-size split (seconds/files):
N=5:
test-gates.shalone sets the floor (107 s), so more shards buy nothing. Byte size is a rough proxy (test_memory_lint.pyis 65 KB and runs in 0.5 s), but it needs no timing table to keep current.Tests
tests/scripts/test-gauntlet-shard.sh(written first, red on the old script:check_shard() not found): unset lists every test file on disk (found byfind, not the globs); for N=1..6 the shards partition the files exactly, none is empty, each keeps glob order, and test-gates.sh / test-subagent-git-guard.sh are on different shards for N>=2;check_shardaccepts/rejects a table of values.b==i->b!=i, drop the sum update, drop the glob reorder, skip shard 1 in the min search,-le->-lt, drop the lower bound, accept junk, ignore the shard). The survivor is<-><=in the tie pick, which changes which shard gets a file but keeps a valid deterministic partition. That is equivalent behaviour, not a gap.test-run-gauntlet-wiring.sh,test-gauntlet-failed-summary.sh,test-gauntlet-log-preservation.sh,test-gauntlet-git-env-isolation.shpass unchanged.GAUNTLET_SHARD=2/5local run prints SKIP for validate/lint and passes. audit.sh 0 CRIT; full gauntlet green withGAUNTLET_JOBS=2.CI wall time
Before: last 10 successful PR runs took 217-308 s (median ~302 s). After: see the comment on this PR.