Use runs-on: macos-15 or runs-on: macos-26 (GA as of February 2026) for GitHub-hosted macOS runners; macos-latest maps to macOS 15 since September 2025 and will eventually track macos-26
List available Xcode versions on the runner with ls /Applications/Xcode*.app; GitHub-hosted macOS images ship with multiple Xcode versions and keep at most three simulator runtimes (policy change effective August 2025)
Switch the active Xcode version with sudo xcode-select -s /Applications/Xcode_16.app/Contents/Developer before running xcodebuild commands
For self-hosted macOS runners, register an Apple Silicon Mac mini or Mac Studio as a runner (GitHub larger runners or your own hardware), install the runner agent, and set up Xcode and provisioning profiles manually
Cache derived data and SPM package caches with actions/cache using a key based on the Xcode version and Package.resolved hash to avoid re-fetching Swift packages on every run
For iOS simulator tests, call xcrun simctl list to see available simulators and pass the simulator UDID or device name to xcodebuild -destination 'platform=iOS Simulator,name=iPhone 16'
Known gotchas
macOS 13 GitHub-hosted runner images were retired December 4, 2025; workflows still referencing macos-13 will fail — update to macos-15 or macos-26
Self-hosted macOS runners must be updated to v2.329.0 or later before March 16, 2026 per GitHub's minimum-version enforcement policy; older runner agents will stop accepting jobs
Signing and notarization require valid Apple Developer credentials stored as secrets; do not hardcode certificate passphrases or API keys — use APPLE_CERTIFICATE_PASSWORD and similar secret names injected at job runtime
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp