test(e2e): Add Detox and Envelope snapshot testing #5626
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: Sample Application | |
on: | |
push: | |
branches: | |
- main | |
- v5 | |
pull_request: | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
env: | |
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
RN_SENTRY_POD_NAME: RNSentry | |
IOS_APP_ARCHIVE_PATH: sentry-react-native-sample.app.zip | |
ANDROID_APP_ARCHIVE_PATH: sentry-react-native-sample.apk.zip | |
REACT_NATIVE_SAMPLE_PATH: samples/react-native | |
IOS_DEVICE: 'iPhone 16' | |
IOS_VERSION: '18.1' | |
ANDROID_API_LEVEL: '30' | |
jobs: | |
diff_check: | |
uses: ./.github/workflows/skip-ci.yml | |
build: | |
name: Build ${{ matrix.rn-architecture }} ${{ 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: | |
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'] | |
ios-use-frameworks: ['no-frameworks', 'dynamic-frameworks'] | |
platform: ['android', 'ios', 'macos'] | |
build-type: ['dev', 'production'] | |
include: | |
- platform: ios | |
runs-on: macos-15 | |
- platform: macos | |
runs-on: macos-15 | |
- platform: android | |
runs-on: ubuntu-latest | |
exclude: | |
- platform: 'android' | |
ios-use-frameworks: 'dynamic-frameworks' | |
- rn-architecture: 'new' | |
ios-use-frameworks: 'dynamic-frameworks' | |
- rn-architecture: 'new' | |
platform: 'macos' | |
- ios-use-frameworks: 'dynamic-frameworks' | |
platform: 'macos' | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Enable Corepack | |
run: | | |
npm install -g [email protected] | |
corepack enable | |
- uses: actions/setup-node@v4 | |
with: | |
node-version: 18 | |
cache: 'yarn' | |
cache-dependency-path: yarn.lock | |
- uses: ruby/setup-ruby@v1 | |
if: ${{ matrix.platform == 'ios' || matrix.platform == 'macos' }} | |
with: | |
working-directory: ${{ matrix.platform == 'ios' && env.REACT_NATIVE_SAMPLE_PATH || ' samples/react-native-macos' }} | |
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 | |
- uses: actions/setup-java@v4 | |
with: | |
java-version: '17' | |
distribution: 'adopt' | |
- name: Gradle cache | |
uses: gradle/gradle-build-action@v3 | |
- name: Setup Global Xcode Tools | |
if: ${{ matrix.platform == 'ios' }} | |
run: which xcbeautify || brew install xcbeautify | |
- name: Install SDK Dependencies | |
run: yarn install | |
- name: Build SDK | |
run: yarn build | |
- name: Install App Pods | |
if: ${{ matrix.platform == 'ios' || matrix.platform == 'macos' }} | |
working-directory: samples | |
run: | | |
[[ "${{ matrix.platform }}" == "ios" ]] && cd react-native/ios | |
[[ "${{ matrix.platform }}" == "macos" ]] && cd react-native-macos/macos | |
[[ "${{ matrix.build-type }}" == "production" ]] && ENABLE_PROD=1 || ENABLE_PROD=0 | |
[[ "${{ matrix.rn-architecture }}" == "new" ]] && ENABLE_NEW_ARCH=1 || ENABLE_NEW_ARCH=0 | |
[[ "${{ matrix.ios-use-frameworks }}" == "dynamic-frameworks" ]] && export USE_FRAMEWORKS=dynamic | |
echo "ENABLE_PROD=$ENABLE_PROD" | |
echo "ENABLE_NEW_ARCH=$ENABLE_NEW_ARCH" | |
PRODUCTION=$ENABLE_PROD RCT_NEW_ARCH_ENABLED=$ENABLE_NEW_ARCH bundle exec pod install | |
cat Podfile.lock | grep $RN_SENTRY_POD_NAME | |
- name: Build Android App | |
if: ${{ matrix.platform == 'android' }} | |
working-directory: ${{ env.REACT_NATIVE_SAMPLE_PATH }}/android | |
run: | | |
../scripts/set-aos-dsn.mjs | |
if [[ ${{ matrix.rn-architecture }} == 'new' ]]; then | |
perl -i -pe's/newArchEnabled=false/newArchEnabled=true/g' gradle.properties | |
echo 'New Architecture enabled' | |
elif [[ ${{ matrix.rn-architecture }} == 'legacy' ]]; then | |
perl -i -pe's/newArchEnabled=true/newArchEnabled=false/g' gradle.properties | |
echo 'Legacy Architecture enabled' | |
else | |
echo 'No changes for architecture: ${{ matrix.rn-architecture }}' | |
fi | |
[[ "${{ matrix.build-type }}" == "production" ]] && CONFIG='Release' || CONFIG='Debug' | |
echo "Building $CONFIG" | |
[[ "${{ matrix.build-type }}" == "production" ]] && TEST_TYPE='release' || TEST_TYPE='debug' | |
echo "Building $TEST_TYPE" | |
./gradlew ":app:assemble$CONFIG" app:assembleAndroidTest -DtestBuildType=$TEST_TYPE -PreactNativeArchitectures=x86 | |
- name: Build iOS App | |
if: ${{ matrix.platform == 'ios' }} | |
working-directory: ${{ env.REACT_NATIVE_SAMPLE_PATH }}/ios | |
run: | | |
../scripts/set-ios-dsn.mjs | |
[[ "${{ matrix.build-type }}" == "production" ]] && CONFIG='Release' || CONFIG='Debug' | |
echo "Building $CONFIG" | |
mkdir -p "DerivedData" | |
derivedData="$(cd "DerivedData" ; pwd -P)" | |
set -o pipefail && xcodebuild \ | |
-workspace sentryreactnativesample.xcworkspace \ | |
-configuration "$CONFIG" \ | |
-scheme sentryreactnativesample \ | |
-sdk 'iphonesimulator' \ | |
-destination 'generic/platform=iOS Simulator' \ | |
ONLY_ACTIVE_ARCH=yes \ | |
-derivedDataPath "$derivedData" \ | |
build \ | |
| tee xcodebuild.log \ | |
| xcbeautify --quieter --is-ci --disable-colored-output | |
- name: Build macOS App | |
if: ${{ matrix.platform == 'macos' }} | |
working-directory: samples/react-native-macos/macos | |
run: | | |
[[ "${{ matrix.build-type }}" == "production" ]] && CONFIG='Release' || CONFIG='Debug' | |
echo "Building $CONFIG" | |
mkdir -p "DerivedData" | |
derivedData="$(cd "DerivedData" ; pwd -P)" | |
set -o pipefail && xcodebuild \ | |
-workspace sentry-react-native-sample.xcworkspace \ | |
-configuration "$CONFIG" \ | |
-scheme sentry-react-native-sample-macOS \ | |
-destination 'platform=macOS' \ | |
ONLY_ACTIVE_ARCH=yes \ | |
-derivedDataPath "$derivedData" \ | |
build \ | |
| tee xcodebuild.log \ | |
| xcbeautify --quieter --is-ci --disable-colored-output | |
- name: Archive iOS App | |
if: ${{ matrix.platform == 'ios' && matrix.rn-architecture == 'new' && matrix.build-type == 'production' && matrix.ios-use-frameworks == 'no-frameworks' }} | |
run: | | |
cd ${{ env.REACT_NATIVE_SAMPLE_PATH }}/ios/DerivedData/Build/Products/Release-iphonesimulator | |
zip -r \ | |
${{ github.workspace }}/${{ env.IOS_APP_ARCHIVE_PATH }} \ | |
sentryreactnativesample.app | |
- name: Archive Android App | |
if: ${{ matrix.platform == 'android' && matrix.rn-architecture == 'new' && matrix.build-type == 'production' }} | |
run: | | |
mv ${{ env.REACT_NATIVE_SAMPLE_PATH }}/android/app/build/outputs/apk/release/app-release.apk app.apk | |
mv ${{ env.REACT_NATIVE_SAMPLE_PATH }}/android/app/build/outputs/apk/androidTest/release/app-release-androidTest.apk app-androidTest.apk | |
zip -j \ | |
${{ env.ANDROID_APP_ARCHIVE_PATH }} \ | |
app.apk \ | |
app-androidTest.apk | |
- name: Upload iOS APP | |
if: ${{ matrix.platform == 'ios' && matrix.rn-architecture == 'new' && matrix.build-type == 'production' && matrix.ios-use-frameworks == 'no-frameworks' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: sample-rn-${{ matrix.rn-architecture }}-${{ matrix.build-type }}-${{ matrix.ios-use-frameworks}}-${{ matrix.platform }} | |
path: ${{ env.IOS_APP_ARCHIVE_PATH }} | |
retention-days: 1 | |
- name: Upload Android APK | |
if: ${{ matrix.platform == 'android' && matrix.rn-architecture == 'new' && matrix.build-type == 'production' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: sample-rn-${{ matrix.rn-architecture }}-${{ matrix.build-type }}-${{ matrix.platform }} | |
path: ${{ env.ANDROID_APP_ARCHIVE_PATH }} | |
retention-days: 1 | |
- name: Upload logs | |
if: ${{ always() }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: build-sample-${{ matrix.rn-architecture }}-${{ matrix.platform }}-${{ matrix.build-type }}-${{ matrix.ios-use-frameworks}}-logs | |
path: ${{ env.REACT_NATIVE_SAMPLE_PATH }}/${{ matrix.platform }}/*.log | |
test: | |
name: Test ${{ matrix.platform }} ${{ matrix.build-type }} | |
runs-on: ${{ matrix.runs-on }} | |
needs: [diff_check, build] | |
if: ${{ needs.diff_check.outputs.skip_ci != 'true' }} | |
strategy: | |
# we want that the matrix keeps running, default is to cancel them if it fails. | |
fail-fast: false | |
matrix: | |
include: | |
- platform: ios | |
runs-on: macos-15 | |
rn-architecture: 'new' | |
ios-use-frameworks: 'no-frameworks' | |
build-type: 'production' | |
- platform: android | |
runs-on: ubuntu-latest | |
rn-architecture: 'new' | |
build-type: 'production' | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Download iOS App Archive | |
if: ${{ matrix.platform == 'ios' }} | |
uses: actions/download-artifact@v4 | |
with: | |
name: sample-rn-${{ matrix.rn-architecture }}-${{ matrix.build-type }}-${{ matrix.ios-use-frameworks}}-${{ matrix.platform }} | |
path: ${{ env.REACT_NATIVE_SAMPLE_PATH }} | |
- name: Download Android APK | |
if: ${{ matrix.platform == 'android' }} | |
uses: actions/download-artifact@v4 | |
with: | |
name: sample-rn-${{ matrix.rn-architecture }}-${{ matrix.build-type }}-${{ matrix.platform }} | |
path: ${{ env.REACT_NATIVE_SAMPLE_PATH }} | |
- name: Unzip iOS App Archive | |
if: ${{ matrix.platform == 'ios' }} | |
working-directory: ${{ env.REACT_NATIVE_SAMPLE_PATH }} | |
run: unzip ${{ env.IOS_APP_ARCHIVE_PATH }} | |
- name: Unzip Android APK | |
if: ${{ matrix.platform == 'android' }} | |
working-directory: ${{ env.REACT_NATIVE_SAMPLE_PATH }} | |
run: unzip ${{ env.ANDROID_APP_ARCHIVE_PATH }} | |
- name: Enable Corepack | |
run: | | |
npm install -g [email protected] | |
corepack enable | |
- uses: actions/setup-node@v4 | |
with: | |
node-version: 18 | |
cache: 'yarn' | |
cache-dependency-path: yarn.lock | |
- name: Install JS Dependencies | |
run: yarn install | |
- name: Install Detox | |
run: npm install -g [email protected] | |
- name: Install Apple Simulator Utilities | |
if: ${{ matrix.platform == 'ios' }} | |
run: | | |
brew tap wix/brew | |
brew install applesimutils | |
- uses: futureware-tech/simulator-action@dab10d813144ef59b48d401cd95da151222ef8cd # pin@v4 | |
if: ${{ matrix.platform == 'ios' }} | |
with: | |
# the same envs are used by Detox ci.sim configuration | |
model: ${{ env.IOS_DEVICE }} | |
os_version: ${{ env.IOS_VERSION }} | |
- name: Run Detox iOS Tests | |
if: ${{ matrix.platform == 'ios' }} | |
working-directory: ${{ env.REACT_NATIVE_SAMPLE_PATH }} | |
run: detox test --configuration ci.sim | |
- name: Run tests on Android | |
if: ${{ matrix.platform == 'android' }} | |
env: | |
# used by Detox ci.android configuration | |
ANDROID_AVD_NAME: 'test' # test is default reactivecircus/android-emulator-runner name | |
uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # [email protected] | |
with: | |
api-level: ${{ env.ANDROID_API_LEVEL }} | |
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 | |
working-directory: ${{ env.REACT_NATIVE_SAMPLE_PATH }} | |
script: detox test --configuration ci.android |