From b8086f89dfae422bdfb50d0c37fec46b7d2bfedb Mon Sep 17 00:00:00 2001 From: Jason Ross Date: Tue, 30 Jun 2026 12:45:41 -0500 Subject: [PATCH 1/2] ci: make API 37 preview emulator boot fail-fast and diagnosable The custom-provisioned preview job hung in 'Boot emulator and run E2E' until the 35-min cap: adb wait-for-device had no timeout and the emulator's own output was never captured, so a failed boot was both invisible and unbounded. Bound the wait with a single 300s timeout covering device registration + full boot, retry once, capture the emulator log, and dump it (plus logcat) on failure. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/ci.yml | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab7e81e..9fdc517 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -227,13 +227,42 @@ jobs: - name: Boot emulator and run E2E run: | set -euo pipefail - "$ANDROID_SDK_ROOT/emulator/emulator" -avd api37 \ - -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -no-snapshot -camera-back none & - adb wait-for-device - timeout 300 bash -c 'while [ "$(adb shell getprop sys.boot_completed | tr -d "\r")" != "1" ]; do sleep 3; done' + EMU_LOG="${RUNNER_TEMP:-/tmp}/emulator.log" + + boot_emulator() { + echo "::group::Start API 37 emulator (attempt $1)" + # Capture the emulator's own output — without this a boot failure is invisible. + "$ANDROID_SDK_ROOT/emulator/emulator" -avd api37 \ + -no-window -no-audio -no-boot-anim -no-snapshot -accel on \ + -gpu swiftshader_indirect -camera-back none -camera-front none > "$EMU_LOG" 2>&1 & + # ONE bounded wait covering both device registration and full boot, so a stuck emulator + # fails fast instead of hanging the whole job until the 35-min cap (the original bug). + if timeout 300 adb wait-for-device shell \ + 'while [ "$(getprop sys.boot_completed | tr -d "\r")" != "1" ]; do sleep 2; done'; then + echo "::endgroup::"; return 0 + fi + echo "::endgroup::" + echo "::warning::API 37 emulator did not boot within 300s (attempt $1)" + adb devices || true + echo "--- emulator.log (tail) ---"; tail -120 "$EMU_LOG" || true + adb emu kill 2>/dev/null || true + sleep 5 + return 1 + } + + booted=0 + for attempt in 1 2; do boot_emulator "$attempt" && { booted=1; break; }; done + [ "$booted" = "1" ] || { echo "::error::API 37 preview emulator failed to boot after 2 attempts"; exit 1; } + adb shell input keyevent 82 || true ./gradlew connectedDebugAndroidTest --stacktrace + - name: Dump emulator log on failure + if: failure() + run: | + echo "--- emulator.log ---"; tail -200 "${RUNNER_TEMP:-/tmp}/emulator.log" 2>/dev/null || echo "(none)" + echo "--- logcat ---"; adb logcat -d 2>/dev/null | tail -120 || echo "(device unavailable)" + - name: Shut down emulator if: always() run: adb emu kill || true -- 2.47.3 From fe0593dba1e0621d7146adeb77e65825905c8c89 Mon Sep 17 00:00:00 2001 From: Jason Ross Date: Tue, 30 Jun 2026 12:59:35 -0500 Subject: [PATCH 2/2] ci: pin ANDROID_AVD_HOME so the API 37 preview emulator finds its AVD The preview emulator failed every boot with "Unknown AVD name [api37]" and exited immediately (no device -> the bounded wait timed out). avdmanager had created the AVD under $ANDROID_SDK_HOME/.android/avd while the emulator searched $ANDROID_SDK_HOME/avd and $HOME/.android/avd. Pin ANDROID_AVD_HOME to one path both tools use, carry it to the boot step via $GITHUB_ENV, and list AVDs after creation to verify. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/ci.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9fdc517..f9564f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -222,7 +222,16 @@ jobs: run: sdkmanager "$ANDROID_PLATFORM" "$ANDROID_BUILD_TOOLS" "platform-tools" "emulator" "$API37_IMAGE" - name: Create API 37 AVD - run: echo "no" | avdmanager create avd -n api37 -k "$API37_IMAGE" -d pixel_2 --force + run: | + # avdmanager and the emulator disagree on the default AVD dir when ANDROID_SDK_HOME is set + # on the runner (avdmanager writes $ANDROID_SDK_HOME/.android/avd; the emulator looks in + # $ANDROID_SDK_HOME/avd), which made the boot step report "Unknown AVD name [api37]". Pin + # ANDROID_AVD_HOME so both agree, and carry it to the boot step via $GITHUB_ENV. + export ANDROID_AVD_HOME="$HOME/.android/avd" + echo "ANDROID_AVD_HOME=$ANDROID_AVD_HOME" >> "$GITHUB_ENV" + mkdir -p "$ANDROID_AVD_HOME" + echo "no" | avdmanager create avd -n api37 -k "$API37_IMAGE" -d pixel_2 --force + echo "AVDs visible to the emulator:"; "$ANDROID_SDK_ROOT/emulator/emulator" -list-avds - name: Boot emulator and run E2E run: | -- 2.47.3