* Cache Swift packages across CI runs
Add actions/cache for the SPM cloned source packages directory so
subsequent runs skip fetching Sparkle, sentry-cocoa, swift-markdown-ui,
posthog-ios, and NetworkImage from GitHub each time.
- nightly/release: replace the no-op SwiftPM cache step with
actions/cache + -clonedSourcePackagesDirPath on xcodebuild
- ci/ci-macos-compat/test-e2e: add actions/cache before the existing
resolve step, stop deleting the cache dir each run
* Include runner in test-e2e cache key
Consistent with ci-macos-compat.yml which uses matrix.os in the key.
Every merge to main already triggers a nightly build, making the hourly
cron redundant. The skipped job was cosmetic (just echoed a message) and
caused confusing red X statuses when cancel-in-progress kicked in.
Build immediately on merge instead of waiting for the hourly cron.
Concurrency group cancels in-progress builds when new commits land.
Depot macos runner replaced with GitHub macos-15 (similar perf, simpler).
* Migrate all workflows from self-hosted Mac Mini to Depot runners
Move CI, nightly, and release workflows to depot-macos-latest. Replace
zig GhosttyKit builds with pre-built xcframework downloads. Add virtual
display for CI UI tests. Remove concurrency groups (ephemeral VMs don't
need them).
* Add per-test timeout to CI UI tests to prevent hangs on Depot
SidebarResizeUITests hangs on headless Depot runners due to mouse drag
simulation issues. Adding -maximum-test-execution-time-allowance 120
(matching test-depot.yml) ensures individual tests timeout after 2 min
instead of blocking the entire run.
* Skip SidebarResizeUITests in CI on Depot runners
Mouse drag simulation hangs on headless Depot runners even with a
virtual display. The per-test timeout doesn't prevent the hang either.
Skip this test class in CI; it still runs fine on local machines.
* Handle XCTExpectFailure in CI UI tests (exit 65 with 0 unexpected)
xcodebuild exits 65 even when all failures use XCTExpectFailure. Add
the same expected-failure handling from the unit test step so browser
focus tests (which are expected to fail on headless runners) don't
break CI.
* Add virtual display for headless Depot runners
Depot macOS runners have no physical display, causing XCUITests to fail
with "Failed to activate application (current state: Running Background)".
This adds a small ObjC tool that creates a virtual display using the
private CGVirtualDisplay API before tests run.
* Split self-hosted concurrency groups per workflow
CI, nightly, and release all shared `self-hosted-build`, so the hourly
nightly cancelled in-progress CI runs. Now each workflow has its own
group (self-hosted-ci, self-hosted-nightly, self-hosted-release).
CI also gets cancel-in-progress: true so rapid pushes cancel stale runs.
After rm -rf of the SPM cache dir, recreate it as an empty directory
so binary target downloads (e.g. Sentry.xcframework.zip) don't hit
"already exists in file system" errors from stale artifacts on the
self-hosted runner.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Org policy now requires actions pinned to immutable SHAs instead of
mutable version tags. Pin actions/checkout, actions/github-script,
softprops/action-gh-release, and oven-sh/setup-bun across all workflows.
* Upgrade Sentry: tracing, breadcrumbs, dSYM upload
- Enhanced Sentry SDK init with performance tracing (10% sample),
explicit app hang timeout, stack trace attachment, and HTTP
failure capture
- Added breadcrumbs for key user actions: workspace switch/create/close,
split creation, command palette open/close, app focus — these give
context to hang/crash reports
- Added dSYM upload step to nightly and release CI workflows so hang
stacks are fully symbolicated (requires SENTRY_AUTH_TOKEN secret)
- Created SentryHelper.swift with lightweight breadcrumb helper
Closes https://github.com/manaflow-ai/cmux/issues/365
* Remove command palette breadcrumbs
Not useful for hang diagnosis — keep only workspace/tab/split/focus
breadcrumbs that correlate with heavy operations.
The decide job already skips when main HEAD matches the nightly tag,
so this only builds when there are actual changes. Hourly means users
get nightly updates within an hour of merging to main.
Follows the same pattern as AppIcon-Debug (orange DEV banner) but with
a purple banner and "NIGHTLY" text. The nightly CI workflow now passes
ASSETCATALOG_COMPILER_APPICON_NAME=AppIcon-Nightly to xcodebuild so
the nightly app gets its own distinct icon.
Includes scripts/generate_nightly_icon.py for regenerating the icons
from the production AppIcon source files.
The nightly build is now a distinct app called "cmux NIGHTLY" with
bundle ID com.cmuxterm.app.nightly, allowing side-by-side installation
with the stable release. The nightly appcast URL is baked into the
app's Info.plist by CI, so no in-app channel switching is needed.
- Nightly workflow: rename app to "cmux NIGHTLY", set bundle ID to
com.cmuxterm.app.nightly, hardcode nightly Sparkle feed URL, publish
DMG as cmux-nightly-macos.dmg
- Remove "Receive Nightly Builds" toggle from settings
- Remove UpdateChannelSettings enum and simplify feed URL resolution
to just use SUFeedURL from Info.plist
- Remove UpdateChannelSettingsTests (no longer applicable)
Hardened runtime's library validation was verifying every dylib on load,
causing noticeable UI lag. Add entitlements file with
disable-library-validation to fix while keeping notarization support.