Updated September 9, 2026

Apple Silicon runners, without a second CI platform.

Manzanita supplies ephemeral macOS machines to GitHub Actions. GitHub remains the control plane for workflow syntax, secrets, logs, artifacts, approvals, and job queues.

Quickstart

  1. Sign in with GitHub and open the dashboard's GitHub page. Install the Manzanita GitHub App on only the repositories that need macOS CI; the installation is verified against your GitHub sign-in before it is connected, and only an organization owner can connect an organization.
  2. Private repositories selected in the installation are enabled for review. Public repositories start disabled and require an explicit opt-in in the GitHub connection page. Installing the App activates one best-effort trial runner automatically. The trial ends after 14 days or 300 build minutes, whichever comes first. Its clock begins with the first runner job, not at sign-in.
  3. Change one line in your workflow:
  4. Keep an instant fallback during the pilot: set a repository variable named MACOS_RUNNER to manzanita-standard, then use ${{ vars.MACOS_RUNNER || 'macos-15' }} in runs-on. Switching the variable routes the next build without a workflow commit.
jobs:
test:
runs-on: manzanita-standard
steps:
- uses: actions/checkout@v5
- run: swift test

No proprietary workflow file is required. Existing GitHub Actions, environments, caches, artifacts, and repository secrets continue to work.

Runner labels and concurrency

Label Profile Capacity
manzanita-standard M4 Pro · 6 vCPU · 22 GB Moving default after advance notice · Xcode 26.6
manzanita-xl M4 Pro · 12 vCPU · 44 GB One concurrent full-host job · Xcode 26.6
manzanita-xcode16 M4 Pro · 6 vCPU · 22 GB Compatibility channel · Xcode 16.4

Simulator matrix

Runtime Prewarmed device Contract
iOS 17.5 iPhone 15 Pro workflow destination Installed and qualified with unchanged Tealium tests
iOS 18.6 Available to workflows Installed and covered by the machine-readable image contract
iOS 26.5 iPhone 17 Pro Installed, booted once during image build, then shut down cleanly
tvOS 26.5 Apple TV workflow destination Installed and qualified with unchanged Tealium tests
watchOS 26.5 Series 11, Ultra, and SE device types Installed and qualified with an unchanged Watch app build

Other device types exposed by an installed runtime may be created by a workflow, but only the entries above are covered by the current image contract. VisionOS is not currently installed. Consult the current Standard manifest when checking workflow compatibility.

The app's deployment target and the simulator runtime are different compatibility signals. An app that targets iOS 13 can compile cleanly with Xcode 26.6 while this image still exercises it only on iOS 26.5. Teams that require behavioral coverage on older iOS releases should keep those matrix lanes on another runner until Manzanita publishes the corresponding runtime in this table.

Differences from GitHub macos-15

Area Manzanita Standard Migration note
Xcode One pinned Xcode per immutable channel Use manzanita-xcode16 when 16.4 is required; do not select an arbitrary preinstalled version.
PATH aliases python and python3; Homebrew arm64 paths enabled Prefer explicit tool versions in workflows.
Ruby tooling CocoaPods and Fastlane installed; xcpretty is not part of the current contract Install unlisted gems in the workflow or pin them with Bundler.
sudo Available for ordinary CI setup; every VM is disposable Do not rely on host persistence between jobs.
Keychain Login keychain is unlocked for the job; no signing identity is preinstalled Unsigned archives are ordinary build output, but code signing, notarization, TestFlight/App Store upload, and release secrets remain unsupported in the pilot.
Job lifetime Maximum two hours per job Split longer workflows into dependent jobs.

This pilot boundary is a security and support decision, not an Xcode limitation. GitHub Actions secrets can reach an authorized runner, but Manzanita does not yet claim the audited import, isolation, and destruction lifecycle required for signing identities. Keep release jobs on a protected runner and use Manzanita for build, test, and GUI validation until that contract is published.

A Standard subscription runs one 6-vCPU/22-GB job at a time. Add Standard runners for parallel jobs. XL runs one 12-vCPU/44-GB job at a time and consumes the full host. Jobs above purchased concurrency remain queued in GitHub, where their normal logs and status stay visible.

Images and toolchains

Choose macOS and Xcode →

Select macOS 15 or macOS 26, an installed Xcode version, and Standard or XL hardware. The selector generates the workflow configuration and shows the current software inventory. Exact Xcode selectors never substitute a different version.

The Standard image is immutable and validated on staging capacity before production nodes pull it. The exact digest used by each job is visible in the Jobs dashboard. Image changes are announced and retain an internal rollback image during migration. Existing labels remain supported; explicit OS selectors stay within the selected macOS major version.

Current default: Current Standard image, macOS Tahoe 26.6.2 with Xcode 26.6. Use manzanita-xcode16 only for projects that still require Xcode 16.4. Both channels are immutable and digest-pinned.

Available opt-in image: macOS 26 with exact Xcode 26.2, 26.5, and 26.6. It is prewarmed, has passed compatibility qualification, and is available through its exact Xcode selectors or immutable digest pin. The current default does not move.

Xcode 27 opt-in: macOS 26.6.2 with Xcode 27.0 and the iOS 27.0 Simulator. Select it with runs-on: [manzanita-standard, manzanita-xcode-27.0]. Jobs without the Xcode selector continue to use Xcode 26.6.

Component Standard image v7
2026-09-09 macos-26-xcode-26.2-26.5 Available · opt-in Adds exact Xcode 26.2 and 26.5 while retaining Xcode 26.6 as the image default. Vultisig and BeeSwift compatibility runs passed. Xcode 26.2 is qualified for macOS and iOS lanes; its matching watchOS, tvOS, and visionOS runtimes are not installed.
Architecture Apple Silicon arm64
macOS Tahoe 26.6.2
Xcode / Swift 26.6 (17F113) / 6.3.3
Python 3.14.7; both python3 and python
Node.js / Ruby / Java 24.20.0 / 4.0.6 / 17.0.20.1
CocoaPods / Fastlane 1.17.0 / 2.239.0
Locale / time zone en_US.UTF-8 / UTC
GUI contract Logged-in Aqua session, Accessibility enabled, persistent scrollbars, animations disabled

Download the machine-readable current Standard manifest. The stable URL follows the current default; immutable versioned manifests remain available for audit and migration checks. Each version records its lifecycle status and replacement without exposing provider-internal registry addresses.

Image release and Xcode policy

Release history

Date Image Status Change
2026-09-05 macos-tahoe-xcode-26.6-v4 Default Adds iOS 17.5 and 18.6, tvOS 26.5, and watchOS 26.5 runtimes; qualified against unchanged Cuckoo and Tealium build and test workflows, including a Watch application.
2026-09-05 macos-tahoe-xcode-26.6-v2 Superseded · retained in release history Adds the checksum-pinned GitHub macOS 26 arm64 Rust baseline and repository-selected Rust toolchains; qualified against TablePro's unchanged universal Rust bridge build.
2026-09-04 macos-tahoe-xcode-26.6-v1 Superseded Moves Xcode 26.6 to its Apple-supported Tahoe host, adds the conventional Xcode and Python paths, and qualifies real Sparkle and Rectangle application builds.
2026-09-04 macos-sequoia-xcode-26.6-v3 Superseded Adds the conventional /Applications/Xcode.app path and a bounded CI-only xed compatibility shim; qualified against unchanged Tealium and Cuckoo entry points.
2026-09-03 macos-sequoia-xcode-26.6-v1 Superseded Xcode 26.6, Swift 6.3.3, iOS 26.5 simulator runtime, and an immutable Xcode 16.4 compatibility channel.
2026-09-03 macos-sequoia-xcode-16.4-v2 Pilot Python compatibility alias, deterministic GUI preferences, and non-interactive Git credential policy.

Job lifecycle

  1. The GitHub App receives workflow_job.queued.
  2. The scheduler selects an entitled slot and issues a short-lived JIT runner token.
  3. The node clones a prewarmed golden image using APFS copy-on-write.
  4. The VM connects directly to GitHub, runs exactly one job, and uploads logs and artifacts there.
  5. The VM and token are destroyed. A clean replacement is prepared.

Caching

Use actions/cache exactly as on GitHub-hosted runners; nothing Manzanita-specific is required. Persistent provider-managed cache volumes are not yet part of the product, so explicitly cache the paths your build needs.

- uses: actions/cache@v4
with:
path: |
.build
~/Library/Developer/Xcode/DerivedData
key: ${{ runner.os }}-${{ runner.arch }}-spm-${{ hashFiles('Package.resolved') }}

Security model

Private package example

For an app such as acme/mobile-app that depends on acme/private-sdk, open Dashboard → GitHub → Private dependencies, choose acme/mobile-app under “Jobs from,” select acme/private-sdk, and save. This does not grant the reverse relationship or access from any other enabled repository.

Manzanita is dedicated-host CI infrastructure, not confidential computing. Sensitive secrets remain governed by GitHub Actions permissions and your workflow design. Do not expose deployment or signing secrets to untrusted pull-request code.

Billing and fair use

Plan Price Capacity
Standard $149/month 6 vCPU / 22 GB; one concurrent job
XL $299/month 12 vCPU / 44 GB; one concurrent job

Plans are flat-rate and have no metered overage charges. To protect responsive queues, usage above 15,000 minutes per runner in 30 days starts a capacity review. During contention, lower-utilization organizations receive scheduling priority while running jobs are never preempted.

The free trial is one best-effort Standard runner for 14 days or 300 build minutes, whichever happens first. Trial jobs may wait behind paid runner capacity. Stripe owns cards, invoices, cancellation, and the Customer Portal. Plans are billed monthly, require no annual prepayment, and may be cancelled at any time.

This invitation-only pilot has no contractual SLA. The first paid monthly charge is refundable within seven calendar days; later monthly charges follow the cancellation and refund rules in the pilot terms.

Troubleshooting

Keep a one-click GitHub-hosted fallback

During the pilot, set a repository variable such as MACOS_RUNNER and use it for runs-on. Set it to manzanita-standard normally; change it to macos-15 to route the next run back to GitHub without a workflow commit.

jobs:
test:
runs-on: ${{ vars.MACOS_RUNNER || 'manzanita-standard' }}
steps:
- uses: actions/checkout@v5
- run: swift test

Job stays queued

Confirm the GitHub App is installed for that repository and the repository is enabled on the dashboard's GitHub page, the label is spelled exactly, and your organization has an active trial or subscription. Jobs also queue normally when all purchased slots are busy.

Toolchain mismatch

Print xcodebuild -version and swift --version in the job. Pinning is deliberate; contact support before assuming xcode-select points at another beta.

Need help

Email hello@manzanita.run with the GitHub job URL, repository name, and approximate queue time. Never send repository or signing secrets.

Pilot service targets

These are operational targets for the invitation-only pilot, not a contractual SLA: p95 runner acquisition below two minutes, infrastructure-caused job failure below 1%, and acknowledgement of support email within four business hours (Pacific time). Active incidents and image changes are communicated to affected workspace owners by email. GitHub remains the source of truth for job logs and status.

How we measure time to runner

Every timing figure on this site and in the dashboard comes from the /api/dashboard/observability metrics over a rolling 30-day window of your own jobs (up to 1,000 most recent samples). Three intervals are reported separately and never added together silently:

Your own numbers for all three are on the Health & queue page, with sample counts, and per job on the Jobs page.

© 2026 Manzanita · Menlo Park, California.