Repository navigation
Split unit-test.yml's Run tests step into one step per suite - #2588
Merged
Merged
Conversation
The combined `npm run test:unit:all` step chained main, apitests, resources, and lmdb behind one 15-minute timeout: a hang or timeout in any one suite killed the step and skipped every later suite, with no way to tell from the checks list which suite actually died. Give each suite its own named step with its own timeout, sized off measured Node 22 durations (the slowest leg, ~9-10m combined across three recent runs). The three later steps run whenever Setup Harper succeeded, regardless of an earlier suite's outcome, so one bad suite doesn't suppress the others' results — but they still skip on cancellation or on a setup failure, since a skipped step's outcome is never 'success'. Fixes harper#2587. Also addresses harper#2017 (same structural cause from the failure side). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BHWm1JSfHJeQju7R7fPKyc
Contributor
|
Note Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported. |
kriszyp
marked this pull request as ready for review
September 14, 2026 16:50
github-actions
Bot
requested review from
Ethan-Arrowood,
cb1kenobi and
heskew
September 14, 2026 16:50
Contributor
|
Reviewed; no blockers found. |
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.
Summary
The
unit-testjob'sRun testsstep chainednpm run test:unit:all(main && apitests && resources && lmdb) behind one 15-minute timeout (unit-test.yml:87-89 onmain). A hang or timeout in any one suite killed the step, so every later suite was silently skipped and the checks list gave no way to tell which suite actually died.This splits it into one named step per suite, each with its own timeout. The three later steps run whenever
Setup Harpersucceeded, regardless of an earlier suite's outcome, so one bad suite no longer suppresses the others — but they still skip on cancellation or on any setup failure upstream, since a skipped step'soutcomeis never'success'.Per-step timeouts are sized off measured Node 22 durations (the slowest matrix leg), taken from three recent runs' logs (main's most recent green run plus the two branch runs referenced in the issue): main ~2m15-2m30 → 4m cap, apitests ~20-25s → 3m cap, resources ~4m30-5m25 → 7m cap, lmdb ~1m55-2m05 → 4m cap.
For the human reviewer
Five rounds of cross-model review (codex + gemini + cursor-composer + harper-domain) surfaced and fixed a real gap — the continuation guard originally used bare
if: always(), which also fires on job cancellation and on any setup failure, not just a test-suite failure. All four suite steps now gate onif: "!cancelled() && steps.setup-harper.outcome == 'success'"instead, so they skip cleanly when setup itself is broken or the run is cancelled.Two findings kept resurfacing that I'm deliberately not fixing, because the fix conflicts with this task's acceptance criteria (harper#2587 explicitly says don't touch the job-level
timeout-minutes):Run testsstep's timeout (15m) could be "wasted" by a wedge, capping the worst case at 26 (setup steps) + 15 = 41 against the 45-minute job cap. Now that later suites run regardless of an earlier suite's failure, the pathological case — every suite independently maxing its own cap — sums to 26 + 18 = 44, one minute under the job cap. If that's ever hit, the job reportscancelled(grey) instead of a stepfailure(red) on a required check, which is exactly the outcome the job's own top-comment says the per-step caps exist to avoid. The reviewers' fix is to raisetimeout-minutesto 48-50; the issue explicitly rules that out. I considered shrinking the suite caps further instead, but that just relocates the same false-timeout risk onto whichever suite gets squeezed (see next point) — there's no way to both keep per-suite caps "generous" and restore the old margin under a fixed 45-minute ceiling, sincetest:unit:resourcesalone needs at least ~6-7 minutes to safely cover its own measured tail.test:unit:resources's 7-minute cap has the thinnest headroom of the four (~29% over its measured 5m25 max, vs 60-620% on the others). I sized it off three data points that were fairly consistent (4m33s-5m25s); widening it further would need to come from somewhere else in the 44-minute budget, reopening the point above.One more open item: the workflow now hardcodes the four-suite list inline instead of just invoking
npm run test:unit:all, so nothing reconciles the two ifpackage.json:73ever grows a fifth suite. That's inherent to giving each suite its own step/timeout/name — happy to add a comment pointer or a lint check in a follow-up if that's wanted.Also worth noting:
test:unit:lmdbitself still chains its three sub-runs (resources/apitests/bin under the LMDB engine) with&&, so a failure in the first still hides the other two — the comment above the steps calls this out. Splitting further wasn't in scope: the issue's own suite list treatslmdbas one of the four suites, matchingtest:unit:all's definition inpackage.json:74.Verification
package.json'stest:unit:*scripts to confirm the four steps preservetest:unit:all's exact suite set and order.gh run view --log) to size each step's timeout off measured data rather than guesswork.python3 -c "import yaml; yaml.safe_load(...)"and formatting withnpx prettier --check.timeout-minutes: 45unchanged.workflow_dispatch— draft PR pushes to this branch, so the PR's own Node 22/24/26 checks are the first real-world exercise of the split; will watch those once pushed.Refs #2587 (and harper#2017, same structural cause from the failure side).
🤖 Generated with Claude Code
https://claude.ai/code/session_01BHWm1JSfHJeQju7R7fPKyc
Review-Coverage: authored=claude; ran=gemini,cursor-composer,codex; adjudicated=domain; declined=cursor-grok; rounds=5; full=1 @ 6cc1b39
Human-Review-Need: 3 (decisions: suite-split-granularity, continue-after-suite-failure, ci-suite-list-location, cap-sizing-policy) @ 6cc1b39