feat: Session Replay is GA #10543
This file contains 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 | |
on: | |
push: | |
branches: | |
- main | |
- v5 | |
- release/** | |
pull_request: | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
env: | |
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
MAESTRO_VERSION: '1.39.0' | |
IOS_DEVICE: 'iPhone 16' | |
IOS_VERSION: '18.1' | |
jobs: | |
diff_check: | |
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-13 | |
name: iOS | |
appPlain: performance-tests/test-app-plain.ipa | |
- platform: android | |
runs-on: ubuntu-latest | |
name: Android | |
appPlain: performance-tests/TestAppPlain/android/app/build/outputs/apk/release/app-release.apk | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/disk-cleanup | |
if: ${{ matrix.platform == 'android' }} | |
- run: sudo xcode-select -s /Applications/Xcode_14.2.app/Contents/Developer | |
if: ${{ matrix.platform == 'ios' }} | |
- run: corepack enable | |
- uses: actions/setup-node@v4 | |
with: | |
node-version: 18 | |
cache: 'yarn' | |
cache-dependency-path: yarn.lock | |
- uses: actions/setup-java@v4 | |
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@v4 | |
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 | |
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@v1 | |
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] | |
if: ${{ needs.diff_check.outputs.skip_ci != 'true' }} | |
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' }} | |
strategy: | |
fail-fast: false # keeps matrix running if one fails | |
matrix: | |
rn-version: ['0.65.3', '0.76.0'] | |
rn-architecture: ['legacy', 'new'] | |
platform: ['android', 'ios'] | |
build-type: ['production'] | |
ios-use-frameworks: ['no', 'static', 'dynamic'] | |
engine: ['hermes', 'jsc'] | |
include: | |
- platform: ios | |
rn-version: '0.76.0' | |
runs-on: macos-14 | |
- platform: ios | |
rn-version: '0.65.3' | |
runs-on: macos-13 | |
- platform: android | |
runs-on: ubuntu-latest | |
exclude: | |
# exclude JSC for new RN versions (keeping the matrix manageable) | |
- rn-version: '0.76.0' | |
engine: 'jsc' | |
# exclude all rn versions lower than 0.70.0 for new architecture | |
- rn-version: '0.65.3' | |
rn-architecture: 'new' | |
# exlude old rn version for use frameworks builds (to minimalize the matrix) | |
- rn-version: '0.65.3' | |
platform: 'ios' | |
ios-use-frameworks: 'static' | |
- rn-version: '0.65.3' | |
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' | |
steps: | |
- uses: actions/checkout@v4 | |
- 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_14.2.app/Contents/Developer | |
if: ${{ matrix.platform == 'ios' && matrix.rn-version == '0.65.3' }} | |
- run: corepack enable | |
- uses: actions/setup-node@v4 | |
with: | |
node-version: 18 | |
cache: 'yarn' | |
cache-dependency-path: yarn.lock | |
- uses: actions/setup-java@v4 | |
with: | |
java-version: ${{ matrix.rn-version == '0.65.3' && '11' || '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 | |
- name: Setup Plain RN ${{ matrix.rn-version }} App | |
run: ./dev-packages/e2e-tests/cli.mjs ${{ matrix.platform }} --create | |
# The old node has to be enabled after creating the test app | |
# to avoid issues with the old node version | |
- run: corepack disable | |
- uses: actions/setup-node@v4 | |
if: ${{ matrix.rn-version == '0.65.3' }} | |
with: | |
node-version: 16 | |
- uses: ruby/setup-ruby@v1 | |
if: ${{ matrix.platform == 'ios' }} | |
with: | |
working-directory: dev-packages/e2e-tests/react-native-versions/${{ matrix.rn-version }}/RnDiffApp | |
ruby-version: '3.3.0' # based on what is used in the sample | |
bundler-cache: true # runs 'bundle install' and caches installed gems automatically | |
cache-version: 1 # cache the installed gems | |
- 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@v4 | |
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@v4 | |
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.65.3', '0.76.0'] | |
rn-architecture: ['legacy', 'new'] | |
platform: ['android', 'ios'] | |
build-type: ['production'] | |
ios-use-frameworks: ['no'] # test only no framworks | |
engine: ['hermes', 'jsc'] | |
include: | |
- platform: ios | |
rn-version: '0.76.0' | |
runs-on: macos-15 | |
- platform: ios | |
rn-version: '0.65.3' | |
runs-on: macos-15 | |
- platform: android | |
runs-on: ubuntu-latest | |
exclude: | |
# exclude all rn versions lower than 0.70.0 for new architecture | |
- rn-version: '0.65.3' | |
rn-architecture: 'new' | |
# e2e test only the default combinations | |
- rn-version: '0.65.3' | |
engine: 'hermes' | |
- rn-version: '0.76.0' | |
engine: 'jsc' | |
steps: | |
- uses: actions/checkout@v4 | |
- 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@v4 | |
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 install -g [email protected] | |
corepack enable | |
- uses: actions/setup-node@v4 | |
with: | |
node-version: 20 | |
cache: 'yarn' | |
cache-dependency-path: yarn.lock | |
- uses: actions/setup-java@v4 | |
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@62dbb605bba737720e10b196cb4220d374026a6d # [email protected] | |
with: | |
api-level: 30 | |
force-avd-creation: false | |
disable-animations: true | |
disable-spellchecker: true | |
target: 'aosp_atd' | |
channel: canary # Necessary for ATDs | |
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 | |
- 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@v4 | |
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 |