Updated September 5, 2026

Which Xcode does macos-latest run, and how do you pin it?

Short answer: macos-latest is an alias, not a version. At the time of writing it points at the macOS 26 arm64 image, and GitHub moves the alias to a new macOS release over a one-to-two-month window. Inside an image, GitHub ships one major Xcode and replaces patch versions as they are released. So the Xcode your build sees can change between two runs with no commit in between.

Find out what you are actually running

- run: |
    sw_vers
    xcodebuild -version
    xcode-select -p
    ls /Applications | grep Xcode

Put this as the first step of any macOS job. When a build breaks "on its own", the log tells you whether the image moved. The authoritative list of installed Xcodes per image is in actions/runner-images.

Pin on GitHub-hosted runners

Two levels. First, stop using the alias: runs-on: macos-15 or macos-26. Second, select the Xcode inside the image explicitly, because the image still carries several:

- run: sudo xcode-select -s /Applications/Xcode_16.4.app
# or
- uses: maxim-lobanov/setup-xcode@v1
  with:
    xcode-version: '16.4'

This pins the major and minor, but the patch can still be swapped when GitHub refreshes the image, and old Xcodes are removed when a macOS image is retired.

Pin on Manzanita

The label is the pin. manzanita-standard is macOS Tahoe 26.6.2 with Xcode 26.6 (17F113) at /Applications/Xcode.app; manzanita-xcode16 is macOS 15.7.7 with Xcode 16.4. Each image has an immutable ID and digest, and a label is never moved to a new major Xcode without notice and an overlap period. No xcode-select step is needed, and there is nothing else to select.

jobs:
  test:
    runs-on: manzanita-standard      # Xcode 26.6
  legacy:
    runs-on: manzanita-xcode16       # Xcode 16.4

Current versions and the release policy are in the image contract; every promotion is listed in the changelog.

Deployment target is not the runtime

An app with an iOS 13 deployment target compiles fine with Xcode 26.6. Whether it is tested on iOS 13 depends on which simulator runtimes are installed, which is a separate question covered in the simulator guide.

Try it on your own workflow. One Standard runner is free for 14 days or 300 build minutes, no card. Change runs-on to manzanita-standard and keep everything else. Start free · Read the docs

Related