Skip to content

ci: optional compile-only pull request runs, and fail-fast merge groups - #13117

Merged
austinywang merged 4 commits into
mainfrom
ci-two-tier
Sep 20, 2026
Merged

austinywang merged 4 commits into
mainfrom
ci-two-tier

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Sep 20, 2026 •

Copy link
Copy Markdown
Collaborator

Nothing changes when this merges. It adds a switch, off by default, that lets pull requests run compile admission only and leaves the full macOS suite to the merge queue.

Why

Last 7 days of ci.yml pull-request runs: 1,111 runs for about 230 merges (74 succeeded, 433 failed, 604 cancelled by a newer push). About 80% of Mac time, roughly 53,000 Mac-minutes a week, goes to commits that never merge (shares estimated from 25 sampled runs per bucket).

A merge queue runs CI again on every queued pull request, so with today's workflow each macOS pull request would pay for the full suite twice. With compile-only, a merged pull request costs one full suite on the commit that lands plus about 21 Mac-minutes per push: about today's spend, and main can no longer break from two pull requests that each passed alone.

The cost: test failures show up when a pull request is queued, not on each push, and a flaky shard now costs a queue slot.

Summary

  • Switch: repository variable CI_PULL_REQUEST_SUITE=compile-only makes pull requests skip the app-host shards, package tests, lag build and Release build. Merge groups and dispatches always run everything. Unset (today), pull requests run everything.
  • Opt back in: the full-ci label restores the full suite for one pull request; labels are read live, so label and re-run.
  • Fails safe: unreadable labels, an unknown value or a missing output all mean full suite. The tests gate accepts a skipped suite only when full_suite is explicitly false.
  • Fail-fast merge groups: the shard matrix fails fast, and a new merge-group-fail-fast.yml cancels a merge group's run at the first failed job so the queue drops it without waiting on the remaining Macs. It needs actions: write, so it runs from workflow_run on the default branch's copy (a queued pull request cannot edit it), checks out nothing, and uses a GitHub-hosted runner. ci.yml gets no write permission.

Rollout (maintainers)

  1. Admin-merge ci: isolate the trusted complexity check from candidate Bun config and run it on merge groups #13114, then merge this.
  2. Together: set CI_PULL_REQUEST_SUITE=compile-only, create the full-ci label, and add "Require merge queue" to the ruleset "main: block force-push or delete" (squash, status check timeout 360 min, merge limits min 1 / max 5, build concurrency 3, only merge non-failing pull requests).
  3. Back out by deleting the variable. Do not set the variable without the queue: macOS changes would merge on compile admission alone.

Testing

  • tests/test_ci_change_areas.py (Python 3.9 and 3.12): runs the real tests gate script against compile-only, full, failed and missing-output inputs, covers the policy for every event, and asserts the fail-fast job never checks out code and is not a ci-status dependency. Pass.
  • test_ci_self_hosted_guard.sh, test_ci_merge_queue_required_checks.py, test_ci_reusable_workflow_permissions.py, actionlint: pass.
  • The watcher's step script against a stubbed gh: failure on the second page of jobs (cancels), completed run (exits), API down (errors after ten tries).
  • Not exercised on a real merge group: the queue is off.

Related: #13095

🤖 Generated with Claude Code

…ps at the first failure

A new changes output, full_suite, decides whether a run gets the whole macOS
suite (app-host shards, package tests, the lag build, the Release build) or
only compile admission. Merge groups and dispatches always get the suite.
Pull requests get it too unless the repository variable
CI_PULL_REQUEST_SUITE is "compile-only"; under that policy the full-ci label
opts one pull request back in. Nothing changes until the variable is set, and
it should be set together with enabling the merge queue, which then runs the
suite on the commit that will land.

The tests gate accepts a skipped suite only when full_suite is explicitly
false, so a missing output cannot relax it.

On merge groups the shard matrix fails fast, and a small job with
actions: write and no checkout cancels the run at the first failed job.
ci-status runs on cancellation and reports it, so the queue drops the entry
without waiting for the remaining macOS jobs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

Warning

Review limit reached

Next included review available in 26 seconds.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: e7f2477e-713f-4023-8c8f-c58d08d3ac14

📥 Commits

Reviewing files that changed from the base of the PR and between 54af70d and 3a9790d.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • .github/workflows/merge-group-fail-fast.yml
  • tests/test_ci_change_areas.py

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: dfe9c055-dc6e-4e0d-86a5-783b05ea8645

📥 Commits

Reviewing files that changed from the base of the PR and between 8f6d3c0 and 54af70d.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • scripts/ci/choose_ci_suite.py
  • tests/test_ci_change_areas.py

Included review availability: Your plan provides up to 10 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

Changes

The CI workflow now selects a full or compile-only macOS suite for pull requests. macOS jobs and the aggregate test gate use this selection. Merge-group runs stop shards and cancel after failures or timeouts. Tests cover routing, gating, and cancellation configuration.

CI routing and execution control

Layer / File(s) Summary
MacOS suite selection
.github/workflows/ci.yml, scripts/ci/choose_ci_suite.py, tests/test_ci_change_areas.py
The workflow fetches pull request labels and invokes choose_ci_suite.py. The helper selects the full suite unless a pull request uses the compile-only policy without the full-ci label. Tests cover the selection rules.
Full-suite job and aggregate gating
.github/workflows/ci.yml, tests/test_ci_change_areas.py
The macOS jobs require full_suite == 'true', except compile admission. The aggregate tests job adjusts required results based on full_suite. Tests cover full-suite and compile-only outcomes.
Merge-group failure cancellation
.github/workflows/ci.yml, tests/test_ci_change_areas.py
App-host test shards use fail-fast on merge groups. A watcher cancels merge-group runs after a failure or timeout. Tests validate the watcher configuration and shard behavior.

Priority: ➖ Normal

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

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant PullRequest
  participant ChangesJob
  participant GitHubAPI
  participant ChooseCISuite
  participant MacOSJobs
  PullRequest->>ChangesJob: Trigger CI
  ChangesJob->>GitHubAPI: Fetch labels
  ChangesJob->>ChooseCISuite: Evaluate event, policy, and labels
  ChooseCISuite-->>ChangesJob: Set full_suite
  ChangesJob->>MacOSJobs: Route full or compile-only suite
Loading
🚥 Pre-merge checks | ✅ 24 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 2 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (24 passed)
Check name Status Explanation
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.
Cmux Cloud Persistent Session And Early Input ✅ Passed PASS: The authoritative diff changes only CI workflow routing, a CI suite-selection script, and CI tests. It introduces no Cloud terminal creation, cmux-tui transport, manual renderer, PTY readiness, …
Cmux Swift Actor Isolation ✅ Passed PASS: The authoritative PR diff changes only .github/workflows/ci.yml, scripts/ci/choose_ci_suite.py, and tests/test_ci_change_areas.py. It contains no .swift files or production Swift code. T…
Cmux Swift Blocking Runtime ✅ Passed PASS: The pull-request diff changes only .github/workflows/ci.yml and Python files. It contains no changed Swift files or production Swift code. The only added sleep 20 is in a GitHub Actions shel…
Cmux Browser Automation Off-Main ✅ Passed The custom check is not applicable. The authoritative pull-request diff changes only .github/workflows/ci.yml, scripts/ci/choose_ci_suite.py, and tests/test_ci_change_areas.py. It does not chang…
Cmux Expensive Synchronous Load ✅ Passed PASS: The review-scoped diff changes only .github/workflows/ci.yml, scripts/ci/choose_ci_suite.py, and tests/test_ci_change_areas.py. It adds CI YAML and Python logic only. It adds or moves no p…
Cmux Cache Substitution Correctness ✅ Passed PASS: The authoritative pull-request diff changes only .github/workflows/ci.yml, scripts/ci/choose_ci_suite.py, and tests/test_ci_change_areas.py. It contains no production Swift, TypeScript, or…
Cmux No Hacky Sleeps ✅ Passed PASS. The only new fixed sleep is sleep 20 inside .github/workflows/ci.yml's merge-group cancellation watcher. The rule explicitly excludes GitHub Actions workflow YAML and allows CI orchestration…
Cmux Algorithmic Complexity ✅ Passed The diff adds no Swift, TypeScript, or JavaScript production code. The new Python helper performs a single linear pass over PR labels via a set comprehension; it does not rescan the collection per lab…
Cmux Swift Concurrency ✅ Passed PASS: The reviewed diff changes only .github/workflows/ci.yml and two Python files. It adds CI routing, a Python suite-selection helper, and test updates. No Swift source files changed, and the adde…
Cmux Swift @Concurrent ✅ Passed PASS: The review range changes only .github/workflows/ci.yml, scripts/ci/choose_ci_suite.py, and tests/test_ci_change_areas.py. The changed-file extensions are YAML and Python, with no Swift fil…
Cmux Swift Package Boundaries ✅ Passed The authoritative pull-request diff changes only .github/workflows/ci.yml, Python CI code, and Python tests. It contains no .swift paths or Swift patch hunks. Therefore, the Swift package-boundary…
Cmux Swiftpm Lockfiles ✅ Passed PASS. The review-scoped diff changes only .github/workflows/ci.yml, scripts/ci/choose_ci_suite.py, and tests/test_ci_change_areas.py. It adds no Package.swift, Package.resolved, .gitignore…
Cmux Swift Logging ✅ Passed The pull request changes only one YAML file and two Python files. It adds no production Swift code or Swift logging statements. The Python print calls emit CI status and the selected suite, which is…
Cmux User-Facing Error Privacy ✅ Passed The changed files are CI workflow automation, a CI-only suite-selection helper, and its behavioral tests. The added output is limited to CI routing states and generic job results. The GitHub API calls…
Cmux Full Internationalization ✅ Passed PASS: The authoritative diff changes only .github/workflows/ci.yml, scripts/ci/choose_ci_suite.py, and tests/test_ci_change_areas.py. It adds CI routing logic, workflow comments/logs, configurat…
Cmux Swiftui State Layout ✅ Passed PASS: The pull request changes only .github/workflows/ci.yml, scripts/ci/choose_ci_suite.py, and tests/test_ci_change_areas.py. The authoritative diff contains no Swift or SwiftUI files and no S…
Cmux Architecture Rethink ✅ Passed PASS. The reviewed range changes only .github/workflows/ci.yml, scripts/ci/choose_ci_suite.py, and tests/test_ci_change_areas.py; it contains no Swift source or SwiftUI/AppKit bridge changes. Th…
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The pull request changes only .github/workflows/ci.yml, scripts/ci/choose_ci_suite.py, and tests/test_ci_change_areas.py. The authoritative diff contains no Swift changes and no standalone `NSWi…
Cmux Source Artifacts ✅ Passed The diff changes only .github/workflows/ci.yml, the hand-written CI helper scripts/ci/choose_ci_suite.py, and tests in tests/test_ci_change_areas.py. These are intentional workflow, source, and …
Cmux No Test Or Debug Seam In Production Source ✅ Passed The pull-request diff changes only .github/workflows/ci.yml, scripts/ci/choose_ci_suite.py, and tests/test_ci_change_areas.py. It contains no Swift files under a production Sources/ path, so i…
Title check ✅ Passed The title clearly summarizes the two main changes: optional compile-only pull request runs and fail-fast merge groups.
Description check ✅ Passed The description clearly explains the changes, rationale, rollout, risks, testing, and known limitations. It omits the template's Demo Video, Review Trigger, and Checklist sections, but the required ch…
Full details: Docstring Coverage

Explanation

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

✨ 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

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.

@greptile-apps

greptile-apps Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge; the prior security and watcher-reliability findings are resolved and no new actionable defect remains.

Summary

This PR introduces an opt-in compile-only policy for pull-request CI while preserving the full macOS suite for merge groups, dispatches, unknown policy values, unreadable labels, and missing outputs. It also adds a default-branch workflow_run watcher that cancels merge-group CI after the first failed job.

  • Selects the suite through a fail-safe Python policy helper.
  • Keeps compile admission mandatory while conditionally skipping expensive macOS jobs.
  • Makes merge-group shard matrices fail fast.
  • Runs the write-capable cancellation watcher only from the default branch without checking out candidate code.
  • Adds focused policy and routing coverage.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  Start[CI event] --> Select[Choose macOS suite]
  Select -->|Pull request + compile-only + labels readable + no full-ci| Compile[Compile admission]
  Select -->|All other cases| Full[Full macOS suite]
  Compile --> Gate[Tests gate]
  Full --> Shards[App-host shards and package/build jobs]
  Shards --> Gate
  Shards -->|Merge group job fails| Watcher[Default-branch workflow_run watcher]
  Watcher --> Cancel[Cancel CI run]
  Gate --> Status[Required CI status]
Loading

Reviews (4) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..."

Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml Outdated
The watcher holds actions: write. As a job in ci.yml it ran on merge_group
from the queue's merge commit, so a queued pull request could edit the code
holding that token. It is now its own workflow triggered by workflow_run,
which always runs the default branch's copy, and ci.yml grants no write
permission at all.

It also stops when the CI run completes instead of inferring that from the
job list, counts startup failures, and gives up visibly after ten
consecutive Actions API errors instead of polling until its timeout.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo enabled auto-merge (squash) September 20, 2026 04:18
@teamleaderleo
teamleaderleo added this pull request to the merge queue Sep 20, 2026
@teamleaderleo
teamleaderleo added this pull request to the merge queue Sep 20, 2026
@austinywang
austinywang removed this pull request from the merge queue due to a manual request Sep 20, 2026
@austinywang
austinywang merged commit bd65a8a into main Sep 20, 2026
41 checks passed
rustybret pushed a commit to rustybret/bmux that referenced this pull request Sep 20, 2026
9da8b07 ci: run package tests only for packages a change can affect (manaflow-ai#13118)
1cd76eb ci: stop pull requests evicting the main cache seeds, and add an optional Warp cache store (manaflow-ai#13160)
bd65a8a ci: optional compile-only pull request runs, and fail-fast merge groups (manaflow-ai#13117)
5517d3d test: preserve native terminal scrollbar visibility (manaflow-ai#12977)
aa45187 Clarify shared Max RAM and vCPU allowance (manaflow-ai#13159)
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.

2 participants