Summary
The test-polars py3.12 cell is at its wall-clock ceiling. It is the only cell in the matrix that runs coverage, and it shares one timeout-minutes with five siblings that do half its work. Adding a single test file to bin/test-polars.sh is now enough to push it over, and when it goes over GitHub reports the job as cancelled — which reads as unrelated fail-fast collateral, not as a budget failure.
This is a structural capacity limit, not a one-off. It will re-fire on the next polars test addition.
Evidence
On PR #1794 (which appends one file to POLARS_TEST_FILES), test-polars (3.12) failed twice with zero test failures:
| attempt |
duration |
outcome |
| 2 |
10m15s |
cancelled |
| 3 |
10m11s |
cancelled |
Job log, attempt 3:
2377 passed, 13 skipped ... in 572.43s (0:09:32)
The operation was canceled.
The pytest phase alone was 9m32s of a 10m job budget. Siblings (3.9/3.10/3.11/3.13/3.14) finish in 4m09s–5m51s. A rerun does not clear it — it is 0-for-2.
Two things made this expensive to diagnose:
- A timed-out job is reported as
cancelled, indistinguishable at a glance from fail-fast collateral. The distinguishing evidence is the duration: a fail-fast cancel lands seconds after a sibling failure; a timeout lands at exactly timeout-minutes. Attempt 2 was 1 cancelled / 72 success / 1 skipped, so collateral was ruled out by evidence.
changed-line-coverage then reports SKIPPED, because it needs: the job that produces polars-coverage-py3.12. So one budget overrun silently disables a second gate.
Root cause
.github/workflows/ci.yml:
test-polars declares timeout-minutes: 10 for the whole matrix job (was line 1579).
- Only the py3.12 cell runs
Polars tests with coverage (POLARS_COV=1, was line 1618) plus the per-file Polars GFQL coverage audit plus an artifact upload.
So one cell carries roughly double the work of its siblings against a budget sized for the siblings. The timeout is simultaneously too tight for the cell that matters and too loose to be a useful hang detector for the ones that don't.
Fix applied in #1794
Split the coverage pass into its own job, test-polars-coverage (py3.12, timeout-minutes: 20), and drop 3.12 from the test-polars matrix. Net effect:
test-polars cells now do identical work, so its 10-minute budget is a real hang detector again.
- The coverage pass has an explicit, separately visible budget that can grow without cancelling five unrelated cells.
- No python version loses a run: py3.12 was already only running the coverage step, so this is the previous step layout re-homed.
changed-line-coverage needs: updated to include the new job (it consumes that job's artifact).
Note there is no required_status_checks configuration on master (verified via the branches API), so introducing a new check name does not block merges. If required checks are added later, test-polars-coverage should be in the list.
Still open after that fix
The 20 minutes buys headroom, it does not remove the ceiling. The polars lane is:
Candidate follow-ups, roughly in order of value:
- Add
-n auto to the polars pytest invocations (coverage under xdist works via coverage combine; needs pytest-xdist confirmed in the test-polars-* locks).
- Shard
POLARS_TEST_FILES across two coverage cells and combine the two .coverage files before the audit.
- Have the coverage lane report its own wall-clock into the step summary, so approaching the ceiling is visible before it fails.
Acceptance
- A polars test-file addition of typical size does not cancel any CI job.
- A
cancelled polars job is attributable to a real cause, not to a shared budget.
Summary
The
test-polarspy3.12 cell is at its wall-clock ceiling. It is the only cell in the matrix that runs coverage, and it shares onetimeout-minuteswith five siblings that do half its work. Adding a single test file tobin/test-polars.shis now enough to push it over, and when it goes over GitHub reports the job ascancelled— which reads as unrelated fail-fast collateral, not as a budget failure.This is a structural capacity limit, not a one-off. It will re-fire on the next polars test addition.
Evidence
On PR #1794 (which appends one file to
POLARS_TEST_FILES),test-polars (3.12)failed twice with zero test failures:cancelledcancelledJob log, attempt 3:
The pytest phase alone was 9m32s of a 10m job budget. Siblings (3.9/3.10/3.11/3.13/3.14) finish in 4m09s–5m51s. A rerun does not clear it — it is 0-for-2.
Two things made this expensive to diagnose:
cancelled, indistinguishable at a glance from fail-fast collateral. The distinguishing evidence is the duration: a fail-fast cancel lands seconds after a sibling failure; a timeout lands at exactlytimeout-minutes. Attempt 2 was 1 cancelled / 72 success / 1 skipped, so collateral was ruled out by evidence.changed-line-coveragethen reports SKIPPED, because itneeds:the job that producespolars-coverage-py3.12. So one budget overrun silently disables a second gate.Root cause
.github/workflows/ci.yml:test-polarsdeclarestimeout-minutes: 10for the whole matrix job (was line 1579).Polars tests with coverage(POLARS_COV=1, was line 1618) plus the per-filePolars GFQL coverage auditplus an artifact upload.So one cell carries roughly double the work of its siblings against a budget sized for the siblings. The timeout is simultaneously too tight for the cell that matters and too loose to be a useful hang detector for the ones that don't.
Fix applied in #1794
Split the coverage pass into its own job,
test-polars-coverage(py3.12,timeout-minutes: 20), and drop3.12from thetest-polarsmatrix. Net effect:test-polarscells now do identical work, so its 10-minute budget is a real hang detector again.changed-line-coverageneeds:updated to include the new job (it consumes that job's artifact).Note there is no
required_status_checksconfiguration onmaster(verified via the branches API), so introducing a new check name does not block merges. If required checks are added later,test-polars-coverageshould be in the list.Still open after that fix
The 20 minutes buys headroom, it does not remove the ceiling. The polars lane is:
bin/test-polars.shruns plainpython -B -m pytestwith no-n auto, unliketest-gfql-corewhich does use it. This is the single biggest available lever and is not taken.POLARS_TEST_FILESgrows monotonically, and every addition lands on the coverage lane at ~2x cost. Related: test-polars.sh is an allowlist: a new polars test file is silently never run until someone remembers to register it #1795 (new test files not in the allowlist run in no polars lane at all).Candidate follow-ups, roughly in order of value:
-n autoto the polars pytest invocations (coverage under xdist works viacoverage combine; needspytest-xdistconfirmed in thetest-polars-*locks).POLARS_TEST_FILESacross two coverage cells and combine the two.coveragefiles before the audit.Acceptance
cancelledpolars job is attributable to a real cause, not to a shared budget.