What are the main ways to run iOS CI/CD (Xcode Cloud, GitHub Actions, Fastlane, others), and what do they all call underneath?

25.2.1 · L3 · Interview

Predict first

Do the xcodebuild options for archiving, exporting and API-key authentication exist?

// === dummy ===
  • Yes, all of them
  • Only -archivePath exists
  • No: archiving needs the Xcode GUI

Predict first

Does the notarisation tool offer subcommands for storing credentials, submitting and listing history?

// === dummy ===
  • Yes: history, store-credentials, submit
  • No, notarisation is only in the browser
  • Only submit

Mental model. CI providers are different kitchens; xcodebuild is the knife they all use. Learn the knife and you can cook in any kitchen.

Every option ends in the same command-line tools, so learn those first. xcodebuild builds and tests (build-for-testing, test-without-building), and releases use two steps: xcodebuild archive -archivePath … produces an .xcarchive, then xcodebuild -exportArchive -archivePath … -exportOptionsPlist ExportOptions.plist -exportPath … produces the signed .ipa for the chosen method (app-store, ad hoc, development). Signing can be automated with an App Store Connect API key (-allowProvisioningUpdates with -authenticationKeyPath, -authenticationKeyID and -authenticationKeyIssuerID), which avoids storing an Apple ID password; the check below confirms those options exist. Mac apps are notarised with xcrun notarytool (store-credentials, submit, history), and uploads to App Store Connect go through Xcode’s upload step, the App Store Connect API or Transporter (check Apple’s current guidance on older command-line upload tools).

The tools differ in how much they wrap that. Xcode Cloud is Apple’s hosted CI: workflows defined in Xcode and App Store Connect, signing managed by Apple’s cloud, direct TestFlight integration, simple to start with and less flexible for unusual steps. GitHub Actions (or GitLab, Bitrise, Jenkins, CircleCI) give you a general runner: hosted macOS machines or your own, full control over steps and caching, and you handle signing and secrets yourself. Fastlane is a Ruby toolbox that scripts the repetitive parts as lanes: gym (build and export), scan (test), match (certificates and profiles in an encrypted repository), pilot (TestFlight), deliver (metadata and submission) and it runs inside any CI. Choose by control and cost: start with the simplest that handles your signing and TestFlight upload, keep the logic in versioned scripts rather than in the CI provider’s UI so you can run a release locally, and pin the Xcode version so builds do not change when the runner image does.

The whole archive, export and signing flow is scriptable from the command line, which is what every CI tool wraps.

notarytool is the supported command-line client for notarisation, so a Mac release can be scripted.

Common traps

  • Putting release logic only in a CI provider’s web UI. It cannot be reviewed, versioned or run locally when the CI is down.
  • Letting the runner’s default Xcode version drift. A new image changes the toolchain and a green pipeline turns red for no code reason.

They might follow up with

  • How do you sign without an Apple ID password? An App Store Connect API key passed to xcodebuild, or managed signing in Xcode Cloud.
  • What does -exportOptionsPlist decide? The export method, team, signing style and options such as symbols and bitcode-era settings.

Related questions

  • 25.2.3 How do you design a release pipeline: hermetic builds, secrets, caching, artefact promotion and the order of…
  • 25.2.2 How do marketing versions and build numbers work, how should CI generate them, and which rules does App Store…
  • 25.1.1 How does iOS code signing work: certificates, App IDs, provisioning profiles, signing identities, export…
  • 16.6.1 A CI pipeline takes hours on a large modular app. How do you analyse and cut it: affected builds, caching…
  • 20.3.2 What does a Mac app need that an iOS app does not: the menu bar, windows, the App Sandbox, Hardened Runtime…

How do marketing versions and build numbers work, how should CI… →