Mobile Development7 min read

Mobile CI/CD

Automate iOS and Android build, test, and release pipelines with Fastlane, Xcode Cloud, and GitHub Actions for consistent, reliable delivery.

ci-cdmobileiosandroid

Mobile CI/CD automates the build, test, and release pipeline for iOS and Android apps. Without automation, releasing requires manual code signing, device registration, and upload steps-error-prone and slow. With CI/CD, a merged PR can trigger a TestFlight build and automated test run without human intervention.

Automate everything that can be automated: signing, versioning, testing, uploading. Use Fastlane for orchestration-it has plugins for every step. Test on simulators in CI; test on physical devices with Xcode Cloud or Firebase Test Lab.

Workflow

  1. Set up Fastlane for iOSFastlane unifies code signing, build, test, and deployment into reproducible lanes.
  2. Automate code signing with Fastlane MatchManual certificate management across team members causes "certificate expired" outages; Match syncs certificates via Git.
  3. Configure GitHub Actions for mobile CIGitHub Actions runs on macOS runners needed for iOS builds and integrates with the PR workflow.
  4. Automate Android builds and Play Store uploadPlay Store upload requires signing keystore, version management, and API credentials - all automatable.
  5. Implement versioning and release automationManual version bumping causes forgotten increments or version conflicts.

Output Format

Fastlane lanes for test/beta/release, Match for code signing, GitHub Actions workflow for iOS and Android, automated versioning, TestFlight and Play Store upload.

Examples

Fastfile beta lane: `lane :beta do increment_build_number; match(type: "appstore", readonly: true); gym(scheme: "MyApp"); pilot(notify_external_testers: false) end`
GitHub Actions iOS: `- uses: actions/cache@v4
  with:
    path: vendor/bundle
    key: gems-${{ hashFiles("Gemfile.lock") }}
- run: bundle install
- run: bundle exec fastlane test`
Android signing in CI: `echo "$KEYSTORE_BASE64" | base64 --decode > android/keystore.jks && ./gradlew bundleRelease -PKEYSTORE_PATH=keystore.jks -PKEYSTORE_PASSWORD=$KEY_PASS`

Edge Cases & Gotchas

  • Xcode version drift: pin Xcode version in CI with `xcodes select 16.2` or `xcode-select -s /Applications/Xcode_16.2.app`; mismatched versions break builds silently
  • Match conflicts: two CI jobs running simultaneously can cause Match conflicts when both try to generate certs; use readonly mode in CI, generate locally
  • APNs certificates in CI: push notification certificates are separate from signing certs; manage via App Store Connect API Keys, not Match

When to Break These Rules

  • Xcode Cloud (Apple's built-in CI) is simpler for small iOS teams and integrates directly with TestFlight without Match configuration - worth considering before setting up custom GitHub Actions runners.

Reference Files

  • Fastlane docs: https://docs.fastlane.tools/
  • Fastlane Match: https://docs.fastlane.tools/actions/match/
  • Xcode Cloud: https://developer.apple.com/xcode-cloud/
  • GitHub Actions macOS: https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners

More skills in this library

Browse all technical skills - Mobile, AI/ML, Web, Backend, Design, and Product.