Skip to content

ci: cut the per-push job fan-out that queues CI behind the runner limit - #1508

Merged
Makisuo merged 1 commit into
mainfrom
ci/trim-runner-fanout
Oct 15, 2026
Merged

Makisuo merged 1 commit into
mainfrom
ci/trim-runner-fanout

Conversation

@Makisuo

@Makisuo Makisuo commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Why

CI's own traces show the slowness is runner contention, not slow jobs. Over the last week CI jobs spent ~13,000 min queued vs ~4,600 min running. Run p50 is ~5 min, but p95 is ~31 min, and nearly all of that is jobs waiting for a runner (p95 queue 15-20 min). A single CI run starts ~17-25 jobs, about the org's concurrency limit. CodeQL starts at the same moment and adds 5 more.

This PR removes jobs that cost a runner slot each but rarely do useful work.

Changes

CodeQL: path-filter the non-JS languages on PRs (codeql.yml)

  • Rust (~6 min/push, 22 files in apps/ingest), Go (14 files), Python (8 files) and Actions ran on every PR push. Over the week that was ~860 runner-min.
  • On pull_request they now run only when their paths change. Main pushes, the weekly schedule and manual dispatch still analyze every language, so the base-branch results stay current. JS/TS is unchanged and runs on every event.
  • The matrix is built in Detect changes from paths-filter's changes output. Swift keeps its existing gate.
  • No Analyze (...) check is required (main has no protection or rulesets), so a leg that is never created can't leave a PR stuck pending. Like Swift today, the code-scanning check may note that some configurations are missing on a PR that skips them.

Test lanes: 12 → 10 (plan-tests.py, run-tests.py)

  • small-6 did ~2s of test work and bun-1 ~7s, yet each paid ~30s setup plus a queue slot.
  • The default per-file estimate goes from 1s to 0.6s, fitted to the slowest cold runs (turbo caches test results, so medians understate). Small-suite lanes were estimated at ~138s but never exceeded 86s.
  • Bun suites now pack into the small lanes. Each lane lists them in bun-filters. run-tests.py runs them in a second Turbo invocation without the Vitest flags, which bun test rejects. Both invocations run even if the first fails. The 240s lane budget still covers the whole lane.

Verification

  • python3 -m unittest discover -s .github/scripts -p 'test_plan_tests.py': 8 pass, including a new mixed-lane runner test that fails if the second invocation is skipped after a failure.
  • Dry-ran the CodeQL matrix jq for the PR-no-changes, PR-rust-changed and push cases.
  • Not verified until this PR runs: the CodeQL matrix on a real runner, and whether small-2 (@maple/api + @maple/cli, cold estimate ~138s) stays under the 240s budget. Watch its job summary line.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

Summary by CodeRabbit

  • Chores
    • CI test lanes now run Bun-native and Vitest suites together where applicable, while keeping their test commands and arguments separate.
    • Scheduled test commands continue running after failures, and CI reports the first failure or a test-budget overrun.
    • CodeQL analysis now selects languages based on changed paths for supported languages; JavaScript and TypeScript analysis runs on every event.
  • Documentation
    • Updated CI performance guidance with revised test-time estimates and lane details.

CI jobs spent ~13,000 min queued against ~4,600 min running over the last
week: one CI run starts ~17-25 jobs, about the org's concurrency limit.

- CodeQL: on pull requests, analyze Rust, Go, Python and Actions only when
  their paths change. Main pushes and the weekly schedule still analyze
  every language. Removes up to four jobs (Rust alone is ~6 min) from most
  PR pushes.
- Test lanes: refit the default per-file estimate to measured cold runs
  (0.6s, was 1s) and let Bun suites pack into the small Vitest lanes, run
  in their own Turbo invocation without Vitest flags. 12 lanes become 10;
  the dropped two did 2s and 7s of test work each.
@maple-review-bot

maple-review-bot Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Maple review

🟢 Confidence 9/10 · safe to merge
Ran the new matrix jq for empty, one- and four-language change sets; the legs match the description and no other job behaviour changed.
quality 100/100 · no findings · tests not needed · risk low

Path-filters CodeQL's Rust/Go/Python/Actions legs on PRs and packs the Bun suites into the existing test lanes, to cut the per-push job fan-out. The workflow change reproduces the removed five-language matrix on every non-PR event, so it is safe to merge.

  • codeql.yml builds the analyze matrix from paths-filter's changes output
  • PRs analyze Rust/Go/Python/Actions only when their paths change
  • Push, schedule and dispatch keep the previous five-language matrix
  • Bun suites pack into the small test lanes via a second Turbo invocation

Before merge

  • Manual · Confirm no ruleset or merge protection requires an Analyze (...) check a skipping PR would leave pending
What was checked
  • Ran the matrix jq for [], ["python"], ["rust"] and all four: JS/TS is always emitted (codeql.yml:77-86)
  • Filters match real files: git ls-files counts 22 .rs, 14 .go, 8 .py (codeql.yml:52-66)
  • Non-PR events force exactly the five languages the removed static matrix ran (codeql.yml:74-99)

5f64e26 · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8a94a348-2b32-4662-9d32-e46ea6f9d20d
📥 Commits

Reviewing files that changed from the base of the PR and between 160fdbd and 5f64e26.

📒 Files selected for processing: 5
  • .github/scripts/plan-tests.py
  • .github/scripts/run-tests.py
  • .github/scripts/test_plan_tests.py
  • .github/workflows/codeql.yml
  • docs/ci-performance.md

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.

📝 Walkthrough

The test planner now packs Bun suites with small Vitest suites and tracks their filters separately. The runner executes each group with the appropriate arguments. The CodeQL workflow now generates its analysis matrix from changed paths on pull requests.

Changes: Test Lane Planning and Execution

Layer / File(s) Summary
Pack Vitest and Bun suites
.github/scripts/plan-tests.py, .github/scripts/test_plan_tests.py
The planner uses a 0.6-second-per-file default and packs Bun suites with small Vitest suites. Each lane records Bun suites in bun-filters. Tests check lane coverage and mixed-suite packing.
Run mixed lanes
.github/scripts/run-tests.py, .github/scripts/test_plan_tests.py, docs/ci-performance.md
The runner executes Vitest and Bun filters in separate commands. It passes lane arguments only to the Vitest command, continues after command failures, and reports a nonzero status or the time-budget failure. Tests and documentation describe this behavior and the updated planner estimates.

CodeQL Language Matrix

Layer / File(s) Summary
Generate the CodeQL matrix
.github/workflows/codeql.yml
The workflow filters Rust, Go, Python, and Actions analysis by changed paths on pull requests. It always includes JavaScript/TypeScript and uses the generated matrix in the analysis job.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Other

Suggested reviewers: jeremyfunk

Merge Risk: ⚪ Minimal · up to 5f64e

The CI changes appear ready to merge after normal checks. Real-runner timing and CodeQL execution remain to be observed, but no concrete blocker was found.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 3 files. (2 skipped: 2… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly summarizes the primary change: reducing per-push CI job fan-out to limit runner contention. It is concise and directly related to the changeset.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 3 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Makisuo
Makisuo merged commit e0569dd into main Oct 15, 2026
40 checks passed
@Makisuo
Makisuo deleted the ci/trim-runner-fanout branch October 15, 2026 23:18
@maple-review-bot

Copy link
Copy Markdown

Merged with 1 step from "Before merge" still open. If it is done, tick it on the review comment; if not, now is the time.

  • Manual · Confirm no ruleset or merge protection requires an Analyze (...) check a skipping PR would leave pending

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