Skip to content

ci: bound the test job with timeout-minutes - #455

Merged
cdeust merged 3 commits into
mainfrom
ci/test-job-timeout
Sep 2, 2026
Merged

cdeust merged 3 commits into
mainfrom
ci/test-job-timeout

Conversation

@cdeust

@cdeust cdeust commented Sep 2, 2026 •

Copy link
Copy Markdown
Owner

What

Adds timeout-minutes: 60 to the test job of .github/workflows/ci.yml, which previously inherited GitHub's 360-minute default.

Why

A hung leg holds the whole workflow for hours. The precedent is release run 30741657854 (v4.17.0): FlashRank's timeout-less requests.get stalled in sock.connect until pytest-timeout killed the suite, and nothing bounded the job itself (CHANGELOG 4.17.1). Since issue #392 the release path is gated through this very job (ci-green -> test -> release-gate), so bounding it bounds the release path too.

Source of the constant

Measured 2026-09-03 over the last 12 green main runs of this workflow (gh run list --workflow ci.yml --branch main --status success --limit 12, runs 31417063954 to 33688337476), 48 Test (Python x.y) jobs, duration = completed_at - started_at from gh api repos/cdeust/Cortex/actions/runs/<id>/jobs:

Leg Duration over the 12 runs
Test (Python 3.12), runs the extended checks 15 to 20 min (max 19 min 36 s, run 32747742631)
Test (Python 3.10) 8 to 10 min in 11 runs; 15 min 06 s in run 33688337476
Test (Python 3.11) 8 to 11 min (max 10 min 59 s, run 33678125783)
Test (Python 3.13) 8 to 10 min in 11 runs; 27 min 17 s in run 33688337476

The slowest green leg in the window is therefore Python 3.13 at 27 min 17 s (run 33688337476, c5ec018), not the 3.12 leg. The constant follows the same rule as before, about twice the measured maximum so a slow runner still passes while a stalled job is cut within one ordinary run's wall time: 60 / 27.3 = 2.2. The earlier 45 would have been 1.65x a single passing observation, too thin a margin to keep the stated rule honest.

Not in this PR

The sibling jobs of ci.yml (test-sqlite, test-windows, lint, craftsmanship, typecheck, build, the Docker jobs) still inherit the 360-minute default. Pre-existing, unworsened by this diff, left for a separate change. release.yml has no test job of its own since #392, so there is nothing to bound there.

Review

  • c660d95: fresh-context review APPROVE, with two prose corrections to this description.
  • 018a40e: fresh-context review REQUEST_CHANGES: the comment's "other three legs took 7-11 min" and "3.12 is the slowest leg" were false for the claimed 12-run window (run 33688337476 has 3.13 at 27 min 17 s), and 45 / 27.3 = 1.65, not "about twice". Fixed by the following commit, which re-measures all 48 legs and moves the constant to 60 so the stated rule holds.
  • e159793: fresh-context review APPROVE (48 legs, window, maxima and ratio re-derived via gh api; one cosmetic note on the 8-min floor, true minimum 7 min 38 s).

🤖 Generated with Claude Code

cdeust and others added 3 commits September 3, 2026 00:23
The `test` job inherited GitHub's 360-minute default, so a hung leg
(release run 30741657854: FlashRank's timeout-less `requests.get`,
CHANGELOG 4.17.1) could hold the whole workflow for hours. Measured
2026-09-03 over the last 12 green `main` runs: Test (Python 3.12) took
15-22 min, the other three legs 7-10 min. 45 minutes is about twice the
measured maximum.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
The in-file source comment read "7-10 min" for the three legs without the
extended checks; the measured maximum over the same 12 green main runs is
10 min 59 s (Python 3.11, run 33678125783). Name it, and the slowest-leg
run id, so the constant's provenance is re-derivable from the comment.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
The previous comment claimed the 3.12 leg was the slowest at 22 min 32 s
and the other three legs took 7-11 min. Re-measuring every Test (Python
x.y) job of the last 12 green main runs (48 legs, completed_at minus
started_at) shows run 33688337476 with Python 3.13 at 27 min 17 s and
Python 3.10 at 15 min 06 s, and the 3.12 maximum inside that window at
19 min 36 s. 45 min was 1.65x the true maximum, not "about twice"; 60 min
restores the stated rule (60 / 27.3 = 2.2).

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@cdeust

cdeust commented Sep 2, 2026

Copy link
Copy Markdown
Owner Author

ZETETIC-REVIEW: APPROVE

Fresh-context review of head e159793 (2026-09-03). Independently re-derived via gh api repos/cdeust/Cortex/actions/runs/<id>/jobs: the 12-run green-main window (31417063954..33688337476), all 48 Test (Python x.y) leg durations, the per-leg maxima (3.12 19 min 36 s run 32747742631; 3.11 10 min 59 s run 33678125783; 3.13 27 min 17 s and 3.10 15 min 06 s run 33688337476), and the ratio 60 / 27.28 = 2.2 stated in the # source: comment of .github/workflows/ci.yml. The PR body's per-leg table matches the raw data. One non-blocking cosmetic note: the comment's small-leg floor "8 min" understates the true minimum 7 min 38 s (leg 3.11, run 31417063954); no action required.

@cdeust cdeust mentioned this pull request Sep 2, 2026
@cdeust
cdeust merged commit bec1da8 into main Sep 2, 2026
27 checks passed
@cdeust
cdeust deleted the ci/test-job-timeout branch September 8, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant