From 6211c769bc44dec799407c5ab54dccff7e1b3cf3 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 06:55:37 +0300 Subject: [PATCH 01/14] Ensure emulator runner installs platform tools --- .github/workflows/scripts-android.yml | 93 +++++++++++++++++++ .../codename1/samples/SampleHelloTest.java | 50 ++++++++++ scripts/build-android-app.sh | 80 +++++++++++++++- 3 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 Samples/SampleProjectTemplate/test/com/codename1/samples/SampleHelloTest.java diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index b1ba7def43..a6fbed7f54 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -15,6 +15,11 @@ name: Test Android build scripts jobs: build-android: runs-on: ubuntu-latest + outputs: + artifact_dir: ${{ steps.build-app.outputs.artifact_dir }} + app_apk: ${{ steps.build-app.outputs.app_apk }} + test_apk: ${{ steps.build-app.outputs.test_apk }} + package_name: ${{ steps.build-app.outputs.package_name }} steps: - uses: actions/checkout@v4 - name: Setup workspace @@ -22,4 +27,92 @@ jobs: - name: Build Android port run: ./scripts/build-android-port.sh -q -DskipTests - name: Build Hello Codename One Android app + id: build-app run: ./scripts/build-android-app.sh -q -DskipTests + - name: Upload Android APK artifacts + uses: actions/upload-artifact@v4 + with: + name: hello-codenameone-apks + path: ${{ steps.build-app.outputs.artifact_dir }} + if-no-files-found: error + + android-device-tests: + needs: build-android + runs-on: ubuntu-22.04-arm + steps: + - name: Download APK artifacts + uses: actions/download-artifact@v4 + with: + name: hello-codenameone-apks + path: artifacts + - name: Launch emulator and capture screenshots + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 33 + arch: arm64-v8a + profile: pixel_6 + pre-emulator-launch-script: | + set -euxo pipefail + if command -v sdkmanager >/dev/null 2>&1; then + yes | sdkmanager --install "platform-tools" >/dev/null + else + echo "sdkmanager executable is required for installing platform-tools" >&2 + exit 1 + fi + if [ -n "${ANDROID_HOME:-}" ] && [ -d "${ANDROID_HOME}/platform-tools" ]; then + echo "${ANDROID_HOME}/platform-tools" >> "$GITHUB_PATH" + elif [ -n "${ANDROID_SDK_ROOT:-}" ] && [ -d "${ANDROID_SDK_ROOT}/platform-tools" ]; then + echo "${ANDROID_SDK_ROOT}/platform-tools" >> "$GITHUB_PATH" + fi + script: | + set -euxo pipefail + mkdir -p screenshots + adb install -r artifacts/${{ needs.build-android.outputs.app_apk }} + adb install -r artifacts/${{ needs.build-android.outputs.test_apk }} + adb logcat -c + AAPT_BIN="" + if command -v aapt >/dev/null 2>&1; then + AAPT_BIN="$(command -v aapt)" + elif [ -n "${ANDROID_HOME:-}" ] && [ -d "${ANDROID_HOME}/build-tools" ]; then + AAPT_BIN="$(find "${ANDROID_HOME}/build-tools" -maxdepth 2 -name aapt -type f | sort | tail -n1 || true)" + elif [ -n "${ANDROID_SDK_ROOT:-}" ] && [ -d "${ANDROID_SDK_ROOT}/build-tools" ]; then + AAPT_BIN="$(find "${ANDROID_SDK_ROOT}/build-tools" -maxdepth 2 -name aapt -type f | sort | tail -n1 || true)" + fi + + TEST_PACKAGE="" + INSTRUMENTATION_NAME="" + if [ -n "$AAPT_BIN" ] && [ -x "$AAPT_BIN" ]; then + BADGING_OUTPUT="$($AAPT_BIN dump badging artifacts/${{ needs.build-android.outputs.test_apk }} || true)" + if [ -n "$BADGING_OUTPUT" ]; then + TEST_PACKAGE="$(printf '%s\n' "$BADGING_OUTPUT" | awk -F"'" '/^package: /{print $2; exit}')" + INSTRUMENTATION_NAME="$(printf '%s\n' "$BADGING_OUTPUT" | awk -F"'" '/^instrumentation: /{print $2; exit}')" + fi + fi + + if [ -n "$INSTRUMENTATION_NAME" ]; then + echo "Running instrumentation tests via $INSTRUMENTATION_NAME" + adb shell am instrument -w "$INSTRUMENTATION_NAME" + else + if [ -z "$TEST_PACKAGE" ]; then + TEST_PACKAGE="${{ needs.build-android.outputs.package_name }}.tests" + fi + echo "Instrumentation runner not found, launching $TEST_PACKAGE via monkey" + adb shell monkey -p "$TEST_PACKAGE" 1 + fi + + adb shell monkey -p ${{ needs.build-android.outputs.package_name }} 1 || true + sleep 20 + if [ -f artifacts/tests.txt ]; then + while IFS= read -r testName; do + [ -n "$testName" ] || continue + adb exec-out screencap -p > "screenshots/${testName}.png" + done < artifacts/tests.txt + else + adb exec-out screencap -p > screenshots/test-suite.png + fi + - name: Upload emulator screenshots + uses: actions/upload-artifact@v4 + with: + name: hello-codenameone-test-screenshots + path: screenshots + if-no-files-found: error diff --git a/Samples/SampleProjectTemplate/test/com/codename1/samples/SampleHelloTest.java b/Samples/SampleProjectTemplate/test/com/codename1/samples/SampleHelloTest.java new file mode 100644 index 0000000000..85bcb63f7d --- /dev/null +++ b/Samples/SampleProjectTemplate/test/com/codename1/samples/SampleHelloTest.java @@ -0,0 +1,50 @@ +package com.codename1.samples; + +import com.codename1.testing.AbstractTest; +import com.codename1.ui.Component; +import com.codename1.ui.Display; +import com.codename1.ui.Form; +import com.codename1.ui.Label; + +/** + * A simple Codename One unit test that verifies the "Hi World" label is displayed + * when {@link SampleMain} starts. + */ +public class SampleHelloTest extends AbstractTest { + @Override + public boolean runTest() throws Exception { + SampleMain app = new SampleMain(); + app.init(null); + app.start(); + + Form current = Display.getInstance().getCurrent(); + assertNotNull(current, "The main form should be visible"); + + Label found = findLabelWithText(current, "Hi World"); + assertNotNull(found, "Expected to find the \"Hi World\" label on the form"); + return true; + } + + private Label findLabelWithText(Form form, String expected) { + for (int i = 0; i < form.getContentPane().getComponentCount(); i++) { + Component child = form.getContentPane().getComponentAt(i); + if (child instanceof Label) { + Label label = (Label) child; + if (expected.equals(label.getText())) { + return label; + } + } + } + return null; + } + + @Override + public boolean shouldExecuteOnEDT() { + return true; + } + + @Override + public String toString() { + return "SampleHelloTest"; + } +} diff --git a/scripts/build-android-app.sh b/scripts/build-android-app.sh index f424546247..dfab9a3bb6 100755 --- a/scripts/build-android-app.sh +++ b/scripts/build-android-app.sh @@ -79,6 +79,10 @@ ba_log "Detected Codename One version $CN1_VERSION" WORK_DIR="$TMPDIR/cn1-hello-android" rm -rf "$WORK_DIR"; mkdir -p "$WORK_DIR" +ARTIFACTS_DIR="$WORK_DIR/artifacts" +mkdir -p "$ARTIFACTS_DIR" +TEST_LIST_FILE="$ARTIFACTS_DIR/tests.txt" +> "$TEST_LIST_FILE" GROUP_ID="com.codenameone.examples" ARTIFACT_ID="hello-codenameone" @@ -191,6 +195,25 @@ done < <(find "$APP_DIR" -type f -name pom.xml -print0) # 5) Build with the property set so any lingering refs resolve to the local snapshot EXTRA_MVN_ARGS+=("-Dcodenameone.version=${CN1_VERSION}") +# --- Record discovered unit tests --- +while IFS= read -r -d '' TEST_FILE; do + REL_PATH="${TEST_FILE#$APP_DIR/}" + REL_PATH="${REL_PATH#*/src/test/java/}" + CLASS_NAME="${REL_PATH%.java}" + CLASS_NAME="${CLASS_NAME//\//.}" + if [ -n "$CLASS_NAME" ]; then + echo "$CLASS_NAME" >> "$TEST_LIST_FILE" + fi +done < <(find "$APP_DIR" -path "*/src/test/java/*.java" -print0) + +if [ ! -s "$TEST_LIST_FILE" ]; then + rm -f "$TEST_LIST_FILE" + ba_log "Warning: no unit test sources were discovered" +else + ba_log "Recorded unit test classes:" + sed 's/^/[build-android-app] /' "$TEST_LIST_FILE" +fi + # (Optional) quick non-fatal checks xmlstarlet sel -N "$NS" -t -v "/mvn:project/mvn:properties/mvn:codenameone.version" -n "$ROOT_POM" || true xmlstarlet sel -N "$NS" -t -c "/mvn:project/mvn:build/mvn:plugins" -n "$ROOT_POM" | head -n 60 || true @@ -282,4 +305,59 @@ export JAVA_HOME="$ORIGINAL_JAVA_HOME" APK_PATH=$(find "$GRADLE_PROJECT_DIR" -path "*/outputs/apk/debug/*.apk" | head -n 1 || true) [ -n "$APK_PATH" ] || { ba_log "Gradle build completed but no APK was found" >&2; exit 1; } -ba_log "Successfully built Android APK at $APK_PATH" \ No newline at end of file +FINAL_APP_APK="$ARTIFACTS_DIR/${ARTIFACT_ID}-debug.apk" +cp "$APK_PATH" "$FINAL_APP_APK" +ba_log "Successfully built Android APK at $APK_PATH" +ba_log "Copied Android APK to $FINAL_APP_APK" + +ba_log "Building Android unit test APK" +rm -rf "$APP_DIR/android/target" +xvfb-run -a "${MAVEN_CMD[@]}" -q -f "$APP_DIR/pom.xml" package \ + -DskipTests \ + -Dcodename1.platform=android \ + -Dcodename1.buildTarget=android-source \ + -Dcodename1.arg.build.unitTest=1 \ + -Dopen=false \ + "${EXTRA_MVN_ARGS[@]}" + +GRADLE_PROJECT_DIR=$(find "$APP_DIR/android/target" -maxdepth 2 -type d -name "*-android-source" | head -n 1 || true) +[ -n "$GRADLE_PROJECT_DIR" ] || { ba_log "Failed to locate generated Android project for unit tests" >&2; exit 1; } + +ba_log "Invoking Gradle build for unit test project in $GRADLE_PROJECT_DIR" +chmod +x "$GRADLE_PROJECT_DIR/gradlew" +ORIGINAL_JAVA_HOME="$JAVA_HOME" +export JAVA_HOME="$JAVA17_HOME" +( + cd "$GRADLE_PROJECT_DIR" + if command -v sdkmanager >/dev/null 2>&1; then + yes | sdkmanager --licenses >/dev/null 2>&1 || true + elif [ -x "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" ]; then + yes | "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" --licenses >/dev/null 2>&1 || true + fi + ./gradlew --no-daemon assembleDebug +) +export JAVA_HOME="$ORIGINAL_JAVA_HOME" + +UNIT_TEST_APK_PATH=$(find "$GRADLE_PROJECT_DIR" -path "*/outputs/apk/debug/*.apk" | head -n 1 || true) +[ -n "$UNIT_TEST_APK_PATH" ] || { ba_log "Gradle unit test build completed but no APK was found" >&2; exit 1; } +FINAL_TEST_APK="$ARTIFACTS_DIR/${ARTIFACT_ID}-tests-debug.apk" +cp "$UNIT_TEST_APK_PATH" "$FINAL_TEST_APK" +ba_log "Successfully built Android unit test APK at $UNIT_TEST_APK_PATH" +ba_log "Copied Android unit test APK to $FINAL_TEST_APK" + +TESTS_METADATA=$(find "$APP_DIR" -name tests.dat | head -n 1 || true) +if [ -n "$TESTS_METADATA" ]; then + cp "$TESTS_METADATA" "$ARTIFACTS_DIR/tests.dat" + ba_log "Copied test metadata to $ARTIFACTS_DIR/tests.dat" +else + ba_log "Warning: tests.dat metadata file not found" +fi + +if [ -n "${GITHUB_OUTPUT:-}" ]; then + { + echo "artifact_dir=$ARTIFACTS_DIR" + echo "app_apk=$(basename "$FINAL_APP_APK")" + echo "test_apk=$(basename "$FINAL_TEST_APK")" + echo "package_name=$PACKAGE_NAME" + } >> "$GITHUB_OUTPUT" +fi From d5d99a1da37f56908c2086064ecfa86d6daed632 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 07:28:41 +0300 Subject: [PATCH 02/14] Allow installing test APKs in CI --- .github/workflows/scripts-android.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index a6fbed7f54..d3cc8eaac0 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -68,7 +68,7 @@ jobs: set -euxo pipefail mkdir -p screenshots adb install -r artifacts/${{ needs.build-android.outputs.app_apk }} - adb install -r artifacts/${{ needs.build-android.outputs.test_apk }} + adb install -r -t artifacts/${{ needs.build-android.outputs.test_apk }} adb logcat -c AAPT_BIN="" if command -v aapt >/dev/null 2>&1; then From 9b687b786ea8803c4a381f884e6fb49802cfcdc5 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 07:58:48 +0300 Subject: [PATCH 03/14] Ensure adb available before emulator workflow --- .github/workflows/scripts-android.yml | 38 +++++++++++++++++---------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index d3cc8eaac0..fcfb7a0b50 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -40,6 +40,26 @@ jobs: needs: build-android runs-on: ubuntu-22.04-arm steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Android SDK + uses: android-actions/setup-android@v3 + + - name: Ensure platform-tools available on PATH + shell: bash + run: | + set -euxo pipefail + yes | sdkmanager --install "platform-tools" >/dev/null + if [ -n "${ANDROID_HOME:-}" ] && [ -d "${ANDROID_HOME}/platform-tools" ]; then + echo "${ANDROID_HOME}/platform-tools" >> "$GITHUB_PATH" + fi + if [ -n "${ANDROID_SDK_ROOT:-}" ] && [ -d "${ANDROID_SDK_ROOT}/platform-tools" ]; then + echo "${ANDROID_SDK_ROOT}/platform-tools" >> "$GITHUB_PATH" + fi + command -v adb + adb version + - name: Download APK artifacts uses: actions/download-artifact@v4 with: @@ -53,22 +73,12 @@ jobs: profile: pixel_6 pre-emulator-launch-script: | set -euxo pipefail - if command -v sdkmanager >/dev/null 2>&1; then - yes | sdkmanager --install "platform-tools" >/dev/null - else - echo "sdkmanager executable is required for installing platform-tools" >&2 - exit 1 - fi - if [ -n "${ANDROID_HOME:-}" ] && [ -d "${ANDROID_HOME}/platform-tools" ]; then - echo "${ANDROID_HOME}/platform-tools" >> "$GITHUB_PATH" - elif [ -n "${ANDROID_SDK_ROOT:-}" ] && [ -d "${ANDROID_SDK_ROOT}/platform-tools" ]; then - echo "${ANDROID_SDK_ROOT}/platform-tools" >> "$GITHUB_PATH" - fi + adb version script: | set -euxo pipefail mkdir -p screenshots - adb install -r artifacts/${{ needs.build-android.outputs.app_apk }} - adb install -r -t artifacts/${{ needs.build-android.outputs.test_apk }} + adb install -r "artifacts/${{ needs.build-android.outputs.app_apk }}" + adb install -r -t "artifacts/${{ needs.build-android.outputs.test_apk }}" adb logcat -c AAPT_BIN="" if command -v aapt >/dev/null 2>&1; then @@ -100,7 +110,7 @@ jobs: adb shell monkey -p "$TEST_PACKAGE" 1 fi - adb shell monkey -p ${{ needs.build-android.outputs.package_name }} 1 || true + adb shell monkey -p "${{ needs.build-android.outputs.package_name }}" 1 || true sleep 20 if [ -f artifacts/tests.txt ]; then while IFS= read -r testName; do From db838981e9dbea4eeef1aed1e84cf7dffc9185f2 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 08:49:36 +0300 Subject: [PATCH 04/14] Install JDK 17 before android device tests --- .github/workflows/scripts-android.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index fcfb7a0b50..e68e05211c 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -43,6 +43,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '17' + - name: Install Android SDK uses: android-actions/setup-android@v3 From 7c528f640ee1fe446be5b60dd68ac2daeb91ed26 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 09:14:26 +0300 Subject: [PATCH 05/14] Avoid interactive license prompts in android emulator job --- .github/workflows/scripts-android.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index e68e05211c..d0667e75ba 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -51,12 +51,16 @@ jobs: - name: Install Android SDK uses: android-actions/setup-android@v3 + with: + accept-android-sdk-licenses: false + packages: '' - - name: Ensure platform-tools available on PATH + - name: Ensure Android tools available on PATH shell: bash run: | set -euxo pipefail - yes | sdkmanager --install "platform-tools" >/dev/null + yes | sdkmanager --install "platform-tools" "build-tools;34.0.0" >/dev/null + yes | sdkmanager --licenses >/dev/null if [ -n "${ANDROID_HOME:-}" ] && [ -d "${ANDROID_HOME}/platform-tools" ]; then echo "${ANDROID_HOME}/platform-tools" >> "$GITHUB_PATH" fi From 1e119ef05cc73d6904f1431b2471ced899c8389c Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 09:30:02 +0300 Subject: [PATCH 06/14] Fix sdkmanager license acceptance in emulator job --- .github/workflows/scripts-android.yml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index d0667e75ba..59b8ee440f 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -59,8 +59,24 @@ jobs: shell: bash run: | set -euxo pipefail - yes | sdkmanager --install "platform-tools" "build-tools;34.0.0" >/dev/null - yes | sdkmanager --licenses >/dev/null + if ! command -v sdkmanager >/dev/null 2>&1; then + echo "sdkmanager executable is required" >&2 + exit 1 + fi + + SDKMANAGER="$(command -v sdkmanager)" + + run_sdk() { + set +o pipefail + yes | "$SDKMANAGER" "$@" >/dev/null 2>&1 + local rc=${PIPESTATUS[1]} + set -o pipefail + return $rc + } + + run_sdk --licenses + run_sdk --install "platform-tools" "build-tools;34.0.0" + run_sdk --install "platforms;android-33" || echo "Warning: failed to install Android 33 platform" >&2 if [ -n "${ANDROID_HOME:-}" ] && [ -d "${ANDROID_HOME}/platform-tools" ]; then echo "${ANDROID_HOME}/platform-tools" >> "$GITHUB_PATH" fi From 7c0309e2391821addf98c77b5c1cd0d6dfc890af Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 09:45:49 +0300 Subject: [PATCH 07/14] Use native adb on ARM runners and auto-detect instrumentation --- .github/workflows/scripts-android.yml | 52 ++++++--------------------- 1 file changed, 11 insertions(+), 41 deletions(-) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index 59b8ee440f..d3971c93f1 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -55,34 +55,12 @@ jobs: accept-android-sdk-licenses: false packages: '' - - name: Ensure Android tools available on PATH + - name: Install adb for ARM environment shell: bash run: | set -euxo pipefail - if ! command -v sdkmanager >/dev/null 2>&1; then - echo "sdkmanager executable is required" >&2 - exit 1 - fi - - SDKMANAGER="$(command -v sdkmanager)" - - run_sdk() { - set +o pipefail - yes | "$SDKMANAGER" "$@" >/dev/null 2>&1 - local rc=${PIPESTATUS[1]} - set -o pipefail - return $rc - } - - run_sdk --licenses - run_sdk --install "platform-tools" "build-tools;34.0.0" - run_sdk --install "platforms;android-33" || echo "Warning: failed to install Android 33 platform" >&2 - if [ -n "${ANDROID_HOME:-}" ] && [ -d "${ANDROID_HOME}/platform-tools" ]; then - echo "${ANDROID_HOME}/platform-tools" >> "$GITHUB_PATH" - fi - if [ -n "${ANDROID_SDK_ROOT:-}" ] && [ -d "${ANDROID_SDK_ROOT}/platform-tools" ]; then - echo "${ANDROID_SDK_ROOT}/platform-tools" >> "$GITHUB_PATH" - fi + sudo apt-get update -y + sudo apt-get install -y adb command -v adb adb version @@ -106,23 +84,15 @@ jobs: adb install -r "artifacts/${{ needs.build-android.outputs.app_apk }}" adb install -r -t "artifacts/${{ needs.build-android.outputs.test_apk }}" adb logcat -c - AAPT_BIN="" - if command -v aapt >/dev/null 2>&1; then - AAPT_BIN="$(command -v aapt)" - elif [ -n "${ANDROID_HOME:-}" ] && [ -d "${ANDROID_HOME}/build-tools" ]; then - AAPT_BIN="$(find "${ANDROID_HOME}/build-tools" -maxdepth 2 -name aapt -type f | sort | tail -n1 || true)" - elif [ -n "${ANDROID_SDK_ROOT:-}" ] && [ -d "${ANDROID_SDK_ROOT}/build-tools" ]; then - AAPT_BIN="$(find "${ANDROID_SDK_ROOT}/build-tools" -maxdepth 2 -name aapt -type f | sort | tail -n1 || true)" - fi - + PACKAGE_NAME="${{ needs.build-android.outputs.package_name }}" TEST_PACKAGE="" INSTRUMENTATION_NAME="" - if [ -n "$AAPT_BIN" ] && [ -x "$AAPT_BIN" ]; then - BADGING_OUTPUT="$($AAPT_BIN dump badging artifacts/${{ needs.build-android.outputs.test_apk }} || true)" - if [ -n "$BADGING_OUTPUT" ]; then - TEST_PACKAGE="$(printf '%s\n' "$BADGING_OUTPUT" | awk -F"'" '/^package: /{print $2; exit}')" - INSTRUMENTATION_NAME="$(printf '%s\n' "$BADGING_OUTPUT" | awk -F"'" '/^instrumentation: /{print $2; exit}')" - fi + + INSTRUMENTATION_LINE="$(adb shell cmd package list instrumentation | tr -d '\r' | grep "target=${PACKAGE_NAME})" || true)" + if [ -n "$INSTRUMENTATION_LINE" ]; then + INSTRUMENTATION_NAME="${INSTRUMENTATION_LINE#instrumentation:}" + INSTRUMENTATION_NAME="${INSTRUMENTATION_NAME%% (*}" + TEST_PACKAGE="${INSTRUMENTATION_NAME%%/*}" fi if [ -n "$INSTRUMENTATION_NAME" ]; then @@ -130,7 +100,7 @@ jobs: adb shell am instrument -w "$INSTRUMENTATION_NAME" else if [ -z "$TEST_PACKAGE" ]; then - TEST_PACKAGE="${{ needs.build-android.outputs.package_name }}.tests" + TEST_PACKAGE="${PACKAGE_NAME}.tests" fi echo "Instrumentation runner not found, launching $TEST_PACKAGE via monkey" adb shell monkey -p "$TEST_PACKAGE" 1 From 2824606c3abe6d09453e1976116677cdf1498622 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 10:59:03 +0300 Subject: [PATCH 08/14] Run Android device tests on macOS HVF emulator --- .github/workflows/scripts-android.yml | 38 ++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index d3971c93f1..d33ddbcd06 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -38,7 +38,7 @@ jobs: android-device-tests: needs: build-android - runs-on: ubuntu-22.04-arm + runs-on: macos-14 steps: - name: Checkout repository uses: actions/checkout@v4 @@ -55,12 +55,36 @@ jobs: accept-android-sdk-licenses: false packages: '' - - name: Install adb for ARM environment + - name: Install Android platform tools shell: bash run: | set -euxo pipefail - sudo apt-get update -y - sudo apt-get install -y adb + if ! command -v sdkmanager >/dev/null 2>&1; then + echo "sdkmanager executable is required" >&2 + exit 1 + fi + + SDKMANAGER="$(command -v sdkmanager)" + + run_sdk() { + set +o pipefail + yes | "$SDKMANAGER" "$@" >/dev/null 2>&1 + local rc=${PIPESTATUS[1]} + set -o pipefail + return $rc + } + + run_sdk --licenses + run_sdk --install "platform-tools" "build-tools;34.0.0" + run_sdk --install "platforms;android-33" || echo "Warning: failed to install Android 33 platform" >&2 + + if [ -n "${ANDROID_HOME:-}" ] && [ -d "${ANDROID_HOME}/platform-tools" ]; then + echo "${ANDROID_HOME}/platform-tools" >> "$GITHUB_PATH" + fi + if [ -n "${ANDROID_SDK_ROOT:-}" ] && [ -d "${ANDROID_SDK_ROOT}/platform-tools" ]; then + echo "${ANDROID_SDK_ROOT}/platform-tools" >> "$GITHUB_PATH" + fi + command -v adb adb version @@ -116,6 +140,12 @@ jobs: else adb exec-out screencap -p > screenshots/test-suite.png fi + target: default + cores: 2 + avd-name: test + force-avd-creation: true + emulator-boot-timeout: 600 + emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -accel hvf - name: Upload emulator screenshots uses: actions/upload-artifact@v4 with: From 8ab9866cee9b3e063e374eddc6a88df0ac50eb15 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 11:54:55 +0300 Subject: [PATCH 09/14] Fix macOS arm emulator toolchain --- .github/workflows/scripts-android.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index d33ddbcd06..0859c530b3 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -68,8 +68,14 @@ jobs: run_sdk() { set +o pipefail - yes | "$SDKMANAGER" "$@" >/dev/null 2>&1 - local rc=${PIPESTATUS[1]} + local rc + if arch -arm64 true 2>/dev/null; then + yes | arch -arm64 "$SDKMANAGER" "$@" >/dev/null 2>&1 + rc=${PIPESTATUS[2]} + else + yes | "$SDKMANAGER" "$@" >/dev/null 2>&1 + rc=${PIPESTATUS[1]} + fi set -o pipefail return $rc } @@ -145,7 +151,7 @@ jobs: avd-name: test force-avd-creation: true emulator-boot-timeout: 600 - emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -accel hvf + emulator-options: -no-window -gpu host -no-snapshot -noaudio -no-boot-anim -feature HVF -accel hvf - name: Upload emulator screenshots uses: actions/upload-artifact@v4 with: From 60f9df2fb598cd1408ff2623ba40f1171fe7d7bd Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 12:11:24 +0300 Subject: [PATCH 10/14] Simplify macOS Android SDK setup --- .github/workflows/scripts-android.yml | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index 0859c530b3..5fc2fc828d 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -58,31 +58,14 @@ jobs: - name: Install Android platform tools shell: bash run: | - set -euxo pipefail + set -eux if ! command -v sdkmanager >/dev/null 2>&1; then echo "sdkmanager executable is required" >&2 exit 1 fi - SDKMANAGER="$(command -v sdkmanager)" - - run_sdk() { - set +o pipefail - local rc - if arch -arm64 true 2>/dev/null; then - yes | arch -arm64 "$SDKMANAGER" "$@" >/dev/null 2>&1 - rc=${PIPESTATUS[2]} - else - yes | "$SDKMANAGER" "$@" >/dev/null 2>&1 - rc=${PIPESTATUS[1]} - fi - set -o pipefail - return $rc - } - - run_sdk --licenses - run_sdk --install "platform-tools" "build-tools;34.0.0" - run_sdk --install "platforms;android-33" || echo "Warning: failed to install Android 33 platform" >&2 + yes 2>/dev/null | sdkmanager --licenses >/dev/null + yes 2>/dev/null | sdkmanager --install "platform-tools" "build-tools;34.0.0" "platforms;android-33" >/dev/null if [ -n "${ANDROID_HOME:-}" ] && [ -d "${ANDROID_HOME}/platform-tools" ]; then echo "${ANDROID_HOME}/platform-tools" >> "$GITHUB_PATH" From b99a0c2190eebf86c1dbc4f2092767ff69e4eb64 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 12:27:55 +0300 Subject: [PATCH 11/14] Simplify macOS SDK setup --- .github/workflows/scripts-android.yml | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index 5fc2fc828d..d1358974b0 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -52,28 +52,15 @@ jobs: - name: Install Android SDK uses: android-actions/setup-android@v3 with: - accept-android-sdk-licenses: false - packages: '' + accept-android-sdk-licenses: true + packages: | + platform-tools + build-tools;34.0.0 + platforms;android-33 - - name: Install Android platform tools - shell: bash + - name: Verify platform tools run: | - set -eux - if ! command -v sdkmanager >/dev/null 2>&1; then - echo "sdkmanager executable is required" >&2 - exit 1 - fi - - yes 2>/dev/null | sdkmanager --licenses >/dev/null - yes 2>/dev/null | sdkmanager --install "platform-tools" "build-tools;34.0.0" "platforms;android-33" >/dev/null - - if [ -n "${ANDROID_HOME:-}" ] && [ -d "${ANDROID_HOME}/platform-tools" ]; then - echo "${ANDROID_HOME}/platform-tools" >> "$GITHUB_PATH" - fi - if [ -n "${ANDROID_SDK_ROOT:-}" ] && [ -d "${ANDROID_SDK_ROOT}/platform-tools" ]; then - echo "${ANDROID_SDK_ROOT}/platform-tools" >> "$GITHUB_PATH" - fi - + set -euxo pipefail command -v adb adb version From 4b8206fcbaa48941c4b7602de277383c343abee5 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 13:18:08 +0300 Subject: [PATCH 12/14] Adjust macOS Android SDK installation --- .github/workflows/scripts-android.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index d1358974b0..a2b0114e37 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -49,18 +49,18 @@ jobs: distribution: temurin java-version: '17' - - name: Install Android SDK + - name: Install Android SDK tools uses: android-actions/setup-android@v3 - with: - accept-android-sdk-licenses: true - packages: | - platform-tools - build-tools;34.0.0 - platforms;android-33 + + - name: Install required Android packages + run: | + set -eux + yes 2>/dev/null | sdkmanager --licenses >/dev/null + yes 2>/dev/null | sdkmanager --install "platform-tools" "build-tools;34.0.0" "platforms;android-33" >/dev/null - name: Verify platform tools run: | - set -euxo pipefail + set -eux command -v adb adb version From 886158cfc88d547729f79731dd9d9dc9f1b6a4f4 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 13:44:55 +0300 Subject: [PATCH 13/14] Adjust macOS emulator provisioning --- .github/workflows/scripts-android.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index a2b0114e37..2fe2af8dbe 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -56,7 +56,7 @@ jobs: run: | set -eux yes 2>/dev/null | sdkmanager --licenses >/dev/null - yes 2>/dev/null | sdkmanager --install "platform-tools" "build-tools;34.0.0" "platforms;android-33" >/dev/null + yes 2>/dev/null | sdkmanager --install "platform-tools" "build-tools;34.0.0" "platforms;android-33" "emulator" >/dev/null - name: Verify platform tools run: | @@ -116,12 +116,12 @@ jobs: else adb exec-out screencap -p > screenshots/test-suite.png fi - target: default + target: google_apis cores: 2 avd-name: test force-avd-creation: true emulator-boot-timeout: 600 - emulator-options: -no-window -gpu host -no-snapshot -noaudio -no-boot-anim -feature HVF -accel hvf + emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim - name: Upload emulator screenshots uses: actions/upload-artifact@v4 with: From 2b16eb949fdfbf3ab6db9df161367fa7ff3ab2f3 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 12 Oct 2025 14:20:32 +0300 Subject: [PATCH 14/14] Simplify macOS device test SDK setup --- .github/workflows/scripts-android.yml | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index 2fe2af8dbe..35e4104c34 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -43,27 +43,6 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: '17' - - - name: Install Android SDK tools - uses: android-actions/setup-android@v3 - - - name: Install required Android packages - run: | - set -eux - yes 2>/dev/null | sdkmanager --licenses >/dev/null - yes 2>/dev/null | sdkmanager --install "platform-tools" "build-tools;34.0.0" "platforms;android-33" "emulator" >/dev/null - - - name: Verify platform tools - run: | - set -eux - command -v adb - adb version - - name: Download APK artifacts uses: actions/download-artifact@v4 with: @@ -77,6 +56,7 @@ jobs: profile: pixel_6 pre-emulator-launch-script: | set -euxo pipefail + adb kill-server || true adb version script: | set -euxo pipefail @@ -121,7 +101,7 @@ jobs: avd-name: test force-avd-creation: true emulator-boot-timeout: 600 - emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim + emulator-options: -no-window -no-snapshot -noaudio -no-boot-anim - name: Upload emulator screenshots uses: actions/upload-artifact@v4 with: