feat(expo): Add RNSentrySDK APIs support to @sentry/react-native/expo plugin #3064
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 | |
| - v5 | |
| - 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.0.10' | |
| 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 | |
| auth_token_check: | |
| uses: ./.github/workflows/skip-ci-noauth.yml | |
| secrets: inherit | |
| metrics: | |
| runs-on: ${{ matrix.runs-on }} | |
| needs: [diff_check, 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 | |
| matrix: | |
| rn-architecture: ['legacy', 'new'] | |
| platform: ["ios", "android"] | |
| include: | |
| - platform: ios | |
| runs-on: macos-26 | |
| name: iOS | |
| appPlain: performance-tests/test-app-plain.ipa | |
| - platform: android | |
| # Not using the latest version due to a known issue: https://github.com/getsentry/sentry-react-native/issues/4418 | |
| runs-on: ubuntu-22.04 | |
| name: Android | |
| appPlain: performance-tests/TestAppPlain/android/app/build/outputs/apk/release/app-release.apk | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: ./.github/actions/disk-cleanup | |
| if: ${{ matrix.platform == 'android' }} | |
| - run: sudo xcode-select -s /Applications/Xcode_26.1.1.app/Contents/Developer | |
| if: ${{ matrix.platform == 'ios' }} | |
| - run: npm i -g corepack | |
| - uses: actions/setup-node@v6 | |
| with: | |
| package-manager-cache: false | |
| node-version: 20 | |
| cache: 'yarn' | |
| cache-dependency-path: yarn.lock | |
| - uses: actions/setup-java@v5 | |
| with: | |
| java-version: '17' | |
| distribution: 'adopt' | |
| - name: Gradle cache | |
| uses: gradle/gradle-build-action@v3 | |
| - name: Install Global Dependencies | |
| run: npm i -g react-native-cli @sentry/cli | |
| - name: Install Dependencies | |
| run: yarn install | |
| - name: Build SDK | |
| run: yarn build | |
| - uses: actions/cache@v5 | |
| 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.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 | |
| pod install | |
| cd ../.. | |
| 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 | |
| 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 | |
| pod install | |
| cd ../.. | |
| 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 | |
| uses: getsentry/action-app-sdk-overhead-metrics@5f2d99b8e5a7b833386524924d24320501099a44 | |
| 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, 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.83.0'] | |
| rn-architecture: ['legacy', 'new'] | |
| platform: ['android', 'ios'] | |
| build-type: ['production'] | |
| ios-use-frameworks: ['no', 'static', 'dynamic'] | |
| engine: ['hermes', 'jsc'] | |
| include: | |
| # Use Xcode 16 for older RN versions | |
| - platform: ios | |
| rn-version: '0.71.19' | |
| xcode-version: '16.4' | |
| runs-on: macos-15 | |
| # Use Xcode 26 for newer RN versions (0.83.0) | |
| - platform: ios | |
| rn-version: '0.83.0' | |
| xcode-version: '26.1.1' | |
| runs-on: macos-26 | |
| - platform: android | |
| runs-on: ubuntu-latest | |
| exclude: | |
| # exclude JSC for new RN versions (keeping the matrix manageable) | |
| - rn-version: '0.83.0' | |
| engine: 'jsc' | |
| # 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: | |
| - uses: actions/checkout@v6 | |
| - uses: ./.github/actions/disk-cleanup | |
| if: ${{ matrix.platform == 'android' }} | |
| - name: Sentry Release | |
| run: | | |
| SENTRY_RELEASE_CANDIDATE=$(echo 'e2e/${{ github.ref }}' | perl -pe 's/\//-/g') | |
| echo "SENTRY_RELEASE=$SENTRY_RELEASE_CANDIDATE" >> $GITHUB_ENV | |
| - name: Sentry Dist | |
| 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 | |
| run: | | |
| echo "SENTRY_RELEASE=$SENTRY_RELEASE" | |
| echo "SENTRY_DIST=$SENTRY_DIST" | |
| - run: sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode-version }}.app/Contents/Developer | |
| if: ${{ matrix.platform == 'ios' }} | |
| - run: npm i -g corepack | |
| - uses: actions/setup-node@v6 | |
| with: | |
| package-manager-cache: false | |
| node-version: 20 | |
| cache: 'yarn' | |
| cache-dependency-path: yarn.lock | |
| - uses: actions/setup-java@v5 | |
| with: | |
| java-version: '17' | |
| distribution: 'adopt' | |
| - name: Gradle cache | |
| uses: gradle/gradle-build-action@v3 | |
| - name: Setup Global Tools | |
| run: | | |
| npm i -g yalc semver | |
| - name: Setup Global Xcode Tools | |
| if: ${{ matrix.platform == 'ios' }} | |
| run: which xcbeautify || brew install xcbeautify | |
| - name: Install JS Dependencies | |
| run: yarn install | |
| - uses: ruby/setup-ruby@v1 | |
| if: ${{ matrix.platform == 'ios' }} | |
| with: | |
| ruby-version: '3.3.0' | |
| - name: Setup Plain RN ${{ matrix.rn-version }} App | |
| run: ./dev-packages/e2e-tests/cli.mjs ${{ matrix.platform }} --create | |
| - name: Build Plain RN ${{ matrix.rn-version }} App | |
| run: ./dev-packages/e2e-tests/cli.mjs ${{ matrix.platform }} --build | |
| - name: Upload App | |
| if: matrix.build-type == 'production' | |
| uses: actions/upload-artifact@v6 | |
| 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() }} | |
| uses: actions/upload-artifact@v6 | |
| 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] | |
| 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.83.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.83.0' | |
| runs-on: macos-26 | |
| - platform: android | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install Maestro | |
| uses: dniHze/maestro-test-action@bda8a93211c86d0a05b7a4597c5ad134566fbde4 # [email protected] | |
| with: | |
| version: ${{env.MAESTRO_VERSION}} | |
| - name: Install iDB Companion | |
| if: ${{ matrix.platform == 'ios' }} | |
| run: brew tap facebook/fb && brew install facebook/fb/idb-companion | |
| - uses: ./.github/actions/disk-cleanup | |
| if: ${{ matrix.platform == 'android' }} | |
| - name: Setup Global Xcode Tools | |
| if: ${{ matrix.platform == 'ios' }} | |
| run: which xcbeautify || brew install xcbeautify | |
| - name: Download App Package | |
| if: matrix.build-type == 'production' | |
| uses: actions/download-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 | |
| - name: Enable Corepack | |
| run: npm i -g corepack | |
| - uses: actions/setup-node@v6 | |
| with: | |
| package-manager-cache: false | |
| node-version: 20 | |
| cache: 'yarn' | |
| cache-dependency-path: yarn.lock | |
| - uses: actions/setup-java@v5 | |
| with: | |
| java-version: '17' | |
| distribution: 'adopt' | |
| - name: Gradle cache | |
| uses: gradle/gradle-build-action@v3 | |
| - name: Setup KVM | |
| if: ${{ 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 | |
| run: yarn install | |
| - name: Run tests on Android | |
| if: ${{ matrix.platform == 'android' }} | |
| uses: reactivecircus/android-emulator-runner@b530d96654c385303d652368551fb075bc2f0b6b # [email protected] | |
| 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: ${{ matrix.platform == 'ios' }} | |
| run: xcrun simctl list devices available | |
| - uses: futureware-tech/simulator-action@dab10d813144ef59b48d401cd95da151222ef8cd # pin@v4 | |
| if: ${{ matrix.platform == 'ios' }} | |
| with: | |
| model: ${{ env.IOS_DEVICE }} | |
| os_version: ${{ env.IOS_VERSION }} | |
| - name: Run tests on iOS | |
| if: ${{ matrix.platform == 'ios' }} | |
| run: ./dev-packages/e2e-tests/cli.mjs ${{ matrix.platform }} --test | |
| - name: Upload logs | |
| if: ${{ always() }} | |
| uses: actions/upload-artifact@v6 | |
| 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 |