CI: split the Windows integration tests over two runners; retry flaky GPU tests

nextest --partition splits the integration tests in two, so Windows runs three legs: on the
Windows runner (EPYC 7763, 2 runs) the integration halves took 9.8 and 10.8 min against 13.8 for
one, leaving the unit leg (~12.8) as the longest.

A ci nextest profile retries the GPU tests: on WARP, under load, one hit wgpu's poll timeout once
in ~40 runs while measuring. A test that passes on retry is reported as FLAKY.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Ivan
2026-10-11 10:06:39 +03:00
co-authored by Claude Opus 5.5
parent 60d682d65d
commit 110d58bea9
2 changed files with 25 additions and 14 deletions
+18 -14
View File
@@ -56,10 +56,12 @@ jobs:
run: |
# No macOS on PRs or main: the org's 5 macOS slots are kept for release builds, and
# release.yml builds and tests macOS (a failing release is fixed and rebuilt).
# Windows tests run as two legs in parallel (unit tests, integration tests): together they
# took ~28 min on the Windows runner, each leg takes ~18.
# Windows tests run as three legs in parallel: the unit tests, and the integration tests
# split in two (nextest --partition). As one job they took ~28 min on the Windows runner;
# the legs take ~13, ~10 and ~11.
linux='{"os":"ubuntu-latest","part":"all"}'
all="[$linux,{\"os\":\"windows-latest\",\"part\":\"unit\"},{\"os\":\"windows-latest\",\"part\":\"integration\"}]"
win() { printf '{"os":"windows-latest","part":"%s"}' "$1"; }
all="[$linux,$(win unit),$(win integration-1),$(win integration-2)]"
if [ "$EVENT" != pull_request ] || [ "$FULL" = true ]; then
echo "legs=$all" >> "$GITHUB_OUTPUT"
echo "web=true" >> "$GITHUB_OUTPUT"
@@ -114,11 +116,11 @@ jobs:
# Only main saves caches; PRs restore main's. Every PR used to save its own set (up to
# 3.8 GB), usable by that PR only, so the repo's 10 GB cache budget kept evicting main's.
# A failing test still saves: the cache holds compiled dependencies, not test results.
# The two Windows legs share one key (same dependencies); the integration leg saves it,
# The Windows legs share one key (same dependencies); the integration-2 leg saves it,
# because it also runs Clippy and so leaves Clippy's dependency metadata in it.
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' && matrix.part != 'unit' }}
save-if: ${{ github.ref == 'refs/heads/main' && (matrix.part == 'all' || matrix.part == 'integration-2') }}
cache-on-failure: true
# sccache caches the workspace crates' compiled libraries, which rust-cache leaves out:
@@ -156,31 +158,33 @@ jobs:
# never run (Clippy's `--all-targets` still checks they compile). nextest skips doctests, so
# they get their own step.
#
# On Windows the unit leg runs `--lib --bins` and the integration leg `--test '*'` (every
# integration-test target); the feature selection stays the same, so both legs share the
# dependency cache.
# On Windows the unit leg runs `--lib --bins` and the integration legs `--test '*'` (every
# integration-test target), half of the tests each; the feature selection stays the same, so
# all legs share the dependency cache. The `ci` profile retries the GPU tests
# (.config/nextest.toml).
- name: Test
env:
PART: ${{ matrix.part }}
run: |
case "$PART" in
unit) targets=(--lib --bins) ;;
integration) targets=(--test '*') ;;
integration-1) targets=(--test '*' --partition count:1/2) ;;
integration-2) targets=(--test '*' --partition count:2/2) ;;
*) targets=(--lib --bins --tests) ;;
esac
cargo nextest run --workspace --locked --features heif "${targets[@]}" --no-fail-fast
cargo nextest run --profile ci --workspace --locked --features heif "${targets[@]}" --no-fail-fast
shell: bash
- name: Doctests
if: matrix.part != 'integration'
if: matrix.part == 'all' || matrix.part == 'unit'
run: cargo test --workspace --locked --features heif --doc
- name: Clippy
if: matrix.part != 'unit'
if: matrix.part == 'all' || matrix.part == 'integration-2'
run: cargo clippy --workspace --all-targets --locked --features heif -- -D warnings
- name: Dependency layering
if: matrix.part != 'unit'
if: matrix.part == 'all' || matrix.part == 'integration-2'
run: cargo xtask layers
# docs/scorecard.md must match its sources (checklists, budgets, baseline, corpus floors,
@@ -246,7 +250,7 @@ jobs:
env:
CRAFT_FONTS_DIR: ${{ github.workspace }}/craft-fonts
CRAFT_FONTS_REQUIRED: "1"
run: cargo nextest run --workspace --locked --features heif --lib --bins --tests --no-fail-fast
run: cargo nextest run --profile ci --workspace --locked --features heif --lib --bins --tests --no-fail-fast
corpus:
# Real-file corpus tests (cargo feature `corpus`), on every PR and on main. The corpora are