Do GitHub Actions Runners Support macOS?

Yes. GitHub Actions runs macOS jobs on ARM64 runners such as warp-macos-15-arm64-6x, which carries 6 vCPU and 22GB of memory at $0.08 per minute.

Last verified:

Yes. GitHub Actions runs macOS jobs on ARM64 macOS runners, and moving a job onto one is a single runs-on change to a label such as warp-macos-15-arm64-6x, which provisions 6 vCPU with 22GB of memory and a 120GB SSD at $0.08 per minute. WarpBuild provides Linux x64, Linux ARM64, macOS, and Windows runners, and the macOS line is ARM64 only (WarpBuild cloud runners, checked on 2026-08-13).

This page covers what macOS support actually means on a GitHub Actions runner: which images and labels exist, what ships on each image, the two limits that catch teams out on their first macOS run, and what a macOS minute costs against GitHub's published list price.

Answer

macOS runners exist in three shapes under GitHub Actions, and all three run real macOS on Apple hardware.

GitHub-hosted macOS runners. GitHub publishes macos-latest, versioned labels such as macos-15, and larger macOS runners on paid plans. Rates are on the GitHub Actions billing reference and the GitHub pricing page.

Self-hosted Macs. The runner agent ships a macOS ARM64 release on github.com/actions/runner, so a Mac you own can register against a repository or organization and advertise labels. You own the hardware, the image, the Xcode installs, and the cleanup between jobs.

Managed macOS runners. A provider registers ephemeral macOS virtual machines against your GitHub organization and you select them by label. WarpBuild runs this shape, and the catalog carries multiple sizes and configurations per chip.

Five WarpBuild labels cover three macOS images. Every row comes from the cloud runners documentation, checked on 2026-08-13.

Runner labelOSvCPUMemoryStoragePer minuteAlias
warp-macos-26-arm64-6xmacOS 26622GB120GB SSD$0.08none
warp-macos-26-arm64-12xmacOS 261244GB270GB SSD$0.16none
warp-macos-15-arm64-6xmacOS 15622GB120GB SSD$0.08warp-macos-latest-arm64-6x
warp-macos-15-arm64-12xmacOS 151244GB270GB SSD$0.16warp-macos-latest-arm64-12x
warp-macos-14-arm64-6xmacOS 14622GB120GB SSD$0.08none

Two facts about this table change how you pin. macOS 13 runners were removed on June 8, 2026, so any workflow still naming warp-macos-13-arm64-6x fails to find a runner and has to move to macOS 14, macOS 15, or macOS 26. The latest aliases resolve to the macOS 15 image, in sync with GitHub's own macos-latest tag, so a job that must stay on one image should name the versioned label instead of the alias.

A workflow that already runs on macos-latest needs one line changed:

name: ios-ci

on:
  pull_request:
  push:
    branches: [main]

jobs:
  test:
    runs-on: warp-macos-15-arm64-6x
    steps:
      - uses: actions/checkout@v4

      - name: Record the toolchain
        run: |
          sw_vers
          uname -m
          xcodebuild -version

      - name: Resolve Swift package dependencies
        run: xcodebuild -resolvePackageDependencies -project App.xcodeproj

      - name: Build and test
        run: |
          xcodebuild test \
            -project App.xcodeproj \
            -scheme App \
            -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest' \
            -resultBundlePath TestResults.xcresult

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: xcresult
          path: TestResults.xcresult

uname -m prints arm64 on that runner and sw_vers prints the image version, which is worth keeping in the log while you are moving labels around.

Detail

What ships on each macOS image

The tooling on a WarpBuild macOS runner is the same set that the matching GitHub-hosted image carries, so the images work as drop-in targets for an existing Xcode workflow. The package lists are published per image by GitHub: macOS 14 ARM64, macOS 15 ARM64, and macOS 26 ARM64. Read the list for the image you are pinning before you assume a Ruby, Node, or Xcode version is present, because the three images do not carry identical sets.

The macOS 26 labels carry one addition. warp-macos-26-arm64-6x and warp-macos-26-arm64-12x ship Xcode 27.0 (build 27A5194q) on top of the Xcode versions already in the upstream GitHub macOS 26 image, along with the iOS 27.0, tvOS 27.0, watchOS 27.0, and visionOS 27.0 simulator runtimes (cloud runners documentation). That addition exists while GitHub's upstream macOS 27 runner image is in beta, and a dedicated macOS 27 image follows once that image is released. Plan for a re-pin of your DEVELOPER_DIR path at that switch. The per-image Xcode and simulator matrix lives on the Xcode image reference.

Tailscale is preinstalled on every runner image, including macOS, with the daemon started on demand when networking is configured for the runner (preinstalled software documentation).

The two limits that catch teams out

No Docker and no nested virtualization. macOS runners do not support nested virtualization and cannot run Docker (cloud runners documentation). A workflow that builds an iOS app and then packages a container image needs two jobs on two platforms. Move the container half of the pipeline to a Linux runner or a remote Docker builder while the macOS job keeps the Xcode, Swift, and simulator work. The Docker on macOS runners answer covers the workarounds that people try first and why they fail.

Concurrency on macOS is quota governed. Since July 27, 2026, concurrency on the macOS fleet is governed by per-organization quotas, and jobs beyond the quota wait for capacity to free up (July 2026 changelog). Teams that need a wide macOS fan-out should size the matrix against the quota their organization holds and contact support to raise it, rather than assuming the Linux and Windows behavior carries over. Runner storage is ephemeral in all cases, so derived data, simulator logs, and build products go to an artifact or a cache before the job ends.

What a macOS minute costs

Both sides of this comparison are list prices. WarpBuild rates come from the cloud runners documentation. GitHub rates come from the GitHub Actions billing reference and the GitHub pricing page, checked on 2026-08-13.

WarpBuild labelShapeWarpBuild per minuteGitHub-hosted comparisonGitHub per minuteDifference
warp-macos-15-arm64-6x6 vCPU, 22GB$0.08Largest GitHub-hosted macOS ARM64 runner, 5 vCPU with 14GB$0.10222 percent lower list price
warp-macos-15-arm64-12x12 vCPU, 44GB$0.16Shape-matched comparison unavailable at 12 vCPUnot comparedsee the per vCPU-minute figures below

Per vCPU-minute the 6 vCPU row works out to $0.0133 against $0.0204 for the GitHub ARM64 larger runner, and the runner carries one more vCPU and 8GB more memory at the lower rate. The 12 vCPU size sits at the same $0.0133 per vCPU-minute, so doubling the machine doubles the bill and nothing else.

Worked model: one iOS repository. The repository merges enough pull requests to queue 900 macOS jobs a month, each running 14 minutes on a 6 vCPU runner. That is 12,600 macOS minutes.

  • warp-macos-15-arm64-6x at $0.08 per minute: 12,600 x $0.08 = $1,008.00 per month.
  • Largest GitHub-hosted macOS ARM64 runner at $0.102 per minute: 12,600 x $0.102 = $1,285.20 per month.
  • Difference: $277.20 per month, $3,326.40 over twelve months, which is 22 percent lower list price (GitHub pricing, checked on 2026-08-13).
  • The $10 in signup credits covers the first $10 of that bill, so month one lands at $998.00 out of pocket at this volume.

Run the same arithmetic with your own job count and minute length on the macOS runner cost guide before you commit to a label.

Which macOS versions run on WarpBuild GitHub Actions runners?

Three images across five labels: macOS 26, macOS 15, and macOS 14. macOS 13 runners were removed on June 8, 2026, so a job still pinned to warp-macos-13-arm64-6x has to move to one of the three remaining images. The full label list with sizes and rates is on the macOS runner catalog.

Can a macOS GitHub Actions runner run Docker?

No. macOS runners do not support nested virtualization and cannot run Docker. Send container builds to Linux runners or to remote Docker builders, and keep the macOS job for Xcode, Swift, and simulator work. The Docker on macOS runners answer has the job split that works.

Which Xcode versions ship on the macOS runner images?

Each image carries the Xcode versions of the upstream GitHub image it is built from. The macOS 26 labels additionally ship Xcode 27.0 (build 27A5194q) with the iOS, tvOS, watchOS, and visionOS 27.0 simulator runtimes, while GitHub's upstream macOS 27 runner image is in beta. The per-image matrix is on the Xcode image reference.

What do macOS GitHub Actions runners cost per minute?

The 6 vCPU size is $0.08 per minute and the 12 vCPU size is $0.16 per minute. GitHub lists its largest macOS ARM64 runner, 5 vCPU with 14GB of memory, at $0.102 per minute (GitHub Actions billing reference, checked on 2026-08-13). The macOS runner cost guide works the monthly model, and every rate is on the pricing page.

Pick a label from the macOS runner catalog, check the Xcode set for that image on the Xcode image reference, and change one runs-on line to move the job.

Start with $10 in free credits

Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.