DEV Community

Alberto Cabrera
Alberto Cabrera

Posted on • Updated on

Implementing a CI/CD Deployment Pattern for React Native Expo Applications with Github Actions

Our deployment pattern leverages the Persistent Staging Flow directly from the Expo documentation. This flow is designed for continuous integration and delivery, with a focus on maintaining persistent "staging" and "production" branches.

Key Aspects of the Deployment Pattern

1. Creating Builds

  • Production Builds: Distinct builds tailored for the production environment.
  • Testing Builds: Separate, dedicated builds for testing purposes.

2. Testing Changes

  • Implement internal distribution builds for comprehensive pre-production testing.

3. Publishing Updates

  • Utilize designated branches, like "staging" and "production", for streamlined update management.

Application of the Pattern: A Practical Example

Local Development

  • Begin with a feature branch (e.g., feature/dark-mode) based on the main branch.
  • Develop the feature with an emphasis on coding, UI design, and local testing.

Merging to Main

  • After development, commit the changes and push to feature/dark-mode.
  • Merge into the main branch upon pull request approval.

Testing in Staging

  • Merge updates from the main to staging.
  • Trigger a staging build through GitHub Actions, followed by internal distribution for testing.

Iterative Fixes and Updates

  • Address feedback, creating and merging fixed branches as necessary.
  • Conduct additional testing after merging updates into staging.

Final Deployment to Production

  • Confirm feature stability in staging before merging to production.
  • Update version numbers in app.json/app.config.js and initiate automated production deployment via GitHub Actions.

CI/CD Configuration Files

Setup the different profiles in build and submit sections in eas.json that are needed. Here is an example,

eas.json

{
 "build": {
   "development": {
     "developmentClient": true,
     "distribution": "internal"
   },
   "preview": {
     "channel": "staging",
     "distribution": "internal",
     "env": {
       "EXPO_PUBLIC_API_HOST": // your staging api url
     }
     // ...other values
     }
   },
   "production": {
     "channel": "production"
     "env": {
       "EXPO_PUBLIC_API_HOST": // your production api url
     }
     // ...other values
   }
 },
 "submit": {
   "production": {
       // This is optional if you already setup the service account key in your expo account
     "android": {
       "serviceAccountKeyPath": "../path/to/api-xxx-yyy-zzz.json",
       "track": "internal"
     },
     "ios": {
       "appleId": "john@turtle.com",
       "ascAppId": "1234567890",
       "appleTeamId": "AB12XYZ34S"
     }
   }
 }
}
Enter fullscreen mode Exit fullscreen mode

GitHub Actions YAML Configurations
Set up your EXPO_TOKEN as a secret in your GitHub repository.

staging.yml
This job will create a staging build that you can distribute to your internal testers to test.

name: Build For Staging
on:
  push:
    branches: ["staging"]
jobs:
  build:
    name: Build For Staging
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16.x
          cache: npm
      - name: Setup Expo and EAS
        uses: expo/expo-github-action@v8
        with:
          eas-version: latest
          token: ${{ secrets.EXPO_TOKEN }}
      - name: Install dependencies
        run: npm ci
      - name: Build For Staging
        run: eas build --profile preview --platform all --non-interactive
Enter fullscreen mode Exit fullscreen mode

production.yml
This job will create a production build and submit this build to AppStore Connect and Google Play Console.

name: Build For Production
on:
  push:
    branches: ["production"]
jobs:
  build:
    name: Build For Production
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16.x
          cache: npm
      - name: Setup Expo and EAS
        uses: expo/expo-github-action@v8
        with:
          eas-version: latest
          token: ${{ secrets.EXPO_TOKEN }}
      - name: Install dependencies
        run: npm ci
      - name: Build For Production
        run: eas build --profile production --platform all --non-interactive --auto-submit --clear-cache
Enter fullscreen mode Exit fullscreen mode

There we have it!

Adopting the Persistent Staging Flow from the Expo documentation in our CI/CD deployment pattern offers a streamlined and effective approach for managing React Native Expo app development. By consistently utilizing "staging" and "production" branches, we ensure a smooth and continuous integration and deployment process, significantly enhancing our development efficiency and release quality.

Happy deploying 🚀

Top comments (0)