fix(android): protect against headlessJS task multiple-invocation #668
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/**' | |
- '**/*.md' | |
push: | |
branches: | |
- main | |
paths-ignore: | |
- 'docs/**' | |
- '**/*.md' | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
jobs: | |
android: | |
name: Android | |
runs-on: ubuntu-latest | |
timeout-minutes: 60 | |
strategy: | |
fail-fast: false | |
matrix: | |
# Currently just API31 to mirror prior testing | |
# TODO: determine min we can test, and test max as well | |
api-level: [31] | |
arch: [x86_64] | |
target: [google_apis] | |
# This is useful for benchmarking, do 0, 1, 2, etc (up to 256 max job-per-matrix limit) for averages | |
iteration: [0] | |
env: | |
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
steps: | |
- name: Liberate disk space | |
uses: jlumbroso/free-disk-space@main | |
with: | |
tool-cache: false | |
android: false | |
dotnet: true | |
haskell: true | |
large-packages: false | |
docker-images: true | |
swap-storage: false | |
- name: Enable KVM group perms | |
run: | | |
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 | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 50 | |
- uses: actions/setup-node@v4 | |
with: | |
node-version: 20 | |
- name: Set workflow variables | |
id: workflow-variables | |
run: | | |
echo "yarn-cache=$(yarn cache dir)" >> $GITHUB_OUTPUT | |
echo "metro-cache=$HOME/.metro" >> $GITHUB_OUTPUT | |
- uses: actions/cache@v4 | |
name: Yarn Cache | |
id: yarn-cache | |
with: | |
path: ${{ steps.workflow-variables.outputs.yarn-cache }} | |
key: ${{ runner.os }}-yarn-v1-${{ hashFiles('package.json', 'packages/react-native/package.json', 'tests_react_native/package.json') }} | |
restore-keys: ${{ runner.os }}-yarn-v1 | |
- uses: actions/cache@v4 | |
name: Gradle Cache | |
with: | |
path: ~/.gradle/caches | |
key: ${{ runner.os }}-gradle-v1--${{ hashFiles('package.json', 'packages/react-native/package.json', 'tests_react_native/package.json', 'packages/react-native/android/build.gradle', 'tests_react_native/android/build.gradle', 'tests_react_native/android/app/build.gradle') }} | |
restore-keys: ${{ runner.os }}-gradle-v1 | |
- uses: actions/cache@v4 | |
name: Cache Pods | |
with: | |
path: tests_react_native/ios/Pods | |
key: ${{ runner.os }}-pods-v2-${{ hashFiles('tests_react_native/ios/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-fields/retry@v3 | |
with: | |
timeout_minutes: 2 | |
retry_wait_seconds: 60 | |
max_attempts: 3 | |
command: gem update cocoapods xcodeproj | |
- name: Yarn Install | |
uses: nick-fields/retry@v3 | |
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-fields/retry@v3 | |
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@v4 | |
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: Emulator Tests | |
uses: reactivecircus/android-emulator-runner@v2 | |
timeout-minutes: 60 | |
with: | |
api-level: ${{ matrix.api-level }} | |
avd-name: TestingAVD | |
target: ${{ matrix.target }} | |
arch: ${{ matrix.arch }} | |
pre-emulator-launch-script: | | |
sudo mkdir /mnt/avd | |
sudo chown $USER:$USER /mnt/avd | |
mkdir -p $HOME/.android | |
ln -s /mnt/avd $HOME/.android/avd | |
script: | | |
$ANDROID_HOME/platform-tools/adb devices | |
nohup sh -c "$ANDROID_HOME/platform-tools/adb logcat '*:D' > adb-log.txt" & | |
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" &' | |
yarn tests_rn:android:test || touch tests-failed.out # even on failure do not exit yet... | |
adb pull /data/local/tmp/emulator1.mp4 || true # ...because we want to download our videos... | |
adb pull /data/local/tmp/emulator2.mp4 || true # ...and we need the emulator up to fetch them | |
adb pull /data/local/tmp/emulator3.mp4 || true | |
adb pull /data/local/tmp/emulator4.mp4 || true | |
if test -e tests-failed.out; then exit 1; fi # now exit with error code if tests failed | |
- uses: codecov/codecov-action@v4 | |
with: | |
verbose: true | |
- name: Upload Emulator Log | |
uses: actions/upload-artifact@v4 | |
if: always() | |
with: | |
name: adb_logs | |
path: adb-log.txt | |
- name: Upload Packager Log | |
uses: actions/upload-artifact@v4 | |
if: always() | |
with: | |
name: packager_log | |
path: packager.log | |
- name: Upload App Video | |
uses: actions/upload-artifact@v4 | |
if: always() | |
with: | |
name: emulator_video | |
path: emulator*.mp4 |