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.
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.
GitHub Actions + EAS Build. Push to main → build → submit to both stores. Automated.
Prerequisites
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.
eas.json configuredCreate .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
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.
My workflow:
mainNo Xcode. No Android Studio. No manual uploading.
Add path filters to avoid building on docs-only changes:
on:
push:
branches: [main]
paths:
- 'apps/mobile/**'
- 'packages/**'
- 'package.json'
iOS and Android builds run in parallel (separate jobs). Total time is the slower of the two, not the sum.
With "autoIncrement": true in eas.json, build numbers increment automatically. No manual version bumping.
Everything in this guide is already pre-configured in AI App Factory. 11 AI agents automate the rest.