@@ -306,3 +306,97 @@ jobs:
306306 run : |
307307 echo "=== Checking simulator logs for errors ==="
308308 xcrun simctl spawn booted log show --predicate 'processImagePath CONTAINS "RiveExample"' --last 5m --style compact 2>&1 | tail -200 || echo "No logs found"
309+
310+ test-harness-android :
311+ runs-on : ubuntu-latest
312+ env :
313+ ANDROID_API_LEVEL : 35
314+ steps :
315+ - name : Checkout
316+ uses : actions/checkout@v4
317+
318+ - name : Setup
319+ uses : ./.github/actions/setup
320+
321+ - name : Install JDK
322+ uses : actions/setup-java@v4
323+ with :
324+ distribution : ' zulu'
325+ java-version : ' 17'
326+
327+ - name : Finalize Android SDK
328+ run : |
329+ /bin/bash -c "yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses > /dev/null"
330+
331+ - name : Cache Gradle
332+ uses : actions/cache@v4
333+ with :
334+ path : |
335+ ~/.gradle/wrapper
336+ ~/.gradle/caches
337+ key : ${{ runner.os }}-gradle-harness-${{ hashFiles('example/android/gradle/wrapper/gradle-wrapper.properties') }}
338+ restore-keys : |
339+ ${{ runner.os }}-gradle-harness-
340+ ${{ runner.os }}-gradle-
341+
342+ - name : Restore Android build cache
343+ id : android-build-cache
344+ uses : actions/cache/restore@v4
345+ with :
346+ path : example/android/app/build
347+ key : ${{ runner.os }}-android-build-${{ env.ANDROID_API_LEVEL }}-${{ hashFiles('yarn.lock', 'android/**', 'nitrogen/generated/android/**', 'example/android/app/build.gradle', 'example/android/gradle.properties') }}
348+ restore-keys : |
349+ ${{ runner.os }}-android-build-${{ env.ANDROID_API_LEVEL }}-
350+
351+ - name : Build Android app
352+ if : steps.android-build-cache.outputs.cache-hit != 'true'
353+ working-directory : example/android
354+ env :
355+ JAVA_OPTS : " -XX:MaxHeapSize=6g"
356+ run : |
357+ ./gradlew assembleDebug --no-daemon --console=plain -PreactNativeArchitectures=x86_64
358+
359+ - name : Save Android build cache
360+ if : steps.android-build-cache.outputs.cache-hit != 'true'
361+ uses : actions/cache/save@v4
362+ with :
363+ path : example/android/app/build
364+ key : ${{ steps.android-build-cache.outputs.cache-primary-key }}
365+
366+ - name : Enable KVM
367+ run : |
368+ echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
369+ sudo udevadm control --reload-rules
370+ sudo udevadm trigger --name-match=kvm
371+
372+ - name : Run harness tests on Android
373+ uses : reactivecircus/android-emulator-runner@v2
374+ with :
375+ api-level : ${{ env.ANDROID_API_LEVEL }}
376+ arch : x86_64
377+ target : google_apis
378+ force-avd-creation : false
379+ emulator-options : -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim
380+ disable-animations : true
381+ script : |
382+ adb install example/android/app/build/outputs/apk/debug/app-debug.apk
383+ sleep 10
384+ cd example
385+ # Retry up to 3 times due to flaky harness connection
386+ for attempt in 1 2 3; do
387+ echo "Attempt $attempt of 3"
388+ if ANDROID_AVD=test yarn test:harness:android --verbose --testTimeout 120000; then
389+ echo "Tests passed on attempt $attempt"
390+ exit 0
391+ fi
392+ echo "Attempt $attempt failed, retrying..."
393+ sleep 5
394+ done
395+ echo "All attempts failed"
396+ exit 1
397+
398+ - name : Debug - Check logcat
399+ if : failure()
400+ run : |
401+ echo "=== Checking logcat for errors ==="
402+ adb logcat -d -s ReactNativeJS:* RiveExample:* RNRive:* | tail -200 || echo "No logs found"
0 commit comments