From 9a219b414a8146ec89ad3d8653932cc3240ad8b2 Mon Sep 17 00:00:00 2001 From: Hanif Koh Date: Fri, 4 Sep 2026 21:32:23 +0800 Subject: [PATCH] ci: 2 shards instead of 8, from measured cost The 8-way matrix was sized against a model that over-estimated slice cost by ~10x. Run 33877144840 measured 25.8 min of sweep work in total and a 4.8 min longest shard against a predicted 52.9, so the sweep fits the 60-minute timeout with no sharding at all. 2 shards keeps feedback at ~12.5 min instead of ~24, for one extra repeat of the merge and G-code stages. Eight repeats plus eight AppImage downloads bought nothing. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TSynfTLvSnHBbVkRUm56nY --- .github/workflows/cli_overrides.yml | 30 +++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/.github/workflows/cli_overrides.yml b/.github/workflows/cli_overrides.yml index a4e883b7a5..aaa87cc678 100644 --- a/.github/workflows/cli_overrides.yml +++ b/.github/workflows/cli_overrides.yml @@ -33,14 +33,14 @@ jobs: strategy: fail-fast: false matrix: - # The effect stage re-slices every landed option one at a time and cannot - # batch, so it is the whole cost of this job. Un-sharded it is ~6 h on a - # 4-vCPU runner once the option is routed to a fixture that can actually - # show its effect. parity/effect_routing.json groups options by cheapest - # capable fixture and balances the groups by measured slice cost; 8 shards - # puts the longest at ~53 min. Shards are disjoint and cover every landed - # option exactly once. - shard: [0, 1, 2, 3, 4, 5, 6, 7] + # The effect stage re-slices every landed option one at a time and + # cannot batch, so it is the whole cost of this job. + # parity/effect_routing.json groups options by the cheapest fixture that + # can show their effect and splits them into balanced, disjoint shards + # covering every landed option exactly once. Measured at ~12.5 min a + # shard; un-sharded the sweep is ~24 min, so this is about feedback time + # rather than fitting the timeout. + shard: [0, 1] steps: - name: Find the latest successful Linux build id: build @@ -109,7 +109,7 @@ jobs: # passing tests, so without it every "grep override sweep" below # finds nothing and the job summary says "no stage summaries" python -m pytest test_cli_overrides.py -c pytest.ini -v -rA --effect-full \ - --effect-shard ${{ matrix.shard }}/8 \ + --effect-shard ${{ matrix.shard }}/2 \ --orca-bin "$ORCA_BIN" --orca-source "$ORCA_SOURCE" \ 2>&1 | tee ../sweep.log @@ -117,7 +117,7 @@ jobs: if: always() run: | { - echo "## CLI override sweep - shard ${{ matrix.shard }}/8" + echo "## CLI override sweep - shard ${{ matrix.shard }}/2" grep -E "\[override sweep" sweep.log || echo "no stage summaries (see log)" echo grep -E "^(=+ )?[0-9]+ (passed|failed)" sweep.log | tail -1 || true @@ -133,3 +133,13 @@ jobs: sweep.log if-no-files-found: warn retention-days: 30 + + # The sweep step is continue-on-error so the summary and artifact steps + # above still run on a failure - without this the job would then report + # success, and a shard that measured nothing would look identical to a + # healthy one. + - name: Fail the job if the sweep failed + if: steps.run.outcome == 'failure' + run: | + echo "the override sweep failed - see the job summary and the uploaded report" >&2 + exit 1