Yashveer Singh
Connect
<- All posts
Cross Platform and Mobile Development12 min read

The Mobile Build Pipeline: Fastlane, EAS, and the Path of Least Pain

The mobile build pipeline is the automated system that takes source code, builds iOS and Android binaries, manages code signing, and distributes the app to TestFlight, Play Store internal tracks, or production. Without a build pipeline, every release requires a developer with the correct certificates, the correct Mac setup, and manual steps through App Store Connect. The build pipeline replaces this with a single command or a CI trigger that handles all of it reliably.

Written by Yashveer Singh, founder of Yashveer Labs.

What you actually need to know

  • Manual iOS builds require a Mac, valid certificates, and multiple steps through App Store Connect. Automating this eliminates the most common cause of release delays in mobile teams.
  • EAS Build is the lowest-friction path for React Native/Expo projects. It runs iOS builds in the cloud without requiring a Mac CI machine.
  • Fastlane is the right choice for Flutter, native iOS, and non-Expo React Native projects with more complex build requirements.
  • Fastlane match manages iOS certificates in a shared Git repository. It is the solution to the "my certificates expired and only one person knows how to renew them" problem.
  • The mobile build pipeline should produce TestFlight/internal track builds automatically on every merge to main, without anyone manually triggering a build.
ApproachBest ForiOS Build MachineCertificate ManagementSetup Time
EAS BuildExpo / React NativeExpo cloud (no Mac needed)EAS managed4-8 hours
Fastlane + GitHub ActionsFlutter / native iOSmacOS GitHub Actions runnermatch (Git repo)1-2 days
Fastlane + BitriseLarge teamsBitrise cloudmatch1-2 days
ManualSmall teams, infrequent releasesDeveloper's MacIndividualNone upfront

The core argument

Manual mobile release processes are the single most reliable source of "we were ready to ship but the build failed" problems. The developer who manages the iOS certificates has left the company. The provisioning profile does not include the new test device. The App Store Connect credentials are not shared. The Xcode version on the build machine does not match the project configuration. Every one of these failure modes is predictable and every one of them is eliminated by an automated build pipeline.

The investment in a mobile build pipeline is front-loaded: 4-8 hours for EAS Build, 1-2 days for Fastlane. The return is every manual build session that never needs to happen, every certificate management failure that never occurs, and every "who can do the release?" question that the pipeline answers automatically.

The teams that resist this investment typically cite the upfront complexity as the reason. The teams that have shipped multiple mobile products use the automation because they have experienced what manual releases cost in time, in failed builds, and in the release process becoming a bottleneck that only certain engineers can unblock.

EAS Build for React Native

EAS Build is the current lowest-friction path for React Native and Expo projects. The setup:

Install and configure EAS CLI: ``bash npm install -g eas-cli eas login eas build:configure ``

The eas build:configure command generates an eas.json file with build profiles:

``json { "cli": { "version": ">= 5.0.0" }, "build": { "development": { "developmentClient": true, "distribution": "internal", "ios": { "simulator": true } }, "preview": { "distribution": "internal", "android": { "buildType": "apk" } }, "production": { "autoIncrement": true } }, "submit": { "production": {} } } ``

Build for internal distribution (TestFlight): ``bash eas build --platform ios --profile preview ``

EAS handles: downloading the correct Xcode version, managing provisioning profiles and certificates, building the app, and uploading the artifact. The result is a TestFlight build link that can be distributed to testers without anyone having run Xcode locally.

Submit to the App Store: ``bash eas submit --platform ios --latest ``

EAS Submit uploads the latest build to App Store Connect and starts the review process.

GitHub Actions integration: ``yaml name: EAS Build on: push: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - run: npm ci - uses: expo/expo-github-action@v8 with: expo-version: latest token: ${{ secrets.EXPO_TOKEN }} - run: eas build --platform all --profile preview --non-interactive ``

Fastlane for Flutter and native iOS

For Flutter and non-Expo React Native, Fastlane provides equivalent automation with more configuration. The core setup:

Fastfile for iOS: ```ruby platform :ios do desc "Build and distribute to TestFlight" lane :beta do # Download certificates and provisioning profiles match(type: "appstore", readonly: true)

# Increment build number increment_build_number( build_number: number_of_commits )

# Build the app build_app( workspace: "ios/YourApp.xcworkspace", scheme: "YourApp", configuration: "Release", export_method: "app-store" )

# Upload to TestFlight upload_to_testflight( skip_waiting_for_build_processing: true ) end end ```

Fastlane match configuration: ``ruby # Matchfile git_url("https://github.com/yourorg/certs") type("appstore") app_identifier("com.yourapp.bundle") username("developer@example.com") ``

Fastlane match stores the certificates and provisioning profiles in an encrypted Git repository. When a new developer runs fastlane match appstore, they receive the current certificates and can build immediately without manual certificate setup.

The CI/CD pipeline structure

A complete mobile CI/CD pipeline has three stages:

Pull request validation (5-10 minutes):

  • ESLint / Dart analyze
  • TypeScript type check
  • Unit test suite
  • No build artifact produced

Main branch build (15-20 minutes):

  • All PR validation steps
  • iOS and Android build (EAS or Fastlane)
  • Distribute to TestFlight (iOS) and Play Store internal track (Android)
  • Post build link to Slack

Release build (20-30 minutes):

  • Triggered by a version tag or manual workflow dispatch
  • Increment version number
  • iOS and Android build with production configuration
  • Submit to App Store review and Play Store review

This structure means the team always has a recent build available for testing (from main branch builds), and production releases are automated without manual App Store Connect steps.

Common mistakes teams make with mobile build pipelines

  1. Setting up the build pipeline after the first release instead of before. The pipeline that is set up before the first beta prevents the "who can build this?" problem from ever occurring. Setting it up after the first release means the first few releases are manual and teach bad habits.
  2. Not caching build artifacts. Xcode build times on clean CI machines are 15-25 minutes. Caching DerivedData and CocoaPods across CI runs reduces this to 5-8 minutes. EAS Build handles this automatically; Fastlane on GitHub Actions requires explicit cache configuration.
  3. Using individual developer Apple IDs for CI certificate access. The CI pipeline should use a dedicated Apple ID for the development team, not a personal developer account. When the personal account's authentication session expires, the CI pipeline fails and requires manual intervention.
  4. Not testing the pipeline on both platforms. iOS build failures and Android build failures are independent. A pipeline that only builds iOS regularly may not catch Android build regressions until they block a release.
  5. Not automating the version bump. Manual version and build number management is a source of "the build number we submitted is already taken" errors in App Store Connect. Automating the build number (using the commit count or a timestamp) eliminates this class of error.

Where to start: a 3-step build pipeline setup

Step 1: Set up EAS Build (for Expo/React Native) or Fastlane (for Flutter/native iOS) and produce the first automated TestFlight build. This is the validation that the pipeline works. A successful automated TestFlight build means the pipeline can replace all manual builds.

Step 2: Add the build trigger to GitHub Actions and verify it runs on push to main. The pipeline should produce a TestFlight build without anyone manually triggering it. Verify this by pushing a test commit and observing the CI run.

Step 3: Configure Fastlane match or EAS credentials management and remove individual developer certificate access from the CI pipeline. The build pipeline should not depend on any individual developer's credentials. Shared, managed credentials ensure the pipeline continues to work as team members change.

The Pipeline That Nobody Has to Think About

Yashveer Singh. Founder of Yashveer Labs. The Prominence Football Academy app uses EAS Build with a GitHub Actions trigger on every push to main. In the first three months after launch, we shipped 14 updates -- bug fixes, performance improvements, and new features. Every single one of those updates was built and distributed to TestFlight by the CI pipeline without a single manual App Store Connect step. The two developers on the project both contributed to the mobile codebase; neither needed to own the release process. When a certificate update was required (quarterly EAS credential refresh), it was handled in a single eas credentials command and did not interrupt any builds. That is what the pipeline investment produces: the release process becomes invisible, and the team's attention goes entirely to the product.

Related reading

FAQ

Frequently asked

Author

A note from Yashveer Singh

This was written by me, Yashveer Singh. The reason I write at this length and this depth is that the alternative is generic SEO content, and I am not interested in being one more of those. If you found this post useful, that is by design. If you want to talk about the project you are facing, the work happens through one channel: send a message via Instagram, and I will get back to you with a real answer, not a templated reply.

Related reading