build(deps): get react-native code and CI working on current toolchains #511
Workflow file for this run
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: Testing E2E Android | |
on: | |
workflow_dispatch: | |
pull_request: | |
paths-ignore: | |
- 'docs-react-native/**' | |
- '**/*.md' | |
push: | |
branches: | |
- main | |
paths-ignore: | |
- 'docs-react-native/**' | |
- '**/*.md' | |
jobs: | |
android: | |
name: Android | |
runs-on: macos-latest | |
timeout-minutes: 60 | |
env: | |
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
EMULATOR_COMMAND: "-avd TestingAVD -noaudio -gpu swiftshader_indirect -camera-back none -no-snapshot -no-window -no-boot-anim -nojni -memory 2048 -timezone 'Europe/London' -cores 2" | |
EMULATOR_EXECUTABLE: qemu-system-x86_64-headless | |
steps: | |
- uses: styfle/[email protected] | |
- uses: actions/checkout@v2 | |
with: | |
fetch-depth: 50 | |
- uses: actions/setup-node@v2 | |
with: | |
node-version: 18 | |
# Set path variables needed for caches | |
- name: Set workflow variables | |
id: workflow-variables | |
run: | | |
echo "::set-output name=metro-cache::$HOME/.metro" | |
echo "::set-output name=yarn-cache-dir::$(yarn cache dir)" | |
- uses: actions/cache@v2 | |
name: Yarn Cache | |
id: yarn-cache | |
with: | |
path: ${{ steps.workflow-variables.outputs.yarn-cache-dir }} | |
key: ${{ runner.os }}-yarn-v1-${{ hashFiles('**/package.json') }} | |
restore-keys: ${{ runner.os }}-yarn-v1 | |
- uses: actions/cache@v2 | |
name: Gradle Cache | |
with: | |
path: ~/.gradle/caches | |
key: ${{ runner.os }}-gradle-v1-${{ hashFiles('**/*.gradle*') }} | |
restore-keys: ${{ runner.os }}-gradle-v1 | |
- uses: actions/cache@v2 | |
name: Cache Pods | |
with: | |
path: tests_react_native/ios/Pods | |
key: ${{ runner.os }}-pods-v2-${{ hashFiles('**/Podfile.lock') }} | |
restore-keys: ${{ runner.os }}-pods-v2 | |
- name: Setup Ruby | |
uses: ruby/setup-ruby@v1 | |
with: | |
ruby-version: 3 | |
- name: Update Ruby build tools | |
uses: nick-invision/retry@v2 | |
with: | |
timeout_minutes: 2 | |
retry_wait_seconds: 60 | |
max_attempts: 3 | |
command: gem update cocoapods xcodeproj | |
- name: Yarn Install | |
uses: nick-invision/retry@v2 | |
with: | |
timeout_minutes: 15 | |
retry_wait_seconds: 60 | |
max_attempts: 4 | |
command: yarn --no-audit --prefer-offline && npm i -g cavy-cli | |
- name: Configure JDK | |
uses: actions/setup-java@v4 | |
with: | |
distribution: 'temurin' | |
java-version: '17' | |
- name: Build Android App | |
uses: nick-invision/retry@v2 | |
with: | |
timeout_minutes: 10 | |
retry_wait_seconds: 60 | |
max_attempts: 3 | |
command: yarn tests_rn:android:build | |
- name: Prepare test index file | |
# For some reason, in CI, the test file is never running. So let's make all index files the test file. | |
run: cp tests_react_native/index.test.js tests_react_native/index.js | |
- name: Metro Bundler Cache | |
uses: actions/cache@v2 | |
with: | |
path: ${{ steps.workflow-variables.outputs.metro-cache }} | |
key: ${{ runner.os }}-metro-v1-${{ github.run_id }} | |
restore-keys: ${{ runner.os }}-metro-v1 | |
- name: Pre-fetch Javascript bundle | |
# Prebuild the bundle so that's fast when the app starts. | |
run: | | |
nohup sh -c "yarn tests_rn:packager > packager.log 2>&1 &" | |
printf 'Waiting for packager to come online' | |
until curl --output /dev/null --silent --head --fail http://localhost:8081/status; do | |
printf '.' | |
sleep 2 | |
done | |
echo "Packager is online! Preparing javascript bundle..." | |
curl --output /dev/null --silent --head --fail "http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&inlineSourceMap=true" | |
echo "...javascript bundle ready." | |
- name: Download Emulator Image | |
# This can fail on network request, wrap with retry | |
uses: nick-invision/retry@v2 | |
with: | |
timeout_minutes: 10 | |
retry_wait_seconds: 60 | |
max_attempts: 3 | |
command: echo "y" | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --install "system-images;android-31;google_apis;x86_64" | |
- name: Create Emulator | |
run: echo "no" | $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager create avd --force --name TestingAVD --device "Nexus 5X" -k 'system-images;android-31;google_apis;x86_64' -g google_apis | |
# These Emulator start steps are the current best practice to do retries on multi-line commands with persistent (nohup) processes | |
- name: Start Android Emulator | |
id: emu1 | |
timeout-minutes: 5 | |
continue-on-error: true | |
run: | | |
echo "Starting emulator" | |
nohup $ANDROID_HOME/emulator/emulator $EMULATOR_COMMAND & | |
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done' | |
- name: Start Android Emulator Retry 1 | |
id: emu2 | |
if: steps.emu1.outcome=='failure' | |
timeout-minutes: 5 | |
continue-on-error: true | |
run: | | |
echo "Starting emulator, second attempt" | |
$ANDROID_HOME/platform-tools/adb devices | |
sudo killall -9 $EMULATOR_EXECUTABLE || true | |
sleep 2 | |
nohup $ANDROID_HOME/emulator/emulator $EMULATOR_COMMAND & | |
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done' | |
- name: Start Android Emulator Retry 2 | |
id: emu3 | |
if: steps.emu2.outcome=='failure' | |
timeout-minutes: 5 | |
continue-on-error: true | |
run: | | |
echo "Starting emulator, third attempt" | |
$ANDROID_HOME/platform-tools/adb devices | |
sudo killall -9 $EMULATOR_EXECUTABLE || true | |
sleep 2 | |
nohup $ANDROID_HOME/emulator/emulator $EMULATOR_COMMAND & | |
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done' | |
- name: Emulator Status | |
if: always() | |
run: | | |
if ${{ steps.emu1.outcome=='success' || steps.emu2.outcome=='success' || steps.emu3.outcome=='success' }}; then | |
echo "Emulator Started" | |
else | |
exit 1 | |
fi | |
- name: Record Emulator Video | |
# screenrecord has a 180 second time limit, with 4 recordings we should capture the run | |
continue-on-error: true | |
run: nohup sh -c 'adb shell "screenrecord /data/local/tmp/emulator1.mp4; screenrecord /data/local/tmp/emulator2.mp4; screenrecord /data/local/tmp/emulator3.mp4; screenrecord /data/local/tmp/emulator4.mp4" &' | |
- name: E2E Test | |
timeout-minutes: 20 | |
run: | | |
$ANDROID_HOME/platform-tools/adb devices | |
$ANDROID_HOME/platform-tools/adb shell settings put global window_animation_scale 0.0 | |
$ANDROID_HOME/platform-tools/adb shell settings put global transition_animation_scale 0.0 | |
$ANDROID_HOME/platform-tools/adb shell settings put global animator_duration_scale 0.0 | |
nohup sh -c "$ANDROID_HOME/platform-tools/adb logcat '*:D' > adb-log.txt" & | |
yarn tests_rn:android:test | |
shell: bash | |
- name: Submit Coverage | |
# This can fail on timeouts etc, wrap with retry | |
uses: nick-invision/retry@v2 | |
with: | |
timeout_minutes: 10 | |
retry_wait_seconds: 60 | |
max_attempts: 3 | |
command: curl https://codecov.io/bash -o codecov.sh && bash ./codecov.sh | |
- name: Compress Emulator Log | |
if: always() | |
run: gzip -9 adb-log.txt | |
shell: bash | |
- name: Upload Emulator Log | |
uses: actions/upload-artifact@v2 | |
if: always() | |
with: | |
name: adb_logs | |
path: adb-log.txt.gz | |
- name: Upload Packager Log | |
uses: actions/upload-artifact@v2 | |
if: always() | |
with: | |
name: packager_log | |
path: packager.log | |
- name: Stop and Retrieve App Video | |
if: always() | |
continue-on-error: true | |
run: | | |
killall -INT adb | |
adb kill-server | |
sleep 2 | |
adb start-server | |
sleep 2 | |
adb pull /data/local/tmp/emulator1.mp4 | |
adb pull /data/local/tmp/emulator2.mp4 | |
adb pull /data/local/tmp/emulator3.mp4 | |
adb pull /data/local/tmp/emulator4.mp4 | |
- name: Upload App Video | |
uses: actions/upload-artifact@v2 | |
if: always() | |
with: | |
name: emulator_video | |
path: emulator*.mp4 |