React Native CI/CD with GitHub Actions and EAS: Build, Test, and Submit Workflow
React NativeCI/CDGitHub ActionsEASAndroid DeploymentiOS Deployment

React Native CI/CD with GitHub Actions and EAS: Build, Test, and Submit Workflow

RReact Native Live Editorial Team
2026-11-12
7 min read

Build a repeatable React Native CI/CD pipeline with GitHub Actions and EAS for checks, previews, releases, submissions, and rollback planning.

A dependable React Native CI/CD pipeline should make every change easier to verify and every release easier to reproduce. This guide shows how to combine GitHub Actions with Expo Application Services (EAS) for pull-request checks, preview builds, production builds, and Android or iOS submission. It also provides a repeatable way to estimate pipeline effort, identify assumptions, manage secrets, and decide when the workflow needs to be recalculated.

Overview

A practical React Native CI/CD workflow separates fast feedback from release operations. Pull requests should run checks that are quick enough to use on every change. Preview builds should help reviewers test a realistic app package without granting production credentials. Production builds and store submissions should require an intentional trigger, protected environment, or approval.

A useful stage matrix looks like this:

StageTriggerTypical workExpected result
Quality checksPull requestInstall dependencies, lint, TypeScript checks, unit testsPass or fail before review
Preview buildSelected branch or manual runCreate a non-production Android or iOS buildTestable artifact for reviewers
Production buildRelease branch, tag, or approvalBuild signed app bundles with the intended environmentRelease artifact with an identifiable version
SubmissionManual approval or release workflowUpload the approved artifact to the relevant store processSubmission record and audit trail

EAS is a natural fit for Expo-based projects and can also support projects with native folders, provided the project and credentials are configured for the selected build profiles. Teams using a fully native React Native setup can use the same GitHub Actions principles while choosing local Gradle and Xcode commands or another build service. Review the related Expo versus React Native CLI guide before selecting the build boundary.

How to estimate the workflow

Estimate a pipeline by measuring work per change, not by counting YAML lines. Record the following values for a representative week:

  • P: pull requests that require CI.
  • T: average minutes for one quality-check run.
  • R: preview or release builds per week.
  • B: average minutes for one build, including queue time if that affects delivery.
  • S: manual submission and verification minutes per release.
  • F: avoidable rerun or failure minutes, such as broken caches, missing secrets, or incorrect profiles.

A simple weekly workload estimate is:

CI minutes = (P × T) + (R × B) + S + F

This is not a billing forecast. It is an operational baseline. If you want to compare designs, calculate the same inputs for each option. For example, compare a workflow that builds every pull request with one that runs checks on every pull request but creates preview builds only for a dedicated branch. The second design may reduce build minutes and signing exposure while preserving review coverage.

Also track outcomes: median time from merge to testable build, failed-run rate, time to diagnose a failed run, and the number of releases requiring manual repair. A slightly slower pipeline can be preferable if it produces reproducible artifacts and clearer failure messages.

Inputs and assumptions

Repository and environment inputs

Define the Node.js version, package manager, lockfile, Expo SDK or React Native version, native build tools, and EAS CLI version used by the workflow. Pinning or explicitly selecting these inputs makes failures easier to reproduce. Avoid relying on an unexamined runner default.

Keep environment configuration separate from credentials. Public runtime configuration can be supplied through an EAS environment or build profile, while signing keys, store tokens, and service-account files belong in protected GitHub or EAS secrets. The React Native environment variables and secrets guide provides a useful review checklist.

Branch and profile assumptions

Use a small, explicit profile set such as development, preview, and production. Map each profile to an environment, distribution method, application identifier, and credential set. Do not let a preview branch silently select production credentials.

Protect the production environment in GitHub. Require review for workflows that can submit an app, and keep submission separate from compilation when possible. A build can then be inspected, tested, and approved before it is uploaded.

Example quality-check workflow

The following is a starting pattern. Adjust action versions, package-manager commands, and Node versions to match the repository; verify current syntax before adopting it.

name: checks

on:
  pull_request:
  push:
    branches: [main]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version-file: .nvmrc
          cache: npm
      - run: npm ci
      - run: npm run lint --if-present
      - run: npx tsc --noEmit
      - run: npm test -- --runInBand

Example EAS build and submit workflow

Store the EAS token as a protected repository or environment secret. Use a preview profile for review builds and a production profile only from a controlled release workflow.

name: mobile-release

on:
  workflow_dispatch:
    inputs:
      profile:
        required: true
        default: preview
        type: choice
        options: [preview, production]

jobs:
  build:
    runs-on: ubuntu-latest
    environment: mobile-release
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version-file: .nvmrc
          cache: npm
      - run: npm ci
      - run: npx eas-cli build --platform all --profile ${{ inputs.profile }} --non-interactive
        env:
          EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}

Submission can be a separate job or workflow, for example with the appropriate eas submit command and platform selection. Keep store credentials in the credential system intended for the project, confirm the artifact and version, and follow the current store-specific submission requirements. Never print tokens, provisioning data, keystores, or service-account contents in logs.

Worked examples

Suppose a team has 18 pull requests per week, with quality checks averaging 7 minutes. It creates 4 preview or release builds averaging 22 minutes, spends 35 minutes on a release submission, and loses 25 minutes to avoidable reruns.

(18 × 7) + (4 × 22) + 35 + 25 = 293 minutes per week

The useful conclusion is not the absolute number. It is where the work goes: pull-request checks account for most of the routine run time, while build and submission work deserves stronger controls. The team might retain checks on every pull request, move preview builds to a review branch, cache dependencies, and investigate the reruns before adding more parallel jobs.

For a second comparison, assume production builds are currently created on every merge. If only tagged releases need production artifacts, changing the trigger can reduce unnecessary signing operations and make the release history easier to audit. Before making that change, confirm that reviewers still have an appropriate preview path and that emergency fixes have a documented manual trigger.

Failure triage table

SymptomLikely areaFirst check
Dependency installation differs from localNode or lockfile mismatchCompare the lockfile, package manager, and configured Node version.
TypeScript or tests fail only in CIEnvironment or test isolationInspect missing variables, timezone assumptions, filesystem paths, and test ordering.
EAS build stops before compilationProfile or credential configurationRun the selected profile locally or with a safe diagnostic command and verify its environment.
Submission is rejected or cannot authenticateStore metadata or credentialsCheck the target application, version, credential scope, and current submission instructions.
Build succeeds but reviewers cannot install itDistribution settingsConfirm the preview profile, signing method, device access, and artifact format.

When to recalculate

Revisit the estimate and workflow whenever an input changes: a new React Native or Expo version, a changed build image, a new package manager, a branch-model change, a higher release cadence, renewed certificates, altered store credentials, or a change in EAS or GitHub Actions behavior. Pricing and usage limits may also change, so consult the current provider documentation before treating minutes or service usage as a budget.

Recalculate after three to five representative release cycles rather than after one unusually large failure. Compare planned and observed values for check time, build time, queue time, reruns, and manual intervention. Update the matrix if a stage no longer provides useful feedback or if production operations have become too easy to trigger accidentally.

For the next iteration, create a release branch or tag, run quality checks, generate a preview artifact, and document who approves production submission. Then test the rollback path: identify the last known-good version, preserve its artifact and release metadata, pause automatic submission, and decide whether the recovery requires a new store submission or a server-side configuration change. Pair this pipeline review with the React Native production readiness checklist and the release error and crash-reporting workflow before the next release train.

Related Topics

#React Native#CI/CD#GitHub Actions#EAS#Android Deployment#iOS Deployment
R

React Native Live Editorial Team

Technical Editor

Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.