chore(deps): update Cocoa SDK to v9.9.0 #5750
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: End-to-End Tests V2 | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - release/** | |
| pull_request: | |
| types: [opened, synchronize, reopened, labeled] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
| env: | |
| SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
| MAESTRO_VERSION: '2.3.0' | |
| IOS_DEVICE: 'iPhone 17' | |
| IOS_VERSION: '>=18.0' | |
| jobs: | |
| ready-to-merge-gate: | |
| name: Ready-to-merge gate | |
| uses: ./.github/workflows/ready-to-merge-workflow.yml | |
| with: | |
| is-pr: ${{ github.event_name == 'pull_request' }} | |
| labels: ${{ toJson(github.event.pull_request.labels) }} | |
| diff_check: | |
| needs: [ready-to-merge-gate] | |
| uses: ./.github/workflows/skip-ci.yml | |
| detect-changes: | |
| needs: [ready-to-merge-gate] | |
| uses: ./.github/workflows/detect-changes.yml | |
| with: | |
| caller_event_name: ${{ github.event_name }} | |
| caller_ref: ${{ github.ref }} | |
| auth_token_check: | |
| uses: ./.github/workflows/skip-ci-noauth.yml | |
| secrets: inherit | |
| metrics: | |
| runs-on: ${{ matrix.runs-on }} | |
| needs: [diff_check, detect-changes, auth_token_check] | |
| if: ${{ needs.diff_check.outputs.skip_ci != 'true' && needs.auth_token_check.outputs.skip_ci != 'true' && !startsWith(github.ref, 'refs/heads/release/') }} | |
| env: | |
| SENTRY_DISABLE_AUTO_UPLOAD: 'true' | |
| strategy: | |
| # we want that the matrix keeps running, default is to cancel them if it fails. | |
| fail-fast: false | |
| # Limit parallel jobs to avoid hitting Sauce Labs concurrency limits (max 3 sessions) | |
| max-parallel: 2 | |
| matrix: | |
| rn-architecture: ['legacy', 'new'] | |
| platform: ["ios", "android"] | |
| include: | |
| - platform: ios | |
| runs-on: ["ghcr.io/cirruslabs/macos-tahoe-xcode:26.2.0", "runner_group_id:10"] | |
| name: iOS | |
| appPlain: performance-tests/test-app-plain.ipa | |
| - platform: android | |
| runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04", "runner_group_id:10"] | |
| name: Android | |
| appPlain: performance-tests/TestAppPlain/android/app/build/outputs/apk/release/app-release.apk | |
| steps: | |
| - name: Check if platform is needed | |
| id: platform-check | |
| run: | | |
| # Performance test changes should always run metrics (that's the | |
| # whole point). The needs_ios/needs_android flags only track SDK | |
| # source & native code — not performance-tests/** files. | |
| PERF_CHANGED="${{ needs.detect-changes.outputs.perf_tests }}" | |
| if [[ "$PERF_CHANGED" == "true" ]]; then | |
| echo "skip=false" >> "$GITHUB_OUTPUT" | |
| echo "Performance tests changed — running metrics for ${{ matrix.platform }}." | |
| elif [[ "${{ matrix.platform }}" == "ios" && "${{ needs.detect-changes.outputs.needs_ios }}" != "true" ]]; then | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| echo "Skipping iOS — no relevant changes detected." | |
| elif [[ "${{ matrix.platform }}" == "android" && "${{ needs.detect-changes.outputs.needs_android }}" != "true" ]]; then | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| echo "Skipping Android — no relevant changes detected." | |
| else | |
| echo "skip=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| - uses: ./.github/actions/disk-cleanup | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'android' }} | |
| - run: corepack enable | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| with: | |
| package-manager-cache: false | |
| node-version: 20 | |
| cache: 'yarn' | |
| cache-dependency-path: yarn.lock | |
| - name: Install Ninja | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'android' }} | |
| run: sudo apt-get update && sudo apt-get install -y ninja-build | |
| - uses: actions/setup-java@v5 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| with: | |
| java-version: '17' | |
| distribution: 'adopt' | |
| - name: Gradle cache | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| uses: gradle/gradle-build-action@v3 | |
| - uses: ruby/setup-ruby@v1 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'ios' }} | |
| with: | |
| ruby-version: '3.3.0' | |
| - name: Install Global Dependencies | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| run: npm i -g react-native-cli @sentry/cli | |
| - name: Install Dependencies | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| run: yarn install | |
| - name: Build SDK | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| run: yarn build | |
| - uses: actions/cache@v5 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| id: app-plain-cache | |
| with: | |
| path: ${{ matrix.appPlain }} | |
| # if the whole plain app folder is hashed the cache is never hit as there are files generated in the folder | |
| # the cache key is calculated both at cache retrieval and save time | |
| # hashFiles fails when there are rn android new arch generated files in the folder (exact reason unknown) | |
| # we removed the lock file of the app due to monorepo changes, we use the package.json instead | |
| # to avoid frequent rebuilds of the app | |
| key: ${{ github.workflow }}-${{ github.job }}-appplain-${{ matrix.platform }}-${{ matrix.rn-architecture }}-${{ hashFiles('performance-tests/TestAppSentry/package.json') }} | |
| - name: Build app plain | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && steps.app-plain-cache.outputs['cache-hit'] != 'true' }} | |
| working-directory: ./performance-tests/TestAppPlain | |
| run: | | |
| cd ${{ matrix.platform }} | |
| if [[ "${{ matrix.platform }}" == "android" ]]; then | |
| if [[ ${{ matrix.rn-architecture }} == 'new' ]]; then | |
| perl -i -pe's/newArchEnabled=false/newArchEnabled=true/g' gradle.properties | |
| fi | |
| ./gradlew assembleRelease | |
| else | |
| export PRODUCTION=1 | |
| if [[ ${{ matrix.rn-architecture }} == 'new' ]]; then | |
| export RCT_NEW_ARCH_ENABLED=1 | |
| fi | |
| bundle install | |
| bundle exec pod install | |
| cd ../.. | |
| bundle install | |
| bundle exec fastlane build_perf_test_app_plain | |
| fi | |
| env: | |
| APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} | |
| APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} | |
| APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} | |
| FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} | |
| MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} | |
| MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} | |
| MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} | |
| - name: Build app with Sentry | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| working-directory: ./performance-tests/TestAppSentry | |
| run: | | |
| cd ${{ matrix.platform }} | |
| if [[ "${{ matrix.platform }}" == "android" ]]; then | |
| if [[ ${{ matrix.rn-architecture }} == 'new' ]]; then | |
| perl -i -pe's/newArchEnabled=false/newArchEnabled=true/g' gradle.properties | |
| ./gradlew generateCodegenArtifactsFromSchema | |
| fi | |
| ./gradlew assembleRelease | |
| else | |
| export PRODUCTION=1 | |
| if [[ ${{ matrix.rn-architecture }} == 'new' ]]; then | |
| export RCT_NEW_ARCH_ENABLED=1 | |
| fi | |
| bundle install | |
| bundle exec pod install | |
| cd ../.. | |
| bundle install | |
| bundle exec fastlane build_perf_test_app_sentry | |
| cd TestAppSentry | |
| fi | |
| env: | |
| APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} | |
| APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} | |
| APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} | |
| FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} | |
| MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} | |
| MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} | |
| MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} | |
| - name: Collect apps metrics | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| uses: getsentry/action-app-sdk-overhead-metrics@44fb5489ac4ac252c87d84811972dc93a1e490b8 | |
| with: | |
| name: ${{ matrix.name }} (${{ matrix.rn-architecture }}) | |
| config: ./performance-tests/metrics-${{ matrix.platform }}.yml | |
| sauce-user: ${{ secrets.SAUCE_USERNAME }} | |
| sauce-key: ${{ secrets.SAUCE_ACCESS_KEY }} | |
| react-native-build: | |
| name: Build RN ${{ matrix.rn-version }} ${{ matrix.rn-architecture }} ${{ matrix.engine }} ${{ matrix.platform }} ${{ matrix.build-type }} ${{ matrix.ios-use-frameworks }} | |
| runs-on: ${{ matrix.runs-on }} | |
| needs: [diff_check, detect-changes, auth_token_check] | |
| if: ${{ needs.diff_check.outputs.skip_ci != 'true' && needs.auth_token_check.outputs.skip_ci != 'true' && !startsWith(github.ref, 'refs/heads/release/') }} | |
| env: | |
| RN_VERSION: ${{ matrix.rn-version }} | |
| RN_ENGINE: ${{ matrix.engine }} | |
| USE_FRAMEWORKS: ${{ matrix.ios-use-frameworks }} | |
| PRODUCTION: ${{ matrix.build-type == 'production' && '1' || '0' }} | |
| RCT_NEW_ARCH_ENABLED: ${{ matrix.rn-architecture == 'new' && '1' || '0' }} | |
| SENTRY_DISABLE_AUTO_UPLOAD: 'false' | |
| strategy: | |
| fail-fast: false # keeps matrix running if one fails | |
| matrix: | |
| rn-version: ['0.71.19', '0.84.0'] | |
| rn-architecture: ['legacy', 'new'] | |
| platform: ['android', 'ios'] | |
| build-type: ['production'] | |
| ios-use-frameworks: ['no', 'static', 'dynamic'] | |
| engine: ['hermes'] | |
| include: | |
| # Use Xcode 16 for older RN versions | |
| - platform: ios | |
| rn-version: '0.71.19' | |
| runs-on: ["ghcr.io/cirruslabs/macos-sequoia-xcode:16.4", "runner_group_id:10"] | |
| # Use Xcode 26 for newer RN versions (0.83.0) | |
| - platform: ios | |
| rn-version: '0.84.0' | |
| runs-on: ["ghcr.io/cirruslabs/macos-tahoe-xcode:26.2.0", "runner_group_id:10"] | |
| - platform: android | |
| runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04", "runner_group_id:10"] | |
| exclude: | |
| # exclude all rn versions lower than 0.80.0 for new architecture | |
| - rn-version: '0.71.19' | |
| rn-architecture: 'new' | |
| # exlude old rn version for use frameworks builds (to minimalize the matrix) | |
| - rn-version: '0.71.19' | |
| platform: 'ios' | |
| ios-use-frameworks: 'static' | |
| - rn-version: '0.71.19' | |
| platform: 'ios' | |
| ios-use-frameworks: 'dynamic' | |
| # use frameworks is ios only feature | |
| - platform: 'android' | |
| ios-use-frameworks: 'static' | |
| - platform: 'android' | |
| ios-use-frameworks: 'dynamic' | |
| # exclude new rn architecture and dynamic frameworks | |
| - rn-architecture: 'new' | |
| ios-use-frameworks: 'dynamic' | |
| # exclude RN 0.82.1 with dynamic frameworks due to React Native circular dependency bug | |
| # https://github.com/facebook/react-native/issues/54267 | |
| - rn-version: '0.82.1' | |
| platform: 'ios' | |
| ios-use-frameworks: 'dynamic' | |
| steps: | |
| - name: Check if platform is needed | |
| id: platform-check | |
| run: | | |
| if [[ "${{ matrix.platform }}" == "ios" && "${{ needs.detect-changes.outputs.needs_ios }}" != "true" ]]; then | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| echo "Skipping iOS — no relevant changes detected." | |
| elif [[ "${{ matrix.platform }}" == "android" && "${{ needs.detect-changes.outputs.needs_android }}" != "true" ]]; then | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| echo "Skipping Android — no relevant changes detected." | |
| else | |
| echo "skip=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| - uses: ./.github/actions/disk-cleanup | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'android' }} | |
| - name: Sentry Release | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| run: | | |
| SENTRY_RELEASE_CANDIDATE=$(echo 'e2e/${{ github.ref }}' | perl -pe 's/\//-/g') | |
| echo "SENTRY_RELEASE=$SENTRY_RELEASE_CANDIDATE" >> $GITHUB_ENV | |
| - name: Sentry Dist | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| run: | | |
| SENTRY_DIST_CANDIDATE=${{ matrix.rn-version }}-${{ matrix.rn-architecture }}-${{ matrix.engine }}-${{ matrix.platform }}-${{ matrix.build-type }}-${{ matrix.ios-use-frameworks }}-${GITHUB_SHA:0:8} | |
| echo "SENTRY_DIST=$SENTRY_DIST_CANDIDATE" >> $GITHUB_ENV | |
| - name: Sentry Envs | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| run: | | |
| echo "SENTRY_RELEASE=$SENTRY_RELEASE" | |
| echo "SENTRY_DIST=$SENTRY_DIST" | |
| - run: corepack enable | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| with: | |
| package-manager-cache: false | |
| node-version: 20 | |
| cache: 'yarn' | |
| cache-dependency-path: yarn.lock | |
| - name: Install Ninja | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'android' }} | |
| run: sudo apt-get update && sudo apt-get install -y ninja-build | |
| - uses: actions/setup-java@v5 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| with: | |
| java-version: '17' | |
| distribution: 'adopt' | |
| - name: Gradle cache | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| uses: gradle/gradle-build-action@v3 | |
| - name: Setup Global Tools | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| run: | | |
| npm i -g yalc semver | |
| - name: Setup Global Xcode Tools | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'ios' }} | |
| run: which xcbeautify || brew install xcbeautify | |
| - name: Install JS Dependencies | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| run: yarn install | |
| - uses: ruby/setup-ruby@v1 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'ios' }} | |
| with: | |
| ruby-version: '3.3.0' | |
| - name: Setup Plain RN ${{ matrix.rn-version }} App | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| run: ./dev-packages/e2e-tests/cli.mjs ${{ matrix.platform }} --create | |
| - name: Build Plain RN ${{ matrix.rn-version }} App | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| run: ./dev-packages/e2e-tests/cli.mjs ${{ matrix.platform }} --build | |
| - name: Upload App | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.build-type == 'production' }} | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ matrix.rn-version }}-${{ matrix.rn-architecture }}-${{ matrix.engine }}-${{ matrix.platform }}-${{ matrix.build-type }}-${{ matrix.ios-use-frameworks }}-app-package | |
| path: dev-packages/e2e-tests/RnDiffApp.ap* | |
| retention-days: 1 | |
| - name: Upload logs | |
| if: ${{ always() && steps.platform-check.outputs.skip != 'true' }} | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: rn-build-logs-${{ matrix.rn-version }}-${{ matrix.rn-architecture }}-${{ matrix.engine }}-${{ matrix.platform }}-${{ matrix.build-type }}-${{ matrix.ios-use-frameworks }} | |
| path: dev-packages/e2e-tests/react-native-versions/${{ matrix.rn-version }}/RnDiffApp/ios/*.log | |
| react-native-test: | |
| name: | |
| Test RN ${{ matrix.rn-version }} ${{ matrix.rn-architecture }} ${{ matrix.engine }} ${{ matrix.platform }} ${{ | |
| matrix.build-type }} ${{ matrix.ios-use-frameworks }} | |
| needs: [react-native-build, diff_check, detect-changes] | |
| if: ${{ needs.diff_check.outputs.skip_ci != 'true' }} | |
| runs-on: ${{ matrix.runs-on }} | |
| strategy: | |
| fail-fast: false # keeps matrix running if one fails | |
| matrix: | |
| rn-version: ['0.84.0'] | |
| rn-architecture: ['legacy', 'new'] | |
| platform: ['android', 'ios'] | |
| build-type: ['production'] | |
| ios-use-frameworks: ['no'] # test only no frameworks | |
| engine: ['hermes'] | |
| include: | |
| - platform: ios | |
| rn-version: '0.84.0' | |
| runs-on: ["ghcr.io/cirruslabs/macos-tahoe-xcode:26.2.0", "runner_group_id:10"] | |
| - platform: android | |
| runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04", "runner_group_id:10"] | |
| steps: | |
| - name: Check if platform is needed | |
| id: platform-check | |
| run: | | |
| if [[ "${{ matrix.platform }}" == "ios" && "${{ needs.detect-changes.outputs.needs_ios }}" != "true" ]]; then | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| echo "Skipping iOS — no relevant changes detected." | |
| elif [[ "${{ matrix.platform }}" == "android" && "${{ needs.detect-changes.outputs.needs_android }}" != "true" ]]; then | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| echo "Skipping Android — no relevant changes detected." | |
| else | |
| echo "skip=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| - name: Install Maestro | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| uses: dniHze/maestro-test-action@bda8a93211c86d0a05b7a4597c5ad134566fbde4 # pin@v1.0.0 | |
| with: | |
| version: ${{env.MAESTRO_VERSION}} | |
| - name: Install iDB Companion | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'ios' }} | |
| run: brew tap facebook/fb && brew install facebook/fb/idb-companion | |
| - uses: ./.github/actions/disk-cleanup | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'android' }} | |
| - name: Setup Global Xcode Tools | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'ios' }} | |
| run: which xcbeautify || brew install xcbeautify | |
| - name: Download App Package | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.build-type == 'production' }} | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: ${{ matrix.rn-version }}-${{ matrix.rn-architecture }}-${{ matrix.engine }}-${{ matrix.platform }}-${{ matrix.build-type }}-${{ matrix.ios-use-frameworks }}-app-package | |
| path: dev-packages/e2e-tests | |
| - name: Enable Corepack | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| run: corepack enable | |
| - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| with: | |
| package-manager-cache: false | |
| node-version: 20 | |
| cache: 'yarn' | |
| cache-dependency-path: yarn.lock | |
| - name: Install Ninja | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'android' }} | |
| run: sudo apt-get update && sudo apt-get install -y ninja-build | |
| - uses: actions/setup-java@v5 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| with: | |
| java-version: '17' | |
| distribution: 'adopt' | |
| - name: Gradle cache | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| uses: gradle/gradle-build-action@v3 | |
| - name: Setup KVM | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'android' }} | |
| shell: bash | |
| run: | | |
| # check if virtualization is supported... | |
| sudo apt install -y --no-install-recommends cpu-checker coreutils && echo "CPUs=$(nproc --all)" && kvm-ok | |
| # allow access to KVM to run the emulator | |
| echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \ | |
| | sudo tee /etc/udev/rules.d/99-kvm4all.rules | |
| sudo udevadm control --reload-rules | |
| sudo udevadm trigger --name-match=kvm | |
| - name: Install JS Dependencies | |
| if: ${{ steps.platform-check.outputs.skip != 'true' }} | |
| run: yarn install | |
| - name: Run tests on Android | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'android' }} | |
| uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # pin@v2.37.0 | |
| with: | |
| api-level: 30 | |
| force-avd-creation: false | |
| disable-animations: true | |
| disable-spellchecker: true | |
| target: 'google_apis' | |
| emulator-options: > | |
| -no-window | |
| -no-snapshot-save | |
| -gpu swiftshader_indirect | |
| -noaudio | |
| -no-boot-anim | |
| -camera-back none | |
| -camera-front none | |
| -timezone US/Pacific | |
| script: ./dev-packages/e2e-tests/cli.mjs ${{ matrix.platform }} --test | |
| - name: List available iOS simulators | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'ios' }} | |
| run: xcrun simctl list devices available | |
| - uses: futureware-tech/simulator-action@e89aa8f93d3aec35083ff49d2854d07f7186f7f5 # pin@v5 | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'ios' }} | |
| with: | |
| model: ${{ env.IOS_DEVICE }} | |
| os_version: ${{ env.IOS_VERSION }} | |
| wait_for_boot: true | |
| erase_before_boot: false | |
| - name: Wait for iOS simulator to be fully ready | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'ios' }} | |
| run: | | |
| # Wait for boot to complete at the system level | |
| xcrun simctl bootstatus booted -b | |
| # Launch and dismiss Settings.app to ensure SpringBoard and system services | |
| # are fully initialized — this avoids Maestro connecting to a half-booted | |
| # simulator on Cirrus Labs Tart VMs. | |
| xcrun simctl launch booted com.apple.Preferences | |
| sleep 5 | |
| xcrun simctl terminate booted com.apple.Preferences | |
| - name: Run tests on iOS | |
| if: ${{ steps.platform-check.outputs.skip != 'true' && matrix.platform == 'ios' }} | |
| env: | |
| # Increase timeout for Maestro iOS driver startup (default is 60s, some CI runners need more time) | |
| MAESTRO_DRIVER_STARTUP_TIMEOUT: 180000 | |
| run: ./dev-packages/e2e-tests/cli.mjs ${{ matrix.platform }} --test | |
| - name: Upload logs | |
| if: ${{ always() && steps.platform-check.outputs.skip != 'true' }} | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ matrix.rn-version }}-${{ matrix.rn-architecture }}-${{ matrix.engine }}-${{ matrix.platform }}-${{ matrix.build-type }}-${{ matrix.ios-use-frameworks }}-logs | |
| path: | | |
| ./dev-packages/e2e-tests/maestro-logs |