Revyl Documentation

Cookbooks

Build a React Native iOS app on Revyl Mac CI

Install JavaScript dependencies, run CocoaPods, and build a committed React Native iOS project.

This cookbook is for React Native repositories that commit their generated ios/ project. The Mac image provides Node, npm, CocoaPods, Watchman, Xcode, and the iOS Simulator plumbing; it does not provide the React Native or Expo CLI, so the build uses the repository's native Xcode project.

Set up with an agent

Paste one prompt and your coding agent does the rest.

Setup prompt

Build and launch this committed React Native iOS project in Simulator.

Read https://docs.revyl.com/cookbooks/react-native-ios-revyl-macos.md and follow it. It's the current Revyl guide for this, so prefer it over anything you remember about Revyl.

Set `IOS_WORKSPACE`, `IOS_SCHEME`, and `IOS_BUNDLE_ID` to the committed iOS project, copy the workflow, and keep all dependency installs in the job workspace or `$HOME`.

You're done when npm dependencies and CocoaPods install, Xcode builds the Simulator app, and `simctl` launches it.

Ask me before anything that needs my login or approval.

Workflow

name: React Native iOS on Revyl Mac

on:
  pull_request:
  workflow_dispatch:

permissions:
  contents: read

env:
  IOS_WORKSPACE: ios/MyApp.xcworkspace
  IOS_SCHEME: MyApp
  IOS_BUNDLE_ID: com.example.myapp
  COREPACK_HOME: /opt/revyl/corepack
  COREPACK_DEFAULT_TO_LATEST: "0"

jobs:
  react-native:
    if: >-
      github.event_name == 'workflow_dispatch' ||
      (github.event_name == 'pull_request' &&
       github.event.pull_request.head.repo.full_name == github.repository)
    runs-on: revyl-macos
    timeout-minutes: 55
    steps:
      - uses: actions/checkout@v4

      - name: Install JavaScript dependencies
        shell: bash
        run: |
          set -euo pipefail
          echo "/opt/revyl/node/bin" >> "$GITHUB_PATH"
          export PATH="/opt/revyl/node/bin:$PATH"
          npm ci

      - name: Install CocoaPods dependencies
        shell: bash
        run: |
          set -euo pipefail
          pod install --project-directory=ios

      - name: Create and boot a clean Simulator
        id: simulator
        shell: bash
        run: |
          set -euo pipefail
          device_type=$(xcrun simctl list devicetypes | awk -F '[()]' '/iPhone/{print $2; exit}')
          runtime=$(xcrun simctl list runtimes | sed -n 's/.* - \(com.apple.CoreSimulator.SimRuntime.iOS-[^ ]*\) (available)/\1/p' | head -1)
          test -n "$device_type" && test -n "$runtime"
          udid=$(xcrun simctl create "Revyl React Native iPhone" "$device_type" "$runtime")
          xcrun simctl boot "$udid"
          xcrun simctl bootstatus "$udid" -b
          echo "udid=$udid" >> "$GITHUB_OUTPUT"
          open -a Simulator

      - name: Build the iOS app for Simulator
        env:
          SIMULATOR_UDID: ${{ steps.simulator.outputs.udid }}
        shell: bash
        run: |
          set -euo pipefail
          xcodebuild \
            -workspace "$IOS_WORKSPACE" \
            -scheme "$IOS_SCHEME" \
            -sdk iphonesimulator \
            -destination "platform=iOS Simulator,id=$SIMULATOR_UDID" \
            -derivedDataPath "$RUNNER_TEMP/DerivedData" \
            CODE_SIGNING_ALLOWED=NO \
            CODE_SIGNING_REQUIRED=NO \
            build

      - name: Install and launch the app
        env:
          SIMULATOR_UDID: ${{ steps.simulator.outputs.udid }}
        shell: bash
        run: |
          set -euo pipefail
          app_path=$(find "$RUNNER_TEMP/DerivedData/Build/Products" -path "*/Debug-iphonesimulator/*.app" -print -quit)
          test -n "$app_path"
          xcrun simctl install "$SIMULATOR_UDID" "$app_path"
          xcrun simctl launch "$SIMULATOR_UDID" "$IOS_BUNDLE_ID"

The first step adds the image's pinned Node to $GITHUB_PATH. GitHub runs bash steps without login profiles, and the runner's own PATH does not include /opt/revyl/node/bin, so CocoaPods and the Xcode build find the same node only through that line.

If your repository uses Yarn or pnpm, replace npm ci with its frozen lockfile command, such as yarn install --immutable or pnpm install --frozen-lockfile. The workflow's COREPACK_HOME points Corepack at the preinstalled Yarn and pnpm versions. Expo projects need a committed native ios/ project for this workflow; an Expo CLI install or prebuild step is outside the sealed image contract.

Common failures

  • npm, node, yarn, or pnpm is not found: keep the $GITHUB_PATH line in the first step.
  • Corepack cannot write /opt/revyl/corepack: the repository's packageManager field asks for a Yarn or pnpm version the image does not carry. Use the preinstalled version, or set COREPACK_HOME to a directory under $HOME so Corepack can download yours.
  • pod install asks for elevation: keep the dependency in the repository or a user-local directory; do not modify /opt/homebrew.
  • The workspace or scheme is not found: set the three environment values to the committed iOS project and scheme.
  • The job approaches its limit: cache only within the job user's home, reduce native build work, or split the workflow. The backend expiry and host lifetime must agree; current production and staging sources use two hours, and a mismatch refuses the computer rather than shortening it.

On this page