Repository navigation
Run the full macOS suite on main and nightly, with a one-job macOS gate on PRs into main #893
Description
This was generated by AI during triage.
Every Ticket PR in a Spec run pays the full macOS CI before it can Self-merge into the Spec branch. That gate costs the Ticket about an hour of CI watch, and the same code gets macOS coverage again on the Spec PR anyway.
Evidence
- On PR Add Console Themes, saved look settings and activity motion #870 (Ticket Built-in Themes, the picker and the page's own look #824 of Spec Spec: the Console, a web page for each machine's Commands #776, base
issue-776), Linux CI finished in 9 minutes (12:47 to 12:56 UTC on 2026-10-20). The macOS shards finished around 14:17. The first shard waited 28 minutes for a runner, and each shard then ran its quarter of the suite in about 20 minutes. Run Built-in Themes, the picker and the page's own look #824 spent over 1 hr 6 min in CI watch, almost all of it on macOS. - Linux runs the whole suite in about 8.5 minutes on one runner. The four macOS shards spend 3,920-4,252 seconds of test time on the same suite on
mainafter Inspect Worktree ownership with fewer git processes to shorten macOS CI #857 (runs 39430050727, 39424576921, 39424072554). - The Spec PR runs full CI, macOS included, after each Ticket lands, but only while it merges cleanly into
main: Spec: the Console, a web page for each machine's Commands #842 (basemain) had 13pull_requestCI runs onissue-776from 2026-10-19 19:50 to 2026-10-20 10:28 UTC. GitHub runs nopull_requestworkflows on a PR that conflicts with its base. Spec: the Console, a web page for each machine's Commands #842 conflicted withmainfrom then until its Repair at 16:18 UTC, so Stop from the Console #823, Built-in Themes, the picker and the page's own look #824 and Your own Themes and fonts #825 landed without a combined macOS run. What holds in every case is the end: the Spec run's Delivery mergesmainin and waits on the Spec PR's full CI before the Spec run ends. - Across the 16 Tickets of Spec: the Console, a web page for each machine's Commands #776, that is about 16 hours of blocking CI watch and roughly 18 hours of macOS runner time, on top of the Spec PR's own runs, which compete with the Tickets for the same runner pool.
Related, not duplicated
- shorten macos CI time #846 / Inspect Worktree ownership with fewer git processes to shorten macOS CI #857 made Worktree ownership inspection cheaper, which speeds up every test run. This issue changes which PRs run macOS at all, so the two compound.
- Reduce CI queueing and runtime without cancelling release publication #725 measured runner start delay; this removes the macOS start delay from Ticket PRs entirely.
- Select affected local tests and use nextest for the full Rust suite #724 is about local affected-test selection, not CI.
Widened in triage, 2026-10-20
The research in #902 (docs/research/macos-ci-speed.md) found the queue comes from this repository's own load on GitHub's 5-job macOS cap for personal accounts: 3.8 of 5 slots busy on average over 47.5 hours, a median 33 minutes from job creation to the last macOS shard (p90 55), against 11 minutes on Linux. By trigger, macOS runner time split 47% PRs into main, 29% PRs into Spec branches, 23% pushes to main. Skipping Spec-branch PRs alone takes demand to about 2.7 slots, where the measured median queue was seconds outside bursts.
So this issue now also moves the full 4-shard suite off PRs into main: it runs on pushes to main and nightly, and PRs into main get a one-job macOS gate, with a test:macos label to opt a PR into the full suite. That is uv's pattern (its test.yml: "Only run macOS tests on main without opt-in"). The updated agent brief below is the contract.
Activity
JacobStephens2 commentedon Oct 20, 2026
Agent Brief
Updated 2026-10-20 to widen the scope after the research in #902.
Category: enhancement
Summary: Run the full macOS suite on pushes to
mainand nightly, give PRs intomaina one-job macOS gate, and run no macOS on PRs into other basesCurrent behavior:
The CI workflow runs
test-macos-shard(four nextest hash partitions onmacos-26) for everypull_request, whatever its base, and for pushes tomain. Thetest-macosaggregate runs withalways()and passes only when the shards' result issuccess, so a skipped shard fails it. Every macOS job shares GitHub's 5-job macOS cap for a personal account. A full run takes 4 of those slots for about 18 minutes, and the measured median from job creation to the last shard is 33 minutes.Desired behavior:
mainscheduleonmainworkflow_dispatchmainwithout thetest:macoslabelmainwith thetest:macoslabelmacos-26job that runscargo clippy --all-targets -- -D warningsand a nextest filterset covering the tests of the macOS-specific code: the#[cfg(target_os = "macos")]process-identity and skills-directory code, and the platform branches in child Run handling. Keep the filterset in one named place (the repository's nextest config or the workflow) with a comment saying what it must cover, so new macOS-specific code has an obvious home.mainwithtest:macosstarts the full suite without a new push, so the workflow'spull_requesttrigger includes thelabeledactivity type. Create thetest:macoslabel if it is missing, with a description saying what it does.test-macoscheck is still created on every pull request and push, under that name. It passes when it should, given the table:mainbase, both were skipped.It fails when a job that ran failed or was cancelled, or when a job the rule requires was skipped.
test,site-test,console-test) are unchanged and run on every pull request.schedulecron; say so in the docs and name what to do when it is red: fix forward onmain, or label the fixing PRtest:macos.docs/ci-performance.md's workflow policy gives the table, the reasons and the trade-offs, citing this issue anddocs/research/macos-ci-speed.md:mainor overnight, not on its PR.Key interfaces:
push,pull_requestwithlabeled,schedule,workflow_dispatch), the shard job's condition, the new gate job and thetest-macosaggregate's success rule.cancel-in-progresspolicy stay as they are. Alabeledevent on a PR must not leave an older run's result standing for the newer head.scripts/generate-release.py, never edited by hand.Acceptance criteria:
mainbranch creates no macOS jobs, andtest-macossucceeds.mainwithouttest:macosruns the gate job and no shards.test-macospasses only if the gate passes.test:macosto an open PR intomainstarts all four shards on its current head, andtest-macosthen reflects the shards.main, a nightly run and aworkflow_dispatchrun all four shards, andtest-macosfails if any shard fails or is cancelled.cargo nextest listwith the filter) and how long the gate job took.test,site-testandconsole-testrun on every PR as now, andpython3 scripts/generate-release.py --checkstill passes.docs/ci-performance.mdrecords the table, the reasons, the trade-offs and the nightly-failure handling.main: gate only);test:macos(shards);mainbranch (no macOS jobs,test-macospassing), closed and its branch deleted afterwards.Out of scope:
build-local-artifacts (aarch64-apple-darwin)job on pull requests.[-]Run the macOS test shards only for pull requests into main[/-][+]Run the full macOS suite on main and nightly, with a one-job macOS gate on PRs into main[/+]