Skip to main content
← Back to Blog

How to choose the Xcode version in GitHub Actions

Pin the Xcode path with DEVELOPER_DIR in the workflow, not with the runs-on label. The default Xcode on xenoci-macos is 27.0.

How to choose the Xcode version in GitHub Actions

The runs-on label picks which macOS image the job runs on; the workflow picks which Xcode to use inside it. If you set nothing, the image’s default Xcode runs, and that default changes when the image changes. The numbers below were checked against the runner images overview (Xcode list recorded 2026-09-25). data_asof: 2026-10-06.

1. Three ways to choose Xcode

  • DEVELOPER_DIR — write the app path literally in the job or step env, for example DEVELOPER_DIR: /Applications/Xcode_26.6.app/Contents/Developer. It applies only to that job or step without changing system settings.
  • setup-xcode action — give maxim-lobanov/setup-xcode a numeric xcode-version: "26.6". latest and latest-stable are not numeric pins.
  • xcode-select — in a step run, put the same app path after xcode-select -s (or --switch). It changes the system-wide selection, so it needs administrator rights.

XenoCI recognizes these three as a version requirement when they are written literally in the workflow. Versions computed from variables or expressions, and paths changed inside repository scripts, are not analyzed.

2. Xcode installed on xenoci-macos

For the macOS 26.6.2 image. data_asof: 2026-10-06 (runner images overview; Xcode list recorded 2026-09-25).

XcodeAvailabilityiOS simulator runtimeNote
27.0Always available27.0Default Xcode
26.6Always available26.5Simulator jobs need a host with the compatible iOS 26.5 runtime
26.2 · 26.3 · 26.4.1 · 26.5Some runners onlyNot verifiedNot present on every job

Availability means the Xcode toolchain is installed; it does not mean every job VM has that simulator runtime. Treat the tool inventory and the runner images overview as the source of truth.

3. Workflow examples

This pins Xcode 26.6 for the whole job with DEVELOPER_DIR. The xcodebuild -version step records the version actually used in the log. Change the scheme name to match your project.

name: build
on: [push, workflow_dispatch]

jobs:
  ios:
    runs-on: xenoci-macos
    env:
      DEVELOPER_DIR: /Applications/Xcode_26.6.app/Contents/Developer
    steps:
      - uses: actions/checkout@v4
      - run: xcodebuild -version
      - run: xcodebuild -scheme App -destination 'generic/platform=iOS' build CODE_SIGNING_ALLOWED=NO

To check several versions, split them into one job per version instead of a matrix, and write each numeric version literally. Below are a default Xcode (27.0) job and a job pinned to 26.6 with setup-xcode.

name: xcode-versions
on: [push, workflow_dispatch]

jobs:
  xcode-default:
    runs-on: xenoci-macos
    steps:
      - uses: actions/checkout@v4
      - run: xcodebuild -version
      - run: xcodebuild -scheme App -destination 'generic/platform=iOS' build CODE_SIGNING_ALLOWED=NO

  xcode-26-6:
    runs-on: xenoci-macos
    steps:
      - uses: actions/checkout@v4
      - uses: maxim-lobanov/setup-xcode@v1
        with:
          xcode-version: "26.6"
      - run: xcodebuild -version
      - run: xcodebuild -scheme App -destination 'generic/platform=iOS' build CODE_SIGNING_ALLOWED=NO

4. Jobs that use the simulator

A version pin alone does not identify a simulator runtime requirement. Writing -sdk iphonesimulator or -destination 'generic/platform=iOS Simulator' directly in a step run requests the runtime that matches that Xcode, and an explicit OS such as -destination 'platform=iOS Simulator,OS=26.5' takes precedence. When the requirement is recognized and no host with a compatible runtime is free, the job waits. Per the runner images overview, an Xcode 26.6 simulator job has not yet been verified from allocation through a successful build.

5. Common failures

  • An Xcode not in the image — the job starts and fails at that step, and the time run until then counts toward usage. Check the table above first.
  • No pin — when the image channel is promoted, the default Xcode changes and the same workflow can run on a different Xcode.
  • Mixed labels — if runs-on mixes labels other than xenoci-macos, XenoCI does not pick up the job and it stays queued on GitHub. No charge occurs in that case.

6. Read next

See the runner images overview for the Xcode list and simulator runtimes, the tool inventory for every installed tool, GitHub Actions integration for connection steps, and what to check when a macOS runner feels slow for slow jobs.

FAQ

Can I pick the Xcode version with the runs-on label?

No. There is one label, xenoci-macos, and it selects the image channel. Choose Xcode inside the workflow with DEVELOPER_DIR, the setup-xcode xcode-version input, or xcode-select. (Runner images overview, data_asof 2026-10-06)

Which Xcode runs if I do not pin a version?

The image’s default Xcode runs; today that is 27.0. Promoting the channel to a newer image changes the default, so pin a version if you need it to stay the same. (Runner images overview, data_asof 2026-10-06)

How do I test against several Xcode versions?

Create one job per version and write the numeric version or app path literally in each. Versions computed from matrix variables or expressions, and latest or latest-stable, are not recognized as pins at allocation. (Runner images overview, data_asof 2026-10-06)

Learn more

Check the docs and get started today.