Back to blog

Wednesday, June 4, 2025

React Native Stallion CI/CD and Testing Framework: Automate, Test, and Ship OTA Updates

cover

Introduction

Modern React Native development is incomplete without automation. CI/CD pipelines, instant testing, and faster rollouts define high-performance mobile teams.

React Native Stallion takes this further by providing first-class support for CI workflows and a blazing-fast testing system built right into your app.

This blog covers how to:

  • Automate OTA bundle releases via CI/CD
  • Use GitHub Actions to publish on every main merge
  • Slash dev-to-QA time using Stallion’s version switching UI

Let’s dive in.

Automate Releases with CI/CD Integration

Stallion supports CI/CD automation via CI tokens.

Step 1: Generate a CI Token

From your Stallion Console:

  1. Go to Project Settings
  2. Click Access Tokens
  3. Generate a CI Token

This token is safe for CI pipelines and scoped only for publishing bundles.

Step 2: Use the Token in CLI

npx stallion publish-bundle \
  --upload-path=org-name/project-name/bucket \
  --platform=android \
  --release-note="your release notes" \
  --ci-token="your-ci-token"

Example: GitHub Action to Auto Publish on Main

name: Publish OTA with Stallion

on:
  push:
    branches:
      - main

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: "18"

      - name: Install dependencies
        run: npm ci

      - name: Publish OTA Update with Stallion
        run: |
          COMMIT_MSG=$(git log -1 --pretty=format:"%s")
          echo "Publishing with commit message: $COMMIT_MSG"
          npx stallion publish-bundle \
            --upload-path=my-org/my-project/prod \
            --platform=android \
            --release-note="$COMMIT_MSG" \
            --ci-token="${{ secrets.STALLION_CI_TOKEN }}"

Instant QA with Stallion Testing Framework

Shipping updates is half the battle. Testing them quickly is just as important.

Stallion Testing lets your team install any version of the app directly inside the released app using a built-in SDK modal.

No rebuilds. No TestFlight. No APK uploads. Just deploy, tap, and test.

Integrate Stallion Modal

import { useStallionModal } from "react-native-stallion";

const MyDebugScreen = () => {
  const { showModal } = useStallionModal();

  return <Button title="Open Stallion" onPress={showModal} />;
};

Set Up Security Pin

Set a security pin in your Stallion Console to restrict internal tester access.

Test Builds via CLI Uploads

After upload, the build shows up inside the Stallion modal. Anyone can install it by clicking the download button and restarting the app.

Learn more here: Stallion Testing Docs

Stallion lets you switch between app versions instantly, speeding up QA/dev cycles.

Automating Releases with Stallion CLI

Publishing a Bundle

stallion publish-bundle \
  --upload-path=orgname/project-name/bucket-name \
  --platform=android/ios \
  --release-note="Your release note here"

Promoting a Bundle

stallion release-bundle \
  --project-id=<your_project_id> \
  --hash=<bundle_hash> \
  --app-version=<target_app_version> \
  --release-note="Your release note" \
  --ci-token=<your_ci_token>

Updating a Release

stallion update-release \
  --project-id=<your_project_id> \
  --hash=<bundle_hash> \
  --release-note="Updated release note" \
  --rollout-percent=<percent> \
  --is-mandatory=<true|false> \
  --ci-token=<your_ci_token>

GitHub Actions Workflow

name: Stallion Release Automation

on:
  push:
    branches:
      - main

jobs:
  release-bundle:
    runs-on: ubuntu-latest

    env:
      PROJECT_ID: 64f5f341a43eb5ccf93548e4
      APP_VERSION: 1.0.1
      RELEASE_NOTE: "Automated CI Release"
      CI_TOKEN: ${{ secrets.STALLION_CI_TOKEN }}
      UPLOAD_PATH: my-org/my-project/my-bucket
      PLATFORM: android

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Node.js (if needed)
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install Stallion CLI
        run: npm install -g stallion-cli

      - name: Publish Bundle and Extract Hash
        id: publish
        run: |
          echo "Publishing bundle..."
          OUTPUT=$(stallion publish-bundle \
            --upload-path=$UPLOAD_PATH \
            --platform=$PLATFORM \
            --release-note="$RELEASE_NOTE")

          echo "$OUTPUT"

          HASH=$(echo "$OUTPUT" | grep -oE '[a-f0-9]{64}')
          echo "Bundle hash: $HASH"

          echo "BUNDLE_HASH=$HASH" >> $GITHUB_ENV

      - name: Release Bundle
        run: |
          stallion release-bundle \
            --project-id=$PROJECT_ID \
            --hash=$BUNDLE_HASH \
            --app-version=$APP_VERSION \
            --release-note="$RELEASE_NOTE" \
            --ci-token=$CI_TOKEN

      - name: Update Release (optional rollout config)
        run: |
          stallion update-release \
            --project-id=$PROJECT_ID \
            --hash=$BUNDLE_HASH \
            --release-note="$RELEASE_NOTE" \
            --rollout-percent=100 \
            --is-mandatory=true \
            --ci-token=$CI_TOKEN
close