Skip to content

ci: run all macOS jobs on paid managed runners (retire self-hosted minis) - #6422

Closed
azooz2003-bit wants to merge 2 commits into
mainfrom
feat-ci-paid-macos-runners
Closed

azooz2003-bit wants to merge 2 commits into
mainfrom
feat-ci-paid-macos-runners

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented Jun 19, 2026 •

Copy link
Copy Markdown
Collaborator

We've decided to stop using the self-hosted Mac minis for CI and run everything on paid managed runners.

What

Removes the vars.MACOS_RUNNER_* indirection from every workflow, so macOS jobs target paid runners directly with no self-hosted option:

  • All ${{ vars.MACOS_RUNNER_15/_26/_26_RELEASE/_DISPLAY/_IOS || '…' }} expressions replaced with their paid default: warp (warp-macos-15/26-arm64-6x), depot (perf-activation on PRs, unchanged), or hosted macos-26 (iOS).
  • perf-activation and test-e2e keep their manual inputs.runner override but default to warp instead of the self-hosted variable.
  • The tests job pin (a temporary 2026-06-18 workaround for the austin minis' missing GUI session) is now permanent; stale comments/descriptions that advertised the self-hosted fleet are updated.

No workflow references MACOS_RUNNER or the cmux-aws-macos-15 / cmux-macos-26 labels anymore. All 12 changed workflows pass yaml.safe_load.

Why

The self-hosted minis (austin, studio) had no logged-in GUI session, so testmanagerd couldn't broker the XCTest control session and the tests job ran 0 tests there — randomly red on unrelated PRs. Paid managed runners (warp/depot) are ephemeral, always in a usable session, and don't have this failure mode.

Follow-up (settings, not in this PR)

The now-unreferenced vars.MACOS_RUNNER_* repo variables can be deleted, and the self-hosted runners deregistered in Settings → Actions → Runners.

🤖 Generated with Claude Code


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Move all macOS CI to paid managed runners and retire the self-hosted Mac minis. Update docs and guard tests to enforce paid-only macOS runs and prevent the flaky XCTest GUI-session failures.

  • Refactors

    • Remove vars.MACOS_RUNNER_*; pin warp-macos-15/26 for most jobs, depot for perf PRs, and macos-26 for iOS.
    • Keep inputs.runner for perf-activation and test-e2e; default now warp with Depot identity guard.
    • Make the tests job pin permanent and update stale comments.
    • Align docs/ci-runners.md and guard tests with the paid-only model: ban bare hosted macOS runners (except iOS on macos-26), block any return of self-hosted labels, and assert the release SDK split using literal Warp labels.
  • Migration

    • Delete unused vars.MACOS_RUNNER_* repo variables.
    • Deregister the self-hosted Mac minis in Settings → Actions → Runners.

Written for commit 71b8ecb. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Chores
    • Updated GitHub Actions workflows to pin macOS CI jobs to explicit paid managed runner labels, removing variable-based runner selection and retired self-hosted Mac mini options.
    • Standardized “auto” runner behavior to consistently use the paid Warp macOS runner.
  • Documentation
    • Rewrote CI runner documentation to reflect the new paid-runner-only macOS policy and the current allowed runner labels.
  • Tests
    • Updated CI guard and release-lane checks to enforce the new explicit runner labels.

We're no longer using the self-hosted Mac minis for CI. Remove the
vars.MACOS_RUNNER_* indirection from every workflow so macOS jobs target paid
managed runners directly, with no self-hosted option:

- vars.MACOS_RUNNER_15 / _26 / _26_RELEASE / _DISPLAY / _IOS references removed;
  jobs now pin warp (warp-macos-15/26-arm64-6x), depot (perf-activation PRs,
  unchanged), or hosted macos-26 (iOS).
- perf-activation and test-e2e keep their manual `inputs.runner` override but
  default to warp instead of the self-hosted variable.
- Make the tests-job pin permanent (it was a temporary 2026-06-18 workaround for
  the austin minis' missing GUI session) and update stale comments/descriptions
  that still advertised the self-hosted fleet.

No workflow still references MACOS_RUNNER or the cmux-aws-macos-15 / cmux-macos-26
labels. Follow-up (settings, not code): the now-unused vars.MACOS_RUNNER_* repo
variables can be deleted and the self-hosted runners deregistered.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 19, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 19, 2026 3:57am
cmux-staging Building Building Preview, Comment Jun 19, 2026 3:57am

@coderabbitai

coderabbitai Bot commented Jun 19, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

All GitHub Actions workflows that previously used vars.MACOS_RUNNER_* repository variables with hardcoded fallbacks now pin the fallback values directly. Jobs with runner-identity guards (e.g., Depot validation) and Swift cache segmentation receive coordinated updates to runs-on, guard conditions, and cache key expressions. Test scripts validate the new policy enforcing paid managed runner labels, and documentation is rewritten to reflect that self-hosted Mac minis are retired.

Changes

Runner Variable Retirement and Hardcoded Label Adoption

Layer / File(s) Summary
Direct runs-on pins
.github/workflows/build-ghosttykit.yml, .github/workflows/ci-macos-compat.yml, .github/workflows/ci.yml, .github/workflows/release.yml, .github/workflows/nightly.yml, .github/workflows/test-depot.yml, .github/workflows/test-ios.yml, .github/workflows/tmux-corpus.yml, .github/workflows/ios-testflight.yml, .github/workflows/reload-build.yml, .github/workflows/perf-activation.yml
One-line runs-on replacements swapping vars.MACOS_RUNNER_* expressions for fixed values: warp-macos-15-arm64-6x, warp-macos-26-arm64-6x, or macos-26. The reload-build.yml input description notes that self-hosted minis are retired and only paid runners are supported.
Coordinated runs-on + identity guard + cache updates
.github/workflows/ci.yml, .github/workflows/test-e2e.yml, .github/workflows/perf-activation.yml
Jobs with "Validate Depot runner identity" guard steps and Swift cache segmentation (tests-build-and-lag, ui-regressions, e2e, activation-session) receive synchronized changes: fixed runs-on pins, REQUESTED_RUNNER env and guard if conditions aligned to the same runner, and key/restore-keys expressions stripped of vars.MACOS_RUNNER_15 references.
Policy documentation and runner table
docs/ci-runners.md
Documentation rewritten to enforce paid managed runner labels only. New runner table lists warp-macos-15-arm64-6x, warp-macos-26-arm64-6x, and depot-macos-* for macOS jobs, with macos-26 sanctioned only for iOS workflows. Sections on Linux routing, GUI-activation pin choices, manual-run defaults, and guard enforcement are updated to reflect the hardcoded paid-label model.
Test validation of runner policy
tests/test_ci_release_sdk_lane.sh, tests/test_ci_self_hosted_guard.sh
Test assertions updated to expect literal paid Warp runner labels instead of vars.MACOS_RUNNER_* patterns. The self-hosted guard script is substantially rewritten: validates that all macOS jobs run on paid Warp/Depot labels, identity guards are correctly applied for Depot choices, and retired self-hosted Mac runner labels (cmux-aws-macos-*, cmux-macos-26) do not reappear.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~18 minutes

Possibly related PRs

  • manaflow-ai/cmux#4926: Modifies the same workflows to target warp-macos-*-arm64-6x runner labels in place of vars.MACOS_RUNNER_* fallbacks.
  • manaflow-ai/cmux#6264: Pins the same nightly.yml and release.yml signing/notarization jobs to warp-macos-*-arm64-6x labels instead of variable-based selection.
  • manaflow-ai/cmux#6408: Updates CI runner enforcement (tests/test_ci_self_hosted_guard.sh and docs/ci-runners.md) to align workflow runs-on pins with the paid-runner-only policy.

Suggested reviewers

  • lawrencecchen

Poem

🐇 Hop, hop, no more vars to chase,
The minis retired, warp takes their place!
Each workflow now knows just where to run,
Hard-coded runners, simply done.
No fallback expressions, clean and bright —
The CI bunny sleeps easy tonight! 🌙

🚥 Pre-merge checks | ✅ 21 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (21 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main objective: retiring self-hosted Mac minis and migrating macOS CI jobs to paid managed runners.
Description check ✅ Passed The PR description comprehensively covers what changed and why, with clear details about removing vars.MACOS_RUNNER_* and migrating to paid runners. However, the Testing and Demo Video sections are missing, and the checklist is not completed.
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 Swift Actor Isolation ✅ Passed PR contains only GitHub Actions workflow YAML, shell scripts, and documentation changes—no Swift production code changes, so actor isolation check is inapplicable.
Cmux Swift Blocking Runtime ✅ Passed PR contains no Swift source code changes; only GitHub Actions YAML workflows, documentation, and shell scripts were modified. Check not applicable.
Cmux Expensive Synchronous Load ✅ Passed PR contains no Swift production source code changes—only GitHub Actions workflow YAML, documentation, and shell scripts. Custom check for expensive synchronous loads is not applicable.
Cmux Cache Substitution Correctness ✅ Passed This PR modifies only CI/CD workflows and documentation, not production code. The cache key changes (in perf-activation.yml and test-e2e.yml) replace repository variable expressions with equivalent...
Cmux No Hacky Sleeps ✅ Passed PR contains only GitHub Actions workflow YAML (out of scope), documentation, and CI validation scripts with no actual sleep/delay calls or hacky timing synchronization.
Cmux Algorithmic Complexity ✅ Passed This PR modifies only GitHub Actions workflow configs, documentation, and test scripts. No production Swift/TypeScript/JavaScript/runtime code changes. Rule explicitly passes "test-only scaffolding...
Cmux Swift Concurrency ✅ Passed Custom check applies only to Swift code; PR contains only YAML workflows, Markdown docs, and shell scripts. No Swift files modified.
Cmux Swift @Concurrent ✅ Passed The PR contains no Swift code changes - only GitHub Actions workflow YAML files, shell scripts, and documentation updates. No Swift concurrent annotations are involved.
Cmux Swift File And Package Boundaries ✅ Passed PR contains no Swift source file changes (0 .swift files modified). Check for Swift file/package boundaries is not applicable to this CI/workflow configuration PR.
Cmux Swiftpm Lockfiles ✅ Passed PR only modifies GitHub workflows, documentation, and test scripts; no SwiftPM packages, Xcode projects, .gitignore, or dependency changes subject to the SwiftPM Package.resolved rule.
Cmux Swift Logging ✅ Passed PR contains only CI/workflow YAML, documentation, and shell script changes; no production Swift code is modified, so the logging rule check is not applicable.
Cmux User-Facing Error Privacy ✅ Passed PR only modifies CI workflows, developer documentation, and test scripts—not user-facing error messages or alerts. All changes are operational/infrastructure related and fall under the "developer-o...
Cmux Full Internationalization ✅ Passed PR contains only CI workflow changes and internal operational documentation. No user-facing Swift text, string catalogs, Info.plist, web UI, or i18n changes present. Exempt as developer/operational...
Cmux Swiftui State Layout ✅ Passed This PR contains no SwiftUI or Swift source code changes (only CI workflow YAML, documentation, and shell scripts), so the swiftui-state-layout rule does not apply.
Cmux Architecture Rethink ✅ Passed PR contains only CI/GitHub Actions infrastructure changes (12 workflow files, 1 documentation file, 2 shell scripts) with no Swift code modifications. Swift architectural rethink rule is not applic...
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR contains no Swift code changes (only CI workflow YAML, docs, and shell scripts), so the Swift auxiliary window close shortcuts check does not apply.
Cmux Source Artifacts ✅ Passed All 15 changed files are intentional source code: 12 workflow configs, 1 documentation file, 2 test scripts. No artifacts (logs, build output, DerivedData, temp folders, caches, dependency checkout...

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-ci-paid-macos-runners

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 and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 19, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR retires the self-hosted Mac minis from CI and wires every macOS job directly to paid managed runners (WarpBuild or Depot). The root cause — testmanagerd could not broker XCTest control sessions on the minis because they had no logged-in GUI session — is addressed by moving to ephemeral runners that always start in a usable state.

  • All ${{ vars.MACOS_RUNNER_* || '...' }} expressions in 12 workflow files are replaced with the corresponding paid hardcoded label (warp-macos-15-arm64-6x, warp-macos-26-arm64-6x, depot-macos-latest, or macos-26).
  • The guard tests (test_ci_self_hosted_guard.sh, test_ci_release_sdk_lane.sh) are updated in lock-step to assert the new literal labels instead of the removed variable references; new defence-in-depth checks block the retired self-hosted labels from ever returning.
  • docs/ci-runners.md is comprehensively rewritten to reflect the new "paid managed runners only" model, and the former break-glass variable-flip runbook is removed.

Confidence Score: 5/5

Safe to merge — all changes are mechanical label substitutions with no logic alterations to the actual build, test, or release steps.

Every workflow change is a straightforward find-and-replace of the vars.MACOS_RUNNER_* expression with the paid label that was already its baked-in fallback, so no job lands on a different runner than it did before. The guard tests are updated in lock-step and add new defence-in-depth checks. Documentation is comprehensively rewritten to match the new state.

No files require special attention. The guard scripts (tests/test_ci_self_hosted_guard.sh and tests/test_ci_release_sdk_lane.sh) are worth a read to confirm the new AWK patterns match the updated YAML, but they are internally consistent with the workflow changes.

Important Files Changed

Filename Overview
.github/workflows/ci.yml Replaces five vars.MACOS_RUNNER_* expressions with direct paid labels; updates the tests job comment from TEMPORARY to the permanent retirement notice; all identity-guard env vars updated consistently.
tests/test_ci_self_hosted_guard.sh Guard logic updated throughout: display-runner AWK pattern now keys off the literal warp-macos-15-arm64-6x label; release-build runner check updated; iOS exemption added for macos-26 in test-ios.yml/ios-testflight.yml; new check blocks retired self-hosted labels from returning.
tests/test_ci_release_sdk_lane.sh SDK-lane assertions updated from variable-based patterns to the direct paid Warp labels; comment block added explaining the intentional removal of the vars.MACOS_RUNNER_* indirection.
docs/ci-runners.md Comprehensively rewritten: variable-indirection table and break-glass runbook removed; new table maps each paid label to its workflows; GUI-activation and iOS sections accurately reflect the new architecture.
.github/workflows/perf-activation.yml Three repeated runner expressions consistently updated; description string updated to remove stale variable reference.
.github/workflows/test-e2e.yml run-name, concurrency group, runs-on, identity-guard if/env, and SPM cache key all updated to direct warp-macos-15-arm64-6x label; no logic change.
.github/workflows/release.yml Two jobs updated to pin their paid Warp labels directly; no functional change to build logic.

Reviews (2): Last reviewed commit: "ci: update runner guards + docs for paid..." | Re-trigger Greptile

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Line 676: The hardcoded REQUESTED_RUNNER value warp-macos-15-arm64-6x at line
676 violates both the test contract in tests/test_ci_self_hosted_guard.sh (which
expects REQUESTED_RUNNER to reference vars.MACOS_RUNNER_DISPLAY) and the runtime
guard logic in the guard script (which expects REQUESTED_RUNNER to match the
depot-* pattern). Replace the hardcoded string REQUESTED_RUNNER:
warp-macos-15-arm64-6x with a proper variable reference like REQUESTED_RUNNER:
${{ vars.MACOS_RUNNER_DISPLAY }} or equivalent, ensuring it resolves to a value
matching the depot-* pattern required by the guard script.

In @.github/workflows/test-e2e.yml:
- Around line 54-57: Update the guard test expectations in
tests/test_ci_self_hosted_guard.sh at lines 99-100 to match the new runner
expression format that now resolves directly to 'warp-macos-15-arm64-6x' instead
of using vars.MACOS_RUNNER_15. Replace the old expression check with the new one
that expects startsWith((!inputs.runner || inputs.runner == 'auto') &&
'warp-macos-15-arm64-6x' || inputs.runner, 'depot-macos-') to align with the
updated workflow at line 54 of .github/workflows/test-e2e.yml and prevent the
guard test from failing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0183b144-ce86-4da3-bd08-bdc7073d0cb7

📥 Commits

Reviewing files that changed from the base of the PR and between 03f9096 and ae4a312.

📒 Files selected for processing (12)
  • .github/workflows/build-ghosttykit.yml
  • .github/workflows/ci-macos-compat.yml
  • .github/workflows/ci.yml
  • .github/workflows/ios-testflight.yml
  • .github/workflows/nightly.yml
  • .github/workflows/perf-activation.yml
  • .github/workflows/release.yml
  • .github/workflows/reload-build.yml
  • .github/workflows/test-depot.yml
  • .github/workflows/test-e2e.yml
  • .github/workflows/test-ios.yml
  • .github/workflows/tmux-corpus.yml

Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/test-e2e.yml
Match test_ci_self_hosted_guard.sh and test_ci_release_sdk_lane.sh to the
paid-only workflow config (literal warp/depot labels instead of the removed
vars.MACOS_RUNNER_*), preserving their intent: paid runners only, depot identity
validation, macOS-15-helper/macOS-26-app SDK split, and a new explicit check
that retired self-hosted labels never reappear. Update docs/ci-runners.md to the
paid-only model.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_ci_self_hosted_guard.sh`:
- Around line 711-713: The grep patterns used to detect hosted runners in the CI
check are too restrictive, using character classes like [a-z0-9]+ and [a-z0-9.]+
which miss runner labels with multiple dash-separated segments such as
macos-15-xlarge or ubuntu-24.04-arm. Replace the character classes in both the
main grep pattern and the exemption filter (at the two locations where this
appears) with [^[:space:]#]+ to match any characters except whitespace or inline
comments, ensuring the patterns capture runner labels regardless of their suffix
complexity while still stopping at whitespace or comment boundaries. This change
should be applied to both the grep pattern on line 711 and the corresponding
exemption filter pattern noted as also applying to lines 725-728.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a487e26c-3f48-4158-bc85-3430286052e9

📥 Commits

Reviewing files that changed from the base of the PR and between ae4a312 and 71b8ecb.

📒 Files selected for processing (3)
  • docs/ci-runners.md
  • tests/test_ci_release_sdk_lane.sh
  • tests/test_ci_self_hosted_guard.sh

Comment on lines +711 to +713
hits="$(grep -rnE "runs-on:[[:space:]]*(ubuntu-[a-z0-9.]+|macos-[a-z0-9]+)[[:space:]]*$" "$ROOT_DIR/.github/workflows" \
| grep -vE "/(test-ios|ios-testflight)\.yml:[0-9]+:[[:space:]]*runs-on:[[:space:]]*macos-26[[:space:]]*$" \
|| true)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

pattern='^[[:space:]]*runs-on:[[:space:]]*(ubuntu-[a-z0-9.]+|macos-[a-z0-9]+)[[:space:]]*$'
for line in \
  "runs-on: macos-26" \
  "runs-on: macos-15-xlarge" \
  "runs-on: ubuntu-24.04-arm" \
  "runs-on: macos-26 # iOS exemption comment"
do
  if [[ "$line" =~ $pattern ]]; then
    echo "MATCH: $line"
  else
    echo "MISS : $line"
  fi
done

Repository: manaflow-ai/cmux

Length of output: 199


🏁 Script executed:

# Check what runner labels are actually used in the repo's workflows
find .github/workflows -name "*.yml" -o -name "*.yaml" | head -20

Repository: manaflow-ai/cmux

Length of output: 635


🏁 Script executed:

# Examine the current guard check more closely
grep -A 20 "check_no_bare_github_hosted_runners" tests/test_ci_self_hosted_guard.sh | head -40

Repository: manaflow-ai/cmux

Length of output: 2277


🏁 Script executed:

# Find actual runs-on labels used in workflows
grep -rh "runs-on:" .github/workflows | sed 's/.*runs-on:[[:space:]]*//; s/[[:space:]]*#.*//' | sort -u

Repository: manaflow-ai/cmux

Length of output: 466


🏁 Script executed:

# Check if any actual workflows use inline comments on runs-on lines
grep -r "runs-on:.*#" .github/workflows

Repository: manaflow-ai/cmux

Length of output: 42


🏁 Script executed:

# Check what bare GitHub-hosted label formats actually exist in the workflows
grep -rh "runs-on:" .github/workflows | grep -E "(ubuntu-|macos-)" | grep -v "{{" | head -20

Repository: manaflow-ai/cmux

Length of output: 522


🏁 Script executed:

# Test the proposed regex fix against real patterns
bash << 'EOF'
set -euo pipefail

# Current narrow pattern
current_pattern='runs-on:[[:space:]]*(ubuntu-[a-z0-9.]+|macos-[a-z0-9]+)[[:space:]]*$'

# Proposed fix
proposed_pattern='^[[:space:]]*runs-on:[[:space:]]*(ubuntu-[^[:space:]#]+|macos-[^[:space:]#]+)[[:space:]]*(#.*)?$'

test_cases=(
  "runs-on: macos-26"
  "runs-on: ubuntu-24.04"
  "runs-on:macos-26"
  "  runs-on: macos-26"
  "runs-on: macos-26 # comment"
  "runs-on: warp-macos-26"  # should NOT match (paid runner)
  "runs-on: ubuntu-latest"
)

echo "=== CURRENT PATTERN ==="
for line in "${test_cases[@]}"; do
  if [[ "$line" =~ $current_pattern ]]; then
    echo "✓ MATCH: $line"
  else
    echo "✗ MISS : $line"
  fi
done

echo ""
echo "=== PROPOSED PATTERN ==="
for line in "${test_cases[@]}"; do
  if [[ "$line" =~ $proposed_pattern ]]; then
    echo "✓ MATCH: $line"
  else
    echo "✗ MISS : $line"
  fi
done
EOF

Repository: manaflow-ai/cmux

Length of output: 538


🏁 Script executed:

# Check the actual lines in the test file around 711-728
sed -n '705,730p' tests/test_ci_self_hosted_guard.sh

Repository: manaflow-ai/cmux

Length of output: 1694


🏁 Script executed:

# Check the second guard function around line 725
sed -n '720,735p' tests/test_ci_self_hosted_guard.sh

Repository: manaflow-ai/cmux

Length of output: 887


🏁 Script executed:

# Verify the proposed pattern handles the exemption filter correctly
bash << 'EOF'
set -euo pipefail

# Test the proposed exemption filter
exemption_pattern='^[[:space:]]*runs-on:[[:space:]]*macos-26([[:space:]]*(#.*)?)?$'

test_exemptions=(
  "runs-on: macos-26"
  "runs-on: macos-26 # comment"
  "  runs-on: macos-26"
  "runs-on: macos-26  # longer comment here"
  "runs-on: macos-26-xlarge"  # should NOT match
  "runs-on: macos-15"  # should NOT match
)

echo "=== TESTING EXEMPTION FILTER ==="
for line in "${test_exemptions[@]}"; do
  if [[ "$line" =~ $exemption_pattern ]]; then
    echo "✓ MATCH (exempt): $line"
  else
    echo "✗ MISS (not exempt): $line"
  fi
done
EOF

Repository: manaflow-ai/cmux

Length of output: 357


🏁 Script executed:

# Check if ubuntu labels are used anywhere with problematic patterns
grep -rh "runs-on:.*ubuntu" .github/workflows | head -10

Repository: manaflow-ai/cmux

Length of output: 750


🏁 Script executed:

# Verify the current guard actually works on the real codebase
bash << 'EOF'
cd "$(git rev-parse --show-toplevel)"

# Run the actual guard function to see if it passes or fails
set +e
bash tests/test_ci_self_hosted_guard.sh 2>&1 | head -50
exit_code=$?
echo "Guard exit code: $exit_code"
EOF

Repository: manaflow-ai/cmux

Length of output: 1701


🏁 Script executed:

# Double-check: are there any bare ubuntu- or macos- labels NOT using variables/expressions?
grep -rh "runs-on:" .github/workflows | grep -vE '(\$\{|\$\(|\{\{)' | grep -E "(ubuntu-|macos-)" | sort -u

Repository: manaflow-ai/cmux

Length of output: 154


Regex for hosted-runner detection is narrow but currently effective; hardening recommended for future-proofing.

The regexes on lines 711 and 725 only match macos-[a-z0-9]+ and ubuntu-[a-z0-9.]+, missing patterns like macos-15-xlarge or ubuntu-24.04-arm. The guard currently passes because the repo uses only:

  • Bare macos-26 (properly exempted for iOS)
  • Paid runner prefixes (warp-*, depot-*, blacksmith-*)
  • Variable expressions (${{ vars.LINUX_RUNNER ... }})

However, the pattern should be broadened to catch any future bare hosted labels with extra suffix segments. Change [a-z0-9]+ to [^[:space:]#]+ to match runner labels up to whitespace or inline comments, and update the exemption filter to handle comments as well.

Suggested hardening
-  hits="$(grep -rnE "runs-on:[[:space:]]*(ubuntu-[a-z0-9.]+|macos-[a-z0-9]+)[[:space:]]*$" "$ROOT_DIR/.github/workflows" \
-    | grep -vE "/(test-ios|ios-testflight)\.yml:[0-9]+:[[:space:]]*runs-on:[[:space:]]*macos-26[[:space:]]*$" \
+  hits="$(grep -rnE "runs-on:[[:space:]]*(ubuntu-[^[:space:]#]+|macos-[^[:space:]#]+)[[:space:]]*(#.*)?$" "$ROOT_DIR/.github/workflows" \
+    | grep -vE "/(test-ios|ios-testflight)\.yml:[0-9]+:[[:space:]]*runs-on:[[:space:]]*macos-26([[:space:]]*(#.*)?)?$" \
     || true)"
@@
-  ios_bad="$(grep -rnE "runs-on:[[:space:]]*macos-[a-z0-9]+[[:space:]]*$" \
+  ios_bad="$(grep -rnE "runs-on:[[:space:]]*macos-[^[:space:]#]+[[:space:]]*(#.*)?$" \
     "$ROOT_DIR/.github/workflows/test-ios.yml" \
     "$ROOT_DIR/.github/workflows/ios-testflight.yml" 2>/dev/null \
-    | grep -vE "runs-on:[[:space:]]*macos-26[[:space:]]*$" || true)"
+    | grep -vE "runs-on:[[:space:]]*macos-26([[:space:]]*(#.*)?)?$" || true)"

Also applies to: 725–728

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_ci_self_hosted_guard.sh` around lines 711 - 713, The grep patterns
used to detect hosted runners in the CI check are too restrictive, using
character classes like [a-z0-9]+ and [a-z0-9.]+ which miss runner labels with
multiple dash-separated segments such as macos-15-xlarge or ubuntu-24.04-arm.
Replace the character classes in both the main grep pattern and the exemption
filter (at the two locations where this appears) with [^[:space:]#]+ to match
any characters except whitespace or inline comments, ensuring the patterns
capture runner labels regardless of their suffix complexity while still stopping
at whitespace or comment boundaries. This change should be applied to both the
grep pattern on line 711 and the corresponding exemption filter pattern noted as
also applying to lines 725-728.

hhsw2015 pushed a commit to hhsw2015/cmux that referenced this pull request Jun 21, 2026
…ettingsCore + wire 110 fork files

Key upstream commits:
- SSH ControlMaster PTY-resize fix (manaflow-ai#6432)
- profiling capture action (manaflow-ai#6433)
- hookless agent forking revert (manaflow-ai#6434)
- notification jump-focus fix for nested tabs (manaflow-ai#6416)
- ~100% CPU re-render loop fix
- right-sidebar custom sidebar tabs (manaflow-ai#6430) — adds SurfaceKind.customSidebar
- terminal scroll-speed multiplier (manaflow-ai#6422)
- Settings recover from offscreen frames (manaflow-ai#5770)

Strategy:
- Default 3-way merge (no -X theirs) — only 15 conflicts vs Frankenstein corruption
  in P58's -X theirs attempt.
- Took fork's TerminalController.swift wholesale (huge fork v2 handler surface).
- Took upstream's pbxproj wholesale — re-added CMUXSessionDaemon + CMUXSettingsCore
  packages to BOTH cmux + cmux-cli targets (P58 only added cmux-cli, leaving
  CmuxSettingsRegistry symbols undefined at link time for the app).
- Wired 110 fork-only Swift files (Sources/Herdr*, StableLayout/, etc.) lost
  when taking upstream's pbxproj.
- Removed dup TerminalController+CustomSidebarCommands.swift (fork TC already
  has all v2CustomSidebar* handlers).
- Removed dup titlebarShortcutHintShouldShow (now in RightSidebarChromeStyle.swift).
- Added SurfaceKind.customSidebar + SessionBlueprintEncoder case for it.
- Made Workspace.isProgrammaticSplit non-private (consumed by Workspace+CustomSidebarPane).

Manual conflict resolutions:
- AppDelegate.shortcut routing: kept fork's selectNext/PreviousTopLevelTab
  but composed with upstream's preferredMainWindowContextForShortcutRouting.
- Workspace.swift session restore: combined fork's Claude restorability filter
  with upstream's Self.resumeBindingForSessionRestore helper.
- WorkspaceContentView canvas mode: nested fork's shouldBypassTopBar branch
  inside the non-canvas arm.

Build green: cmux app + cmuxTests both compile clean.

Co-Authored-By: Claude <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview – cmux — 71b8ecb1 Deployed Jun 19, 2026 by vercel[bot]
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