Automating CodePush Releases with DeployPulse Using GitHub Actions

Managing over-the-air (OTA) updates for React Native apps can be time-consuming, but DeployPulse and GitHub Actions make it seamless. In this guide, we'll walk through a GitHub Action workflow that automates the release process of a CodePush update to DeployPulse.


πŸ“Œ What This GitHub Action Does

This workflow:

  1. Runs on push to main or dev branches.
  2. Triggers when changes occur inside the app/ directory.
  3. Clones and sets up the CodePush CLI (code-push-standalone).
  4. Authenticates with DeployPulse using a secret API key.
  5. Reads the current app version from package.json.
  6. Installs dependencies before releasing the update.
  7. Deploys a CodePush release targeting either the production or development environment.

πŸ›  GitHub Action YAML Breakdown

Let's go step by step through the workflow.

1️⃣ Trigger the Workflow on Code Changes

on:
  push:
    branches:
      - main
      - dev
    paths:
      - 'app/**'

This ensures the workflow only runs when changes are pushed to main or dev inside the app/ directory. This assumes that your app code is stored in the app/ directory. If your app code is stored elsewhere, update the paths accordingly.


2️⃣ Set the Deployment Environment

environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'dev' }}

This dynamically sets the deployment environment:

  • If the branch is main β†’ use production.
  • Otherwise, use dev.

3️⃣ Checkout the Repository

- name: Checkout repository
  uses: actions/checkout@v4

This retrieves the latest version of the code from GitHub.


4️⃣ Set Up Node.js

- name: Set up Node.js
  uses: actions/setup-node@v4
  with:
    node-version: 23

This ensures that Node.js 23 is installed for running the CLI and dependencies.


5️⃣ Clone and Build the CodePush CLI

- name: Clone Code Push CLI
  run: |
    git clone https://github.com/microsoft/code-push-server code-push-server
    cd code-push-server/cli
    npm install
    npm run build
    npm install -g

Since DeployPulse is based on CodePush, we need to clone and build the CLI from Microsoft's repository.


6️⃣ Verify the CodePush CLI

- name: Test Code Push CLI
  run: code-push-standalone --version

This ensures that the CLI is installed and ready to use.


7️⃣ Authenticate with DeployPulse

- name: Authenticate with DeployPulse
  continue-on-error: true
  run: |
    code-push-standalone login --key ${{ secrets.DEPLOYPULSE_ACCESS_TOKEN }} https://apps.deploypulse.io

πŸ” Authentication Details:

  • DEPLOYPULSE_ACCESS_TOKEN: Stored as a GitHub Secret for security.

8️⃣ Read the Current App Version

- name: Read Current Version
  working-directory: ./app
  run: |
    TARGET_VERSION=$(node -p "require('./package.json').version")
    echo "TARGET_VERSION=$TARGET_VERSION" >> $GITHUB_ENV
    echo "Deploying CodePush for version: $TARGET_VERSION"

This reads the current version from package.json and saves it as an environment variable (TARGET_VERSION).


9️⃣ Install App Dependencies

- name: Install Dependencies
  working-directory: ./app
  run: npm install

This ensures that all necessary npm dependencies are installed.


πŸ”Ÿ Release the Update to DeployPulse

- name: Release Update via CodePush
  working-directory: ./app
  env:
    DEPLOYMENT: ${{ vars.DEPLOYMENT }}
    APP_NAME: ${{ vars.APP_NAME }}
  run: |
      code-push-standalone release-react \
      "$APP_NAME" ios \
      -d "$DEPLOYMENT" \
      --mandatory \
      --targetBinaryVersion "$TARGET_VERSION" \
      --description "CodePush Release for Version $TARGET_VERSION" \
      --disabled true

πŸš€ This step deploys the OTA update!

  • Uses code-push-standalone release-react to release the update.
  • APP_NAME and DEPLOYMENT are retrieved from GitHub Environment Variables.
  • The release is mandatory (--mandatory), ensuring all users receive it.
  • --disabled true allows pre-disabling the release if needed. If you would like to publish immediately, remove this flag.

βœ… Why This GitHub Action is Useful

βœ” Automates OTA updates to DeployPulse. βœ” Ensures updates are version-controlled via package.json. βœ” Uses secure authentication with GitHub Secrets. βœ” Handles multiple environments (dev & production) dynamically. βœ” Only triggers when necessary (app/ directory changes).


πŸ”₯ Conclusion

This GitHub Action streamlines CodePush updates by integrating directly with DeployPulse. With zero manual effort, updates can be deployed to iOS and Android users seamlessly.

πŸ‘‰ Need to learn more? Check out the DeployPulse Docs. πŸš€


πŸ“š Full YAML

name: Deploy CodePush Update via DeployPulse

on:
  push:
    branches:
      - main
      - dev
    paths:
      - 'app/**'

jobs:
  release:
    environment: ${{github.ref == 'refs/heads/main' && 'production' || 'dev'}}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 23

      - name: Clone Code Push CLI
        run: |
          git clone https://github.com/microsoft/code-push-server code-push-server
          cd code-push-server/cli
          npm install
          npm run build
          npm install -g

      - name: Test Code Push CLI
        run: code-push-standalone --version

      - name: Authenticate with DeployPulse
        continue-on-error: true
        run: |
          code-push-standalone login --key ${{ secrets.DEPLOYPULSE_ACCESS_TOKEN }} https://apps.deploypulse.io

      - name: Read Current Version
        working-directory: ./app
        run: |
          TARGET_VERSION=$(node -p "require('./package.json').version")
          echo "TARGET_VERSION=$TARGET_VERSION" >> $GITHUB_ENV
          echo "Deploying CodePush for version: $TARGET_VERSION"

      - name: Install Dependencies
        working-directory: ./app
        run: npm install

      - name: Release Update via CodePush
        working-directory: ./app
        env:
          DEPLOYMENT: ${{ vars.DEPLOYMENT }}
          APP_NAME: ${{ vars.APP_NAME }}
        run: |
            code-push-standalone release-react \
            "$APP_NAME" ios \
            -d "$DEPLOYMENT" \
            --mandatory \
            --targetBinaryVersion "$TARGET_VERSION" \
            --description "CodePush Release for Version $TARGET_VERSION" \
            --disabled true