From d4eae6a5cac0ced1b62880fee503875dd0479fef Mon Sep 17 00:00:00 2001 From: Joseph <162703152+josephnef@users.noreply.github.com> Date: Sun, 18 Oct 2026 09:29:33 +0300 Subject: [PATCH 1/2] Add a non-blocking emulator smoke job to PR checks Runs the debug APK on an x86_64 API-34 emulator under NDK ARM translation and drives flows/pixelpilot_smoke.py from android-emulator-qa: accept the VPN consent, reach the no-adapter screen, then decode a synthetic H.264 RTP stream pushed to UDP 5600 and assert on the decoder's logcat milestones. Screenshots, UI dumps, logcat and verdict.json are uploaded as an artifact. continue-on-error until it has proven stable on hosted runners. Co-Authored-By: Claude Fable 5.1 --- .github/workflows/pr.yml | 69 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 0c496f8d..7f6306aa 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -55,6 +55,8 @@ jobs: build: name: Debug APK runs-on: ubuntu-latest + outputs: + artifact: ${{ steps.artifact_name.outputs.name }} steps: # Non-recursive on purpose: the build only needs devourer and wfb-ng # themselves. devourer's own reference/ submodules are vendor driver @@ -74,14 +76,73 @@ jobs: - name: Build run: ./gradlew assembleDebug - - name: Short SHA - id: sha - run: echo "short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" + - name: Artifact name + id: artifact_name + run: echo "name=PixelPilot-debug-$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" - name: Upload debug APK uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: - name: PixelPilot-debug-${{ steps.sha.outputs.short }} + name: ${{ steps.artifact_name.outputs.name }} path: app/build/outputs/apk/debug/app-debug.apk retention-days: 14 if-no-files-found: error + + # Hardware-free end-to-end check of the videonative path: the debug APK runs + # on an x86_64 API-34 emulator under NDK ARM translation (PixelPilot ships + # arm64/armv7 only), accepts the VPN consent, reaches the no-adapter screen, + # and decodes a synthetic H.264 RTP stream pushed to UDP 5600. Driven by + # flows/pixelpilot_smoke.py from OpenIPC/android-emulator-qa. + # Non-blocking for now: emulator runs are slower and flakier than the rest. + emulator-smoke: + name: Emulator smoke (non-blocking) + runs-on: ubuntu-latest + needs: build + continue-on-error: true + timeout-minutes: 30 + steps: + - name: Check out the QA harness + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + # TODO: switch to OpenIPC/android-emulator-qa at a pinned main SHA once + # the pixelpilot-smoke flow PR is merged there. + repository: josephnef/android-emulator-qa + ref: pixelpilot-smoke + path: qa + + - name: Download debug APK + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + with: + name: ${{ needs.build.outputs.artifact }} + path: apk + + - name: Enable KVM + 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 + + - name: Install ffmpeg + run: | + sudo apt-get update -q + sudo apt-get install -y -q ffmpeg + + - name: Run smoke flow on an API 34 x86_64 emulator + uses: reactivecircus/android-emulator-runner@a421e43855164a8197daf9d8d40fe71c6996bb0d # v2.38.0 + with: + api-level: 34 + target: google_apis + arch: x86_64 + force-avd-creation: false + emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -no-snapshot-save -camera-back none + disable-animations: true + script: python3 qa/flows/pixelpilot_smoke.py --apk apk/app-debug.apk --run-dir qa-run --stream 15 + + - name: Upload run artifacts (screenshots, dumps, logcat, verdict) + if: always() + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + with: + name: emulator-smoke-${{ needs.build.outputs.artifact }} + path: qa-run + retention-days: 14 + if-no-files-found: warn From 409b27ff67af13502d791a591ba4ab32f4d7f6ca Mon Sep 17 00:00:00 2001 From: Joseph <162703152+josephnef@users.noreply.github.com> Date: Sun, 18 Oct 2026 09:47:28 +0300 Subject: [PATCH 2/2] Pin the QA harness checkout to OpenIPC/android-emulator-qa main The pixelpilot_smoke flow has landed upstream, so the emulator job no longer needs the fork branch. Co-Authored-By: Claude Fable 5.1 --- .github/workflows/pr.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 7f6306aa..535f827a 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -104,10 +104,8 @@ jobs: - name: Check out the QA harness uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - # TODO: switch to OpenIPC/android-emulator-qa at a pinned main SHA once - # the pixelpilot-smoke flow PR is merged there. - repository: josephnef/android-emulator-qa - ref: pixelpilot-smoke + repository: OpenIPC/android-emulator-qa + ref: 3be94489105f6ff8903a1dcdae90fa437cbbb23c # main, flows/pixelpilot_smoke.py added path: qa - name: Download debug APK