How to Set Up CI/CD for Expo with GitHub Actions

Automated builds and App Store submission for Expo apps using GitHub Actions. Push to main → EAS Build → EAS Submit → both stores. The pipeline that shipped 4 apps.

Learn/How to Set Up CI/CD for Expo with GitHub Actions
intermediate30 minutes

How to Set Up CI/CD for Expo with GitHub Actions

GitHub Actions + EAS Build. Push to main → build → submit to both stores. Automated.

Prerequisites

Expo project with eas.jsonGitHub repositoryEAS accountApp Store Connect API key

The Goal

Push to main → GitHub Actions builds the app → submits to App Store and Play Store. No manual steps.

This is the pipeline I use for all 4 of my production apps. Total manual time per release: zero.

Prerequisites

  • Expo project with eas.json configured
  • EAS account (free for limited builds)
  • GitHub repository
  • App Store Connect API key
  • Google Play service account

GitHub Actions Workflow

Create .github/workflows/deploy.yml:

name: Build and Submit

on:
  push:
    branches: [main]

jobs:
  build-ios:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - uses: expo/expo-github-action@v8
        with:
          eas-version: latest
          token: ${{ secrets.EXPO_TOKEN }}
      - run: eas build --platform ios --profile production --non-interactive
      - run: eas submit --platform ios --profile production --non-interactive

  build-android:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - uses: expo/expo-github-action@v8
        with:
          eas-version: latest
          token: ${{ secrets.EXPO_TOKEN }}
      - run: eas build --platform android --profile production --non-interactive
      - run: eas submit --platform android --profile production --non-interactive

Required Secrets

In GitHub → Settings → Secrets:

Secret Where to Get It
EXPO_TOKEN expo.dev → Account → Access Tokens
App Store Connect API key Configured in EAS
Google Play service account Configured in EAS

EAS stores the App Store and Play Store credentials. You only need the EXPO_TOKEN in GitHub.

How I Actually Use This

My workflow:

  1. Develop on a feature branch
  2. Test on Expo Go or development build
  3. Merge to main
  4. GitHub Actions runs automatically
  5. 20 minutes later: builds submitted to both stores
  6. 24-48 hours later: apps are live (after store review)

No Xcode. No Android Studio. No manual uploading.

Optimizations

Only Build When App Code Changes

Add path filters to avoid building on docs-only changes:

on:
  push:
    branches: [main]
    paths:
      - 'apps/mobile/**'
      - 'packages/**'
      - 'package.json'

Parallel Builds

iOS and Android builds run in parallel (separate jobs). Total time is the slower of the two, not the sum.

Version Auto-Increment

With "autoIncrement": true in eas.json, build numbers increment automatically. No manual version bumping.

Cost

  • EAS free tier: 30 builds/month. Enough for most indie developers.
  • EAS priority builds: $99/month if you need faster builds.
  • GitHub Actions: free for public repos, 2,000 min/month for private.

Related

Or let AI App Factory handle this for you.

Everything in this guide is already pre-configured in AI App Factory. 11 AI agents automate the rest.

AI App FactoryLearnHow to Set Up CI/CD for Expo with GitHub Actions