Revyl Documentation

Cookbooks

Build an iOS app in Simulator on Revyl Mac CI

Build an iOS Simulator app, boot a simulator, install it, and launch it in a recorded GitHub Actions job.

Use the Revyl Mac as the build machine when your repository already has an Xcode project. The workflow below creates a clean Simulator, builds an .app for iphonesimulator, installs it, and launches it. Replace the three app values with your project's project file, scheme, and bundle identifier.

Set up with an agent

Paste one prompt and your coding agent does the rest.

Setup prompt

Build and launch this iOS app in a Revyl Mac Simulator job.

Read https://docs.revyl.com/cookbooks/build-ios-app-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_PROJECT`, `IOS_SCHEME`, and `IOS_BUNDLE_ID` to this app's values, copy the workflow, and keep the build under the one-hour computer lifetime.

You're done when Xcode builds the Simulator app, `simctl` launches it, and the Simulator is visible in the GitHub Actions computer recording.

Ask me before anything that needs my login or approval.

Workflow

name: iOS Simulator on Revyl Mac

on:
  pull_request:
  workflow_dispatch:

permissions:
  contents: read

env:
  IOS_PROJECT: MyApp.xcodeproj
  IOS_SCHEME: MyApp
  IOS_BUNDLE_ID: com.example.myapp

jobs:
  ios:
    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: Build for iOS Simulator
        run: |
          set -euo pipefail
          xcodebuild \
            -project "$IOS_PROJECT" \
            -scheme "$IOS_SCHEME" \
            -sdk iphonesimulator \
            -configuration Debug \
            -derivedDataPath "$RUNNER_TEMP/DerivedData" \
            build

      - 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 CI iPhone" "$device_type" "$runtime")
          xcrun simctl boot "$udid"
          xcrun simctl bootstatus "$udid" -b
          echo "udid=$udid" >> "$GITHUB_OUTPUT"
          open -a Simulator

      - 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"

xcrun simctl operates on the local Simulator inside the Mac job. It does not create a separate Revyl mobile session. The outer Revyl Mac computer records the desktop, including the Simulator window when it is visible.

What you see in Revyl

Open the GitHub Actions computer session from the Sessions list or the computer page. After the job finishes, the computer page contains the desktop recording when it has finished uploading. The activity also retains the commands and their outcomes; command output is not included in the computer report.

Start with a small pull request before adding this job to a larger matrix. It uses the same Xcode and simctl commands as a local Mac build, with the outer computer recording the desktop.

Common failures

  • No .app found: the project may use a workspace or a different build product path. Change the xcodebuild invocation and the find path together.
  • No matching Simulator runtime: print xcrun simctl list runtimes and choose a runtime your app supports.
  • Code signing failure: build for iphonesimulator with a Debug configuration and use a simulator-compatible target.
  • The job approaches its limit: reduce build work, disable unnecessary schemes, or split the workflow. Plan for one hour, including cleanup.

On this page