Skip to content

Fix main macOS CI - #3643

Merged
lawrencecchen merged 3 commits into
mainfrom
fix-main-ci-65706d
May 6, 2026
Merged

lawrencecchen merged 3 commits into
mainfrom
fix-main-ci-65706d

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented May 6, 2026 •

Copy link
Copy Markdown
Contributor

Fixes the current red main macOS CI lanes at commit 65706d036f138628d5337188ca51f5f34acb566c.

Changes:

  • add a verified Zig installer script with retrying mirror fallback, then use it from CircleCI and GitHub workflows
  • make CLI socket receive timeouts deterministic for fast closed-peer cases
  • isolate shortcut routing tests from the developer cmux.json
  • route browser-focused shortcuts through the focused browser panel before rename-tab/workspace defaults

Local verification:

  • bash -n scripts/install-zig-ci.sh
  • workflow YAML parse for .circleci/config.yml and .github/workflows/*.yml
  • ./tests/test_ci_self_hosted_guard.sh
  • ./tests/test_ci_create_dmg_pinned.sh
  • bash tests/test_ci_unit_test_spm_retry.sh
  • bash tests/test_ci_ghosttykit_checksum_verification.sh
  • bash tests/test_ci_ghosttykit_checksum_present.sh
  • CLI contract tests: version memory guard, help contract, layout focus contract, socket operation deadline
  • targeted AppDelegateShortcutRoutingTests and AppDelegateRenameShortcutContextTests
  • CircleCI release reproduction: universal Release build with explicit /tmp/cmux-mainci-release derived data

Summary by cubic

Fixes failing macOS CI by introducing a verified Zig installer with mirror fallback and using it across all workflows. Also stabilizes CLI socket timeouts and tightens shortcut routing and tests to reduce flakes.

  • Bug Fixes
    • macOS CI: replace inline Zig install steps with scripts/install-zig-ci.sh (minisign verification, retrying mirror fallback, arch autodetect) across CircleCI and all GitHub workflows.
    • CLI: make receive timeouts deterministic by configuring on connect and only when changed; avoid redundant setsockopt calls; include errno and reason in errors.
    • Shortcuts/tests: prioritize the focused browser panel during routing; add KeyboardShortcutTestSettingsIsolation.installIsolatedTestFileStore to isolate settings in tests; update keybinding expectation to Cmd+Option+E and wrap debug shortcut test with a temporary unbind to prevent flakes.

Written for commit 618d619. Summary will update on new commits.

Summary by CodeRabbit

  • Improvements

    • Better keyboard shortcut focus resolution to prioritize the active browser panel
    • Improved CLI socket timeout handling and clearer error reporting
  • Tests

    • Added isolation for keyboard shortcut settings in tests to reduce flakiness
    • Included a new test helper to support isolated test stores
  • Chores

    • Centralized Zig toolchain installation into a dedicated CI script used across workflows for more consistent builds

@vercel

vercel Bot commented May 6, 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 May 6, 2026 10:59am
cmux-staging Building Building Preview, Comment May 6, 2026 10:59am

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented May 6, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8fbb605d-51fa-46b0-8a97-df3aeb49e7a4

📥 Commits

Reviewing files that changed from the base of the PR and between 50a82ec and 618d619.

📒 Files selected for processing (3)
  • CLI/cmux.swift
  • Sources/KeyboardShortcutContext.swift
  • scripts/install-zig-ci.sh

📝 Walkthrough

Walkthrough

Centralizes Zig installation into a new scripts/install-zig-ci.sh and updates CircleCI/GitHub workflows to invoke it. Adds a test helper to isolate keyboard-shortcut settings and updates tests/project to use it. Adjusts keyboard-shortcut focus resolution to prefer the focused BrowserPanel. Adds receive-timeout tracking and improved error reporting in the CLI socket code.

Changes

CI/CD Zig Installation Centralization

Layer / File(s) Summary
Shared Installation Script
scripts/install-zig-ci.sh
New strict-shell script that downloads a macOS Zig tarball, verifies its minisign signature, detects macOS architecture, extracts, and installs Zig binaries/libraries to system paths.
Workflow Invocation
.github/workflows/..., .circleci/config.yml
Replaced inline Zig install blocks with ./scripts/install-zig-ci.sh invocations across many GitHub Actions workflows and CircleCI jobs (tests, builds, nightly, perf, release, e2e, etc.).

Keyboard Shortcut Focus Resolution & Test Isolation

Layer / File(s) Summary
Focus Resolution Logic
Sources/KeyboardShortcutContext.swift
Added shortcutFocusedBrowserPanel(in:) helper and updated web-inspector/event-focused resolution to prefer the currently focused BrowserPanel for the shortcut's window.
Test Support
cmuxTests/KeyboardShortcutTestSettingsIsolation.swift, GhosttyTabs.xcodeproj/...
New helper installIsolatedTestFileStore(prefix:) that replaces KeyboardShortcutSettings.settingsFileStore with a temp-file-backed store; project file added to include the helper source.
Test Wiring / Updates
cmuxTests/AppDelegateRenameShortcutContextTests.swift, cmuxTests/AppDelegateShortcutRoutingTests.swift
Tests now install isolated settings stores in setUp; added temporary-settings handling helpers and small test updates (including renaming/updating one shortcut test to Cmd+Option+E and scoping an openSettings action to avoid global mutation).

CLI Socket Timeout Configuration

Layer / File(s) Summary
Timeout Tracking & Reconfiguration
CLI/cmux.swift
Introduced a private tracker for last configured receive timeout; conditionally (re)configures socket receive timeout only when needed and resets it during socket cleanup and write-safety setup.
Error Reporting
CLI/cmux.swift
On timeout configuration failure, captures errno and derives a human-readable reason, then throws a CLIError including both errno and reason; updates the tracker after successful configuration.

Sequence Diagram(s)

sequenceDiagram
    participant Shortcut as Shortcut Event
    participant Window as NSWindow
    participant Resolver as shortcutFocusedBrowserPanel(in:)
    participant TabMgr as TabManager
    participant Panel as BrowserPanel

    Shortcut->>Window: event dispatched (shortcut, web inspector, etc.)
    Window->>Resolver: resolve focused panel for this window
    Resolver-->>Panel: returns focused BrowserPanel (if any)
    alt Panel found
        Resolver-->>Shortcut: dispatch action targeting Panel
    else Panel not found
        Window->>TabMgr: ask for global focused panel
        TabMgr-->>Resolver: return focused BrowserPanel or nil
        Resolver-->>Shortcut: dispatch action or return nil
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

A rabbit nibbles scripts at dawn,
Packs Zig and signatures, neat and drawn.
Panels find focus, tests sleep tight,
Timeouts tuned — CI hums tonight.
🐇✨

🚥 Pre-merge checks | ✅ 12 | ❌ 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 (12 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix main macOS CI' directly relates to the main objective of the PR, which is to fix failing macOS CI lanes, and clearly summarizes the primary change.
Description check ✅ Passed The PR description covers the required sections: detailed summary of changes, comprehensive testing verification, and lists multiple checks performed. However, the template's Testing section and Demo Video section lack some requested details.
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 No actor isolation violations. Socket timeout optimization and shortcut refactoring are safe. Test helpers properly marked @MainActor.
Cmux Swift Blocking Runtime ✅ Passed No new blocking patterns in production Swift code. Timeout tracking optimization and focus resolution helpers added. Test scaffolding changes permitted.
Cmux Swift Concurrency ✅ Passed No legacy async patterns introduced. Changes use synchronous state tracking, helper functions, and modern @MainActor isolation in tests.
Cmux Swift @Concurrent ✅ Passed All Swift changes comply with concurrency rules. Socket timeout code is synchronous with proper GCD dispatch. Test helper correctly uses @MainActor. No missing or invalid @concurrent annotations.
Cmux Swift File And Package Boundaries ✅ Passed All Swift changes comply with boundary rules. Small focused bug fixes to CLI/cmux.swift (+11 lines) and KeyboardShortcutContext.swift (+16 lines) with coherent responsibilities under limits.
Cmux Swift Logging ✅ Passed The PR contains only CLI output (allowed), no logging violations in production Swift code, and all test files are exempt. Error reporting uses errno/strerror without exposing secrets.
Cmux Swiftui State Layout ✅ Passed PR modifies CI configs, adds Zig installer script, adjusts socket timeout, and creates test isolation helpers. No modified files introduce new SwiftUI state patterns.
Cmux Architecture Rethink ✅ Passed Complies with rules: timeout tracking is syscall optimization; focus helper refactors logic without duplication. No timing repairs, lifecycle splits, or state duplication.

✏️ 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 fix-main-ci-65706d

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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 May 6, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the red macOS CI lanes by centralising Zig installation into a verified script with mirror-fallback, stabilising CLI socket timeouts on reused connections, and isolating shortcut tests from the developer's on-disk settings.

  • CI / Zig install: eight identical inline Zig install blocks across CircleCI and GitHub workflows are replaced by scripts/install-zig-ci.sh, which adds minisign verification, --retry 8 curl flags, and a mirror→official URL fallback for HTTP-level failures.
  • CLI socket timeouts: lastConfiguredReceiveTimeout tracks the socket's actual timeout state; connectOnce() now explicitly sets the receive timeout after opening the socket, and close() resets the tracker — ensuring the first send() on a reused socket never inherits the previous call's short multiline-idle timeout.
  • Shortcut routing / tests: shortcutFocusedBrowserPanel(in:) is extracted as a shared fallback in shortcutEventFocusedBrowserPanel; routing tests switch to installIsolatedTestFileStore to prevent the developer's cmux.json from causing test flakes; the Cmd+Option+E binding replaces Cmd+Shift+E in the relevant test.

Confidence Score: 5/5

Safe to merge; all three change areas are well-scoped fixes with no new structural risk introduced.

The socket timeout change eliminates the stale-timeout window on reused connections by tracking actual socket state. The shortcut routing refactor is a pure extraction with no new logic surface. CI and test isolation changes are infrastructure-only with no production runtime impact.

No files require special attention.

Important Files Changed

Filename Overview
CLI/cmux.swift Adds lastConfiguredReceiveTimeout tracking to skip redundant setsockopt calls, explicitly sets the receive timeout on connectOnce(), resets it on close(), and improves timeout error messages with errno details.
Sources/KeyboardShortcutContext.swift Extracts a shared shortcutFocusedBrowserPanel(in:) helper and adds it as a fallback in shortcutEventFocusedBrowserPanel, routing browser-focused shortcuts through the tab manager's focused panel when no specific responder is detected.
scripts/install-zig-ci.sh New Zig installer with minisign verification and mirror/official URL fallback. Mirror fallback is HTTP-failure-only (already discussed in a prior thread).
cmuxTests/KeyboardShortcutTestSettingsIsolation.swift New test-only helper that installs an isolated temporary file store for KeyboardShortcutSettings, preventing shortcut tests from reading the developer's on-disk cmux.json.
.github/workflows/ci.yml Replaces four identical inline Zig install blocks with ./scripts/install-zig-ci.sh, gaining proper architecture detection and minisign verification.
GhosttyTabs.xcodeproj/project.pbxproj Adds KeyboardShortcutTestSettingsIsolation.swift to the test target build phase.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant SocketClient
    participant Darwin

    Note over SocketClient: connectOnce()
    SocketClient->>Darwin: configureSocketWriteSafety(responseTimeout)
    SocketClient->>Darwin: configureReceiveTimeout(responseTimeout)
    Darwin-->>SocketClient: lastConfiguredReceiveTimeout = responseTimeout

    Note over Caller,Darwin: First send()
    Caller->>SocketClient: send(command)
    SocketClient->>SocketClient: lastConfigured == initial? skip setsockopt
    SocketClient->>Darwin: read()
    Darwin-->>SocketClient: sawNewline -> currentTimeout = multilineIdle
    SocketClient->>Darwin: configureReceiveTimeout(multilineIdle)
    Darwin-->>SocketClient: EAGAIN -> complete

    Note over Caller,Darwin: Second send() on reused socket
    Caller->>SocketClient: send(command)
    SocketClient->>SocketClient: lastConfigured(multilineIdle) != responseTimeout
    SocketClient->>Darwin: configureReceiveTimeout(responseTimeout)
    Darwin-->>SocketClient: timeout reset correctly
Loading

Reviews (3): Last reviewed commit: "Address CI review feedback" | Re-trigger Greptile

Comment thread scripts/install-zig-ci.sh
Comment on lines +56 to +61
if ! download_file "$ZIG_MIRROR_URL" "$ZIG_TAR"; then
echo "Mirror download failed; retrying from ${ZIG_OFFICIAL_URL}" >&2
download_file "$ZIG_OFFICIAL_URL" "$ZIG_TAR"
fi
download_file "${ZIG_OFFICIAL_URL}.minisig" "$ZIG_SIG"
minisign -Vm "$ZIG_TAR" -x "$ZIG_SIG" -P "$ZIG_MINISIGN_PUBLIC_KEY"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 No official fallback after mirror content fails minisign

The script falls back to the official URL only when download_file itself fails (e.g., HTTP error, network timeout). If the mirror returns HTTP 200 but serves stale or wrong content — for example a cached 0.14.x tarball while CI expects 0.15.2 — minisign will fail and set -euo pipefail will abort the script with no further attempt. CI would then be stuck until someone overrides ZIG_MIRROR_URL manually.

Comment thread CLI/cmux.swift Outdated
Comment on lines +1046 to +1050
var configuredReceiveTimeout = Self.responseTimeoutSeconds
if initialResponseTimeout != configuredReceiveTimeout {
try configureReceiveTimeout(initialResponseTimeout)
configuredReceiveTimeout = initialResponseTimeout
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Stale receive timeout on socket reuse

configuredReceiveTimeout is initialised to Self.responseTimeoutSeconds, but that only matches the socket's actual state immediately after connectOnce(). For non-relay sockets the connection is reused across multiple send() calls; if a previous call entered the multiline-response phase it leaves the socket with Self.multilineResponseIdleTimeoutSeconds (0.12 s). The next call with responseTimeout == nil evaluates initialResponseTimeout == configuredReceiveTimeout as equal and skips the pre-loop setsockopt. The first read() then hits EAGAIN after 0.12 s instead of the expected initial timeout, and the error branch at !sawNewline throws "Command timed out" on a healthy socket.

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cmuxTests/AppDelegateShortcutRoutingTests.swift (1)

53-106: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

CI blocker: this file is over the enforced Swift length budget.

The pipeline is failing with actual=5577 vs budget=5556. Please split part of this class (for example, move the isolated keyboard-shortcut settings harness and related tests into a companion test file) so CI can pass without budget override.

Also applies to: 125-129

🤖 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 `@cmuxTests/AppDelegateShortcutRoutingTests.swift` around lines 53 - 106, This
file exceeds the Swift length budget; extract the isolated keyboard-shortcut
settings harness and its related tests into a new companion test file: move the
temporarySettingsDirectoryURL property,
makeKeyEvent(_:characters:charactersIgnoringModifiers:keyCode:), setUp()
teardown/cleanup logic that manipulates executionTimeAllowance,
actionsWithPersistedShortcut, savedShortcutsByAction, originalSettingsFileStore,
and the code that assigns KeyboardShortcutSettings.settingsFileStore to a
KeyboardShortcutSettingsFileStore into the new test file (also move any tests
referencing those symbols), update imports and test class name accordingly, and
ensure the new file contains the matching tearDown that restores
KeyboardShortcutSettings.settingsFileStore and persisted UserDefaults; apply the
same extraction for the code referenced at lines ~125-129 that belongs to this
harness.
🤖 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 `@CLI/cmux.swift`:
- Around line 1046-1050: The local variable configuredReceiveTimeout in send()
can drift from the actual socket SO_RCVTIMEO across calls when relayEndpoint ==
nil; fix by ensuring the socket's timeout is restored at the start of every
send(): either unconditionally call
configureReceiveTimeout(initialResponseTimeout) at the top of send(), or add an
instance property (e.g., lastConfiguredReceiveTimeout) on SocketClient and
update/compare that instead of a local var so the guard reflects real socket
state; update configureReceiveTimeout and places that change the timeout
(including the multilineResponseIdleTimeoutSeconds adjustment) to maintain
lastConfiguredReceiveTimeout whenever the kernel socket option is modified.

In `@scripts/install-zig-ci.sh`:
- Around line 56-60: The script only falls back to the official URL for the
tarball but always downloads the .minisig from ZIG_OFFICIAL_URL; update the
.minisig download to mirror the tarball logic by first trying download_file
"$ZIG_MIRROR_URL".minisig to "$ZIG_SIG" and, on failure, echo a retry message
and call download_file "$ZIG_OFFICIAL_URL".minisig to "$ZIG_SIG" (use the same
retry/fallback pattern and the existing variables ZIG_MIRROR_URL,
ZIG_OFFICIAL_URL, ZIG_TAR, ZIG_SIG and the download_file function).
- Around line 7-9: The startup check currently uses a prefix regex (grep -q
"^${ZIG_REQUIRED}") which can falsely match longer versions; change the version
check to require exact equality of the output of `zig version` against the
ZIG_REQUIRED variable (e.g., compare the full version string or use grep -x for
exact match) so only the exact version is accepted; additionally, update the
minisig download logic (the same area that fetches the tarball/mirror fallback)
to try the mirror minisig URL first and fall back to the official minisig URL on
failure just like the tarball fetch does, ensuring both tarball and minisig
follow the same mirror fallback behavior (refer to the ZIG_REQUIRED variable,
the initial zig version check block, and the minisig/tarball download code
around the mirror fallback).

In `@Sources/KeyboardShortcutContext.swift`:
- Around line 133-141: The helper shortcutFocusedBrowserPanel(in:) wrongly falls
back to the global tabManager when a specific NSWindow was supplied but not
found in mainWindowContexts, allowing cross-window shortcut routing; change
shortcutFocusedBrowserPanel(in:) so that if a non-nil window is passed and no
matching context is found it returns nil (instead of returning
tabManager?.focusedBrowserPanel), otherwise keep existing behavior for nil
window by returning tabManager?.focusedBrowserPanel; update references to
mainWindowContexts, tabManager, and focusedBrowserPanel inside
shortcutFocusedBrowserPanel(in:) accordingly.

---

Outside diff comments:
In `@cmuxTests/AppDelegateShortcutRoutingTests.swift`:
- Around line 53-106: This file exceeds the Swift length budget; extract the
isolated keyboard-shortcut settings harness and its related tests into a new
companion test file: move the temporarySettingsDirectoryURL property,
makeKeyEvent(_:characters:charactersIgnoringModifiers:keyCode:), setUp()
teardown/cleanup logic that manipulates executionTimeAllowance,
actionsWithPersistedShortcut, savedShortcutsByAction, originalSettingsFileStore,
and the code that assigns KeyboardShortcutSettings.settingsFileStore to a
KeyboardShortcutSettingsFileStore into the new test file (also move any tests
referencing those symbols), update imports and test class name accordingly, and
ensure the new file contains the matching tearDown that restores
KeyboardShortcutSettings.settingsFileStore and persisted UserDefaults; apply the
same extraction for the code referenced at lines ~125-129 that belongs to this
harness.
🪄 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: fe35da4d-2513-447c-a7ee-3e20b1951783

📥 Commits

Reviewing files that changed from the base of the PR and between 65706d0 and 05a97d8.

📒 Files selected for processing (14)
  • .circleci/config.yml
  • .github/workflows/build-ghosttykit.yml
  • .github/workflows/ci-macos-compat.yml
  • .github/workflows/ci.yml
  • .github/workflows/nightly.yml
  • .github/workflows/perf-activation.yml
  • .github/workflows/release.yml
  • .github/workflows/test-depot.yml
  • .github/workflows/test-e2e.yml
  • CLI/cmux.swift
  • Sources/KeyboardShortcutContext.swift
  • cmuxTests/AppDelegateRenameShortcutContextTests.swift
  • cmuxTests/AppDelegateShortcutRoutingTests.swift
  • scripts/install-zig-ci.sh

Comment thread CLI/cmux.swift Outdated
Comment thread scripts/install-zig-ci.sh Outdated
Comment thread scripts/install-zig-ci.sh Outdated
Comment thread Sources/KeyboardShortcutContext.swift

This branch was successfully deployed

1 active deployment
Preview – cmux — 618d619b Deployed May 6, 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