Repository navigation
CI perf: ci.yml e2e-macos — 23 one-minute macOS jobs per merge_group/push run (~2,300 macOS job starts/day) #1176
Description
Measurement
Window: 2026-10-01 → 2026-10-08 (jobs sampled: 643 successful e2e-macos legs from merge_group/push/schedule runs).
e2e-macos(ci.yml:1734) is a 23-row matrix, allmacos-latest. It runs on every merge_group run (21.8 legs/run in the sample), every push to main (23/run) and nightly —if: github.event_name != 'pull_request'.- Per leg: run time p50 0.83 min; queue wait p50 1.1 min, p90 20.8 min (macOS pool saturation).
- Last 24h: 115 merge_group CI runs + 26 push runs ⇒ roughly 100 runs/day × 23 = ~2,300 macOS job starts/day for ~9.4 min of actual test work per run.
- Pre-Cut merge-group CI from ~46 to ~20 min: shard Gradle e2e and test legs, skip test-release in queue, cancel orphaned runs #1133 sample: on merge_group runs, 11
e2e (macos-latest, …)legs had finish offset p50 ~45–49 min with queue wait p50 ~20 min / p90 ~50 min against a run time of ~1 min — i.e. the legs were waiting for a mac runner, not testing. Example run: https://github.com/SocketDev/socket-patch/actions/runs/37726213794/job/113147648897 - macOS queue wait across all jobs, last 24h: p50 22.0 min, p90 55.5 min; worst hour 2026-10-07T20 p50 81 min.
Where the time goes (per leg, averaged over 643 legs)
| step | min/leg | share |
|---|---|---|
| Run e2e tests (+ Run vlt e2e tests) | 0.47 | 44% |
| Set up job | 0.15 | 14% |
| Download the e2e binaries | 0.12 | 11% |
| Install Maven 3.9.16 | 0.10 | 10% |
| Checkout | 0.06 | 6% |
| toolchain setup / post steps | ~0.1 | ~15% |
So ~56% of each leg is fixed overhead, and GitHub bills each job rounded up to a whole minute (23 billed macOS minutes per run for ~9.4 min of tests).
Root cause
Each suite × toolchain combination is its own matrix job. That was cheap when macOS legs ran on idle runners; now that the macOS pool (~20 concurrent, shared by every PR push and merge_group run) is the bottleneck, every extra job is another trip through the macOS queue.
Proposed fix
In .github/workflows/ci.yml, collapse e2e-macos from 23 rows to ~3 grouped rows, reusing the existing multi-suite loop in the shared *e2e-steps "Run e2e tests" step (it already iterates for suite in $E2E_SUITE and checks each suite ran ≥1 test):
- JS: e2e_safety_pnpm, e2e_redirect_npm_build, e2e_redirect_rush_sim, e2e_redirect_pnpm_build, bun ×3 (bun 1.4.2), vlt ×5 (vlt 1.2.0).
- Python: e2e_redirect_uv_build, e2e_vendor_pypi_build, e2e_vex_build for poetry/pdm/hatch/pipenv/pip.
- JVM/.NET: e2e_redirect_maven_build, e2e_vendor_maven_build, e2e_vendor_jvm_build (maven_reactor), e2e_nuget_dotnet_build.
Rows that need distinct test_filters per suite need a small extension: allow test_filter per suite (e.g. a suite=filter list, or run the step once per sub-row with a bash loop over a JSON list in the matrix). The vlt legs' separate "Run vlt e2e tests" step and vlt_store_linker: hardlink (e2e_safety_vlt) can stay as an extra step in group 1. Keep fail-fast: false and keep the per-suite ::error:: reporting so a failure still names the suite. e2e-full (same steps) is unaffected.
Expected saving
- macOS job starts: 23 → 3 per run, ~2,000 fewer macOS jobs/day (~100 merge_group+push runs/day).
- macOS job-minutes: ~20 legs × ~0.5 min overhead ≈ ~10 min/run ≈ 1,000 macOS job-min/day actual; billed minutes drop more (per-job rounding: 23 → ~3 roundings).
- Merge-queue critical path: macOS queue contention from these legs is what pushed the mac legs' finish to ~45–49 min p50 pre-Cut merge-group CI from ~46 to ~20 min: shard Gradle e2e and test legs, skip test-release in queue, cancel orphaned runs #1133; with 3 jobs the e2e-macos group needs 3 slots instead of 23. Expected ~5–15 min off merge_group p90 when the mac pool is saturated (to be confirmed post-Cut merge-group CI from ~46 to ~20 min: shard Gradle e2e and test legs, skip test-release in queue, cancel orphaned runs #1133).
- Also cuts macOS queue wait for every other macOS job (PR compat legs on push/nightly, test (macos-latest)).
Coverage and risk
Every suite still runs on macOS on every merge_group, push to main, and nightly — only the job boundaries change. A group's wall time becomes ~4–6 min (still far under the ~24 min merge_group run). Risk: one failing suite marks the whole group red, so the job name no longer pinpoints the suite — mitigated by the existing per-suite ::error:: annotations. Required checks ci-ok / clippy are unchanged (ci-ok already depends on e2e-macos as a job, not on leg names).
Effort
S/M (matrix rewrite + per-suite filter plumbing in the shared step).
ROI
Saving ~1,000 macOS job-min/day + ~2,000 fewer macOS queue entries/day (weighted ×3 for the scarce macOS pool ≈ 3,000 pts) × confidence 0.8 / effort 1.5 ≈ 1600.
Activity
mikolalysenko commentedon Oct 8, 2026
[agent] Shares root cause with #1172, #1178:
ci.ymlgives every suite × toolchain row of thee2e/e2e-macos/e2e-fullmatrices its own job, so per-job setup dominates sub-minute test legs. Will be fixed together. Triaged aspriority:p3(CI-only).Generated by Claude Code
mikolalysenko commentedon Oct 9, 2026
Profiler refresh, 2026-10-09 08:17 UTC (24h window; job detail for 52
CImerge_group runs and 3 push runs)macOS load per run.
e2e-macositself.Run e2e teststook 0.4 min on average over 1,148 jobs (455 min total).Set up jobtook 181 min over the same jobs, ~40% of the test time.Concurrency. With the queue building 5 entries, macOS concurrency peaked at 50 jobs (06:42) and stayed at 40–49 through every wave from 06:26 to 07:53. macOS queue wait is still 0.2 / 1.8 min (p50 / p90), so it is not saturated today.
Why this matters now. This issue is the main thing standing between the queue and a deeper build window (#1248 proposes
max_entries_to_build5 → 8, which would push the peak to ~80 macOS jobs). PR #1234 (one leg per shared toolchain) is in the merge queue now; the next profiler run will measure it.Generated by Claude Code
mikolalysenko commentedon Oct 11, 2026
[agent] Re-verified against origin/main (578b63e) on 2026-10-11: fixed.
e2e-macosnow runs only whenCI_SCOPE=='full', on schedule or on workflow_dispatch (ci.yml:1906), and so doese2e-build-macos(ci.yml:1035). Merge-queue run https://github.com/SocketDev/socket-patch/actions/runs/38099894100 has 0 macOS jobs executed (e2e-macos / e2e-build-macos skipped). Closing as completed.Generated by Claude Code