Wrong Xcode version in GitHub Actions
To check the Xcode version in a GitHub Actions job, run xcodebuild -version in a step. To pick one, select its path with xcode-select, or on your own Mac, ask for it with a runner label.
The short answer
A build breaks on the wrong Xcode when the runner's default moves. You may see new compiler errors, missing SDKs or a Swift version that doesn't match your project. First check the Xcode version the job really used. Then pin it, so it can't change under you.
Check which Xcode a job uses
Add this step to any macOS job. It shows what Xcode the job uses, where it lives, and which others are installed:
- name: Show Xcode
run: |
xcodebuild -version
xcode-select -p
ls -d /Applications/Xcode*
The log then shows lines like these:
Xcode 16.4
Build version 16F6
/Applications/Xcode_16.4.app/Contents/Developer
Run this step early in the job, so the answer sits at the top of the log. The same three commands find the Xcode version on your own Mac, in Terminal.
Select a version with xcode-select
On GitHub's Macs, each Xcode lives at a path like /Applications/Xcode_16.4.app. Switch to one before you build:
- name: Use Xcode 16.4
run: sudo xcode-select -s /Applications/Xcode_16.4.app
- run: xcodebuild -version
To skip sudo, set DEVELOPER_DIR for the job instead:
env:
DEVELOPER_DIR: /Applications/Xcode_16.4.app/Contents/Developer
Pick a version the image really has. The list is in GitHub's runner-images repo.
Why macos-latest changes under you
macos-latest moves to a newer image over time. An image's default Xcode can change too. So a build that worked last week can break with no change from you. Pin both the image, such as macos-15, and the Xcode path. Watch the runner-images repo for notices before a big change lands.
Pin Xcode with runner labels
On your own Mac, Codemany adds labels for Xcode. Every Mac with Xcode gets a plain xcode. It also gets one that follows the Xcode chosen with xcode-select, such as xcode-26.0.
runs-on: [self-hosted, codemany, xcode-26.0]
Ask for xcode when any Xcode will do. Pin xcode-26.0 when the build needs that one. After a switch, jobs asking for the old one wait. They never build with the wrong toolchain. If no Mac has that Xcode, the job stays queued on GitHub. Install that Xcode, or change the label. All labels are in Runner labels.
Install another Xcode on your Mac
Download the Xcode .xip from Apple yourself. In the Codemany app, add it with Add .xip…. Codemany installs it at GitHub's path, /Applications/Xcode_<version>.app. Your other Macs copy it from that Mac, so you download each version once. Codemany checks your tools every 30 minutes, so new Xcode labels show up by themselves.
Then sudo xcode-select -s /Applications/Xcode_16.4.app in a job picks that Xcode for that job only. It needs no password, and other jobs keep their own Xcode. Codemany needs an Apple silicon Mac with macOS 14 or later. Read iOS and Xcode builds, the Mac runner guide and Mac runners. Builds are slow too? See slow macOS jobs.
Questions
How do I check the Xcode version in a job?
Run xcodebuild -version in a step.
How do I pick an Xcode version?
Use sudo xcode-select -s with the Xcode path, or a label such as xcode-26.0 on Codemany.
Do I need Intel Macs for old Xcode?
Codemany needs Apple silicon; check that your Xcode runs there.
Related
Read next: iOS and Xcode builds, Mac runner guide, Mac runners and runner labels.
Start a 14-day trial $20 a month for 2 machines. No card needed.