From 9ab5614e8ea060db67f3f30b2e6715709b163b2a Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 11 Jan 2026 15:41:26 -0500 Subject: [PATCH 1/8] Wait briefly before starting to poll the emulator in android-emulator-tests.sh --- .github/workflows/scripts/android/android-emulator-tests.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/scripts/android/android-emulator-tests.sh b/.github/workflows/scripts/android/android-emulator-tests.sh index b346b0f..f15de8f 100755 --- a/.github/workflows/scripts/android/android-emulator-tests.sh +++ b/.github/workflows/scripts/android/android-emulator-tests.sh @@ -95,6 +95,9 @@ log "Starting Android emulator" # launch the emulator in the background nohup emulator -no-metrics -partition-size 1024 -memory 4096 -wipe-data -no-window -no-snapshot -noaudio -no-boot-anim -avd "${ANDROID_EMULATOR_NAME}" & +# wait briefly before starting to poll the emulator +sleep 20 + log "Waiting for Android emulator startup" timeout "${ANDROID_EMULATOR_TIMEOUT}" adb wait-for-any-device From eb3dac9ed97ba4e4b120871c9eefdb5c9caf2ae8 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Wed, 14 Jan 2026 17:07:10 -0500 Subject: [PATCH 2/8] Poll emulator with adb shell getprop sys.boot_completed and manually handle timeout --- .github/workflows/android_sdk.yml | 174 ++++++++++++++++++ .../scripts/android/android-emulator-tests.sh | 23 ++- 2 files changed, 194 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/android_sdk.yml diff --git a/.github/workflows/android_sdk.yml b/.github/workflows/android_sdk.yml new file mode 100644 index 0000000..ac1df75 --- /dev/null +++ b/.github/workflows/android_sdk.yml @@ -0,0 +1,174 @@ +# This workflow can be added to a branch of swift-docker +# in order to test building the chages in a fork: +# +# ln ../android_sdk.yml .github/workflows/android_sdk.yml +# +# Note that the workflow should be removed before filing a PR +# so it is not submitted to the upstream swiftlang/swift-docker repo +name: Build Android SDK +on: [push, pull_request] + +jobs: + build: + name: Android ${{ matrix.build-type }} ${{ matrix.swift-version }} ${{ matrix.arch }} ${{ matrix.runner }} (compiler=${{ matrix.build-compiler }}) + strategy: + fail-fast: false + matrix: + include: + - runner: 'ubuntu-24.04' + swift-version: 'scheme:main' + build-type: 'docker' + - runner: 'ubuntu-24.04' + swift-version: 'scheme:release/6.2' + build-type: 'docker' + - runner: 'ubuntu-24.04' + swift-version: 'tag:swift-6.2.3-RELEASE' + build-type: 'docker' + - runner: 'ubuntu-24.04' + swift-version: 'tag:swift-6.3-DEVELOPMENT-SNAPSHOT-2025-12-24-a' + build-type: 'docker' + runs-on: ${{ matrix.runner }} + # 16 hour timeout + timeout-minutes: 960 + steps: + - name: Free Disk Space + if: ${{ matrix.runner != 'self-hosted' }} + run: | + df -h + # brings available space from 25G to 32G + # otherwise we sometimes run out of space during the build + sudo rm -rf /opt/microsoft /opt/google /opt/az /usr/share/miniconda /usr/share/az* /usr/share/glade* /usr/local/share/chromium /usr/local/share/powershell /usr/share/dotnet /opt/ghc /opt/hostedtoolcache /usr/local/graalvm/ /usr/local/.ghcup/ /usr/local/lib/node_modules /usr/local/share/boost + sudo docker image prune --all --force + sudo docker builder prune -a + df -h + - name: Setup + id: config + run: | + # these variabes are used by build-docker and build-local + # to determine which Swift version to build for + echo "SWIFT_VERSION=${{ matrix.swift-version }}" >> $GITHUB_ENV + # pass the build-compiler matrix through to the build script + echo "BUILD_COMPILER=${{ matrix.build-compiler }}" >> $GITHUB_ENV + echo "TARGET_ARCHS=${{ matrix.arch }}" >> $GITHUB_ENV + echo "WORKDIR=${{ runner.temp }}/swift-android-sdk" >> $GITHUB_ENV + - name: Checkout repository + uses: actions/checkout@v4 + - name: Build Android SDK (Local) + if: ${{ matrix.build-type == 'local' }} + working-directory: swift-ci/sdks/android + run: | + sudo apt install -q patchelf build-essential cmake ninja-build python3 golang git gnupg2 libcurl4-openssl-dev libedit-dev libicu-dev libncurses5-dev libpython3-dev libsqlite3-dev libxml2-dev rsync uuid-dev uuid-runtime tzdata curl unzip + ./build-local ${SWIFT_VERSION} ${WORKDIR} + - name: Build Android SDK (Docker) + if: ${{ matrix.build-type == 'docker' }} + working-directory: swift-ci/sdks/android + run: | + ./build-docker ${SWIFT_VERSION} ${WORKDIR} + - name: Install Host Toolchain + if: ${{ matrix.build-type == 'docker' }} + working-directory: swift-ci/sdks/android + run: | + # when building in a Docker container, we don't have a local host toolchain, + # but we need one in order to run the SDK validation tests, so we install it now + HOST_OS=ubuntu$(lsb_release -sr) + source ./scripts/toolchain-vars.sh + mkdir -p ${WORKDIR}/host-toolchain + ./scripts/install-swift.sh ${WORKDIR}/host-toolchain/$SWIFT_BASE/usr + ls ${WORKDIR}/host-toolchain + ${WORKDIR}/host-toolchain/*/usr/bin/swift --version + - name: Get artifact info + id: info + shell: bash + run: | + set -ex + SWIFT_ROOT=$(dirname ${WORKDIR}/host-toolchain/*/usr) + echo "swift-root=${SWIFT_ROOT}" >> $GITHUB_OUTPUT + echo "swift-path=${SWIFT_ROOT}/usr/bin/swift" >> $GITHUB_OUTPUT + + ARTIFACT_PATH=$(realpath ${WORKDIR}/products/*.artifactbundle.tar.gz) + echo "artifact-path=${ARTIFACT_PATH}" >> $GITHUB_OUTPUT + echo "sdk-id=x86_64-unknown-linux-android28" >> $GITHUB_OUTPUT + + ARTIFACT_EXT=".artifactbundle.tar.gz" + ARTIFACT_NAME="$(basename ${ARTIFACT_PATH} ${ARTIFACT_EXT})" + # depending on whether we are building locally or in a container, add a maker to the name + if [[ "${{ matrix.build-type }}" == 'local' ]]; then + ARTIFACT_NAME="${ARTIFACT_NAME}-local" + fi + if [[ "${{ matrix.build-compiler }}" == '1' ]]; then + ARTIFACT_NAME="${ARTIFACT_NAME}-hostbuild" + fi + # artifacts need a unique name so we suffix with the matrix arch(s) + if [[ ! -z "${{ matrix.arch }}" ]]; then + ARTIFACT_NAME="${ARTIFACT_NAME}-$(echo ${{ matrix.arch }} | tr ',' '-')" + fi + ARTIFACT_NAME="${ARTIFACT_NAME}${ARTIFACT_EXT}" + + # There is no way to prevent even a single-file artifact from being zipped: + # https://github.com/actions/upload-artifact?tab=readme-ov-file#zip-archives + # so the actual artifact download will look like: + # swift-6.1-RELEASE_android-0.1-x86_64.artifactbundle.tar.gz.zip + echo "artifact-name=${ARTIFACT_NAME}" >> $GITHUB_OUTPUT + - name: Upload SDK artifactbundle + uses: actions/upload-artifact@v4 + with: + compression-level: 0 + name: ${{ steps.info.outputs.artifact-name }} + path: ${{ steps.info.outputs.artifact-path }} + - name: Cleanup + if: ${{ matrix.runner != 'self-hosted' }} + run: | + # need to free up some space or else when installing we get: No space left on device + df -h + rm -rf ${WORKDIR}/{build,source} + sudo docker image prune --all --force + sudo docker builder prune -a + df -h + - name: Install artifactbundle + if: ${{ matrix.runner != 'self-hosted' }} + shell: bash + run: | + set -ex + ${{ steps.info.outputs.swift-path }} sdk install ${{ steps.info.outputs.artifact-path }} + ${{ steps.info.outputs.swift-path }} sdk configure --show-configuration $(${{ steps.info.outputs.swift-path }} sdk list | head -n 1) ${{ steps.info.outputs.sdk-id }} + # recent releases require that ANDROID_NDK_ROOT *not* be set + # see https://github.com/swiftlang/swift-driver/pull/1879 + echo "ANDROID_NDK_ROOT=" >> $GITHUB_ENV + + - name: Create Demo Project + if: ${{ matrix.runner != 'self-hosted' }} + run: | + cd ${{ runner.temp }} + mkdir DemoProject + cd DemoProject + ${{ steps.info.outputs.swift-path }} --version + ${{ steps.info.outputs.swift-path }} package init + echo 'import Foundation' >> Sources/DemoProject/DemoProject.swift + echo 'import FoundationEssentials' >> Sources/DemoProject/DemoProject.swift + echo 'import FoundationXML' >> Sources/DemoProject/DemoProject.swift + echo 'import FoundationNetworking' >> Sources/DemoProject/DemoProject.swift + echo 'import Dispatch' >> Sources/DemoProject/DemoProject.swift + echo 'import Android' >> Sources/DemoProject/DemoProject.swift + - name: Test Demo Project on Android + uses: skiptools/swift-android-action@main + if: ${{ matrix.runner != 'self-hosted' }} + with: + # only test for the complete arch SDK build to speed up CI + #run-tests: ${{ matrix.arch == '' }} + package-path: ${{ runner.temp }}/DemoProject + installed-sdk: ${{ steps.info.outputs.sdk-id }} + installed-swift: ${{ steps.info.outputs.swift-root }} + + - name: Checkout swift-algorithms + if: ${{ matrix.runner != 'self-hosted' }} + uses: actions/checkout@v4 + with: + repository: apple/swift-algorithms + path: swift-algorithms + - name: Test swift-algorithms + if: ${{ matrix.runner != 'self-hosted' }} + uses: skiptools/swift-android-action@main + with: + package-path: swift-algorithms + installed-sdk: ${{ steps.info.outputs.sdk-id }} + installed-swift: ${{ steps.info.outputs.swift-root }} diff --git a/.github/workflows/scripts/android/android-emulator-tests.sh b/.github/workflows/scripts/android/android-emulator-tests.sh index 0754837..feef7d8 100755 --- a/.github/workflows/scripts/android/android-emulator-tests.sh +++ b/.github/workflows/scripts/android/android-emulator-tests.sh @@ -99,9 +99,26 @@ nohup emulator -no-metrics -partition-size 1024 -memory 4096 -wipe-data -no-wind sleep 20 log "Waiting for Android emulator startup" -adb start-server -sleep 5 -timeout "${ANDROID_EMULATOR_TIMEOUT}" adb wait-for-any-device +EMULATOR_CHECK_SECONDS_ELAPSED=0 +EMULATOR_CHECK_INTERVAL=5 # Seconds between status checks +while true; do + # Check if the boot is completed + # 'adb shell getprop sys.boot_completed' returns 1 when done + BOOT_STATUS=$(adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r') + + if [ "$BOOT_STATUS" == "1" ]; then + log "Emulator is ready" + break; + fi + + if [ "$EMULATOR_CHECK_SECONDS_ELAPSED" -ge "$ANDROID_EMULATOR_TIMEOUT" ]; then + log "Timeout reached ($ANDROID_EMULATOR_TIMEOUT seconds). Aborting." + exit 1 + fi + + sleep "$EMULATOR_CHECK_INTERVAL" + ((EMULATOR_CHECK_SECONDS_ELAPSED+=EMULATOR_CHECK_INTERVAL)) +done log "Prepare Swift test package" # create a staging folder where we copy the test executable From 6c0dc593f6f1284a9d1a3c10a75ddb906ddeace8 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Wed, 14 Jan 2026 17:09:44 -0500 Subject: [PATCH 3/8] Remove unused workflow --- .github/workflows/android_sdk.yml | 174 ------------------------------ 1 file changed, 174 deletions(-) delete mode 100644 .github/workflows/android_sdk.yml diff --git a/.github/workflows/android_sdk.yml b/.github/workflows/android_sdk.yml deleted file mode 100644 index ac1df75..0000000 --- a/.github/workflows/android_sdk.yml +++ /dev/null @@ -1,174 +0,0 @@ -# This workflow can be added to a branch of swift-docker -# in order to test building the chages in a fork: -# -# ln ../android_sdk.yml .github/workflows/android_sdk.yml -# -# Note that the workflow should be removed before filing a PR -# so it is not submitted to the upstream swiftlang/swift-docker repo -name: Build Android SDK -on: [push, pull_request] - -jobs: - build: - name: Android ${{ matrix.build-type }} ${{ matrix.swift-version }} ${{ matrix.arch }} ${{ matrix.runner }} (compiler=${{ matrix.build-compiler }}) - strategy: - fail-fast: false - matrix: - include: - - runner: 'ubuntu-24.04' - swift-version: 'scheme:main' - build-type: 'docker' - - runner: 'ubuntu-24.04' - swift-version: 'scheme:release/6.2' - build-type: 'docker' - - runner: 'ubuntu-24.04' - swift-version: 'tag:swift-6.2.3-RELEASE' - build-type: 'docker' - - runner: 'ubuntu-24.04' - swift-version: 'tag:swift-6.3-DEVELOPMENT-SNAPSHOT-2025-12-24-a' - build-type: 'docker' - runs-on: ${{ matrix.runner }} - # 16 hour timeout - timeout-minutes: 960 - steps: - - name: Free Disk Space - if: ${{ matrix.runner != 'self-hosted' }} - run: | - df -h - # brings available space from 25G to 32G - # otherwise we sometimes run out of space during the build - sudo rm -rf /opt/microsoft /opt/google /opt/az /usr/share/miniconda /usr/share/az* /usr/share/glade* /usr/local/share/chromium /usr/local/share/powershell /usr/share/dotnet /opt/ghc /opt/hostedtoolcache /usr/local/graalvm/ /usr/local/.ghcup/ /usr/local/lib/node_modules /usr/local/share/boost - sudo docker image prune --all --force - sudo docker builder prune -a - df -h - - name: Setup - id: config - run: | - # these variabes are used by build-docker and build-local - # to determine which Swift version to build for - echo "SWIFT_VERSION=${{ matrix.swift-version }}" >> $GITHUB_ENV - # pass the build-compiler matrix through to the build script - echo "BUILD_COMPILER=${{ matrix.build-compiler }}" >> $GITHUB_ENV - echo "TARGET_ARCHS=${{ matrix.arch }}" >> $GITHUB_ENV - echo "WORKDIR=${{ runner.temp }}/swift-android-sdk" >> $GITHUB_ENV - - name: Checkout repository - uses: actions/checkout@v4 - - name: Build Android SDK (Local) - if: ${{ matrix.build-type == 'local' }} - working-directory: swift-ci/sdks/android - run: | - sudo apt install -q patchelf build-essential cmake ninja-build python3 golang git gnupg2 libcurl4-openssl-dev libedit-dev libicu-dev libncurses5-dev libpython3-dev libsqlite3-dev libxml2-dev rsync uuid-dev uuid-runtime tzdata curl unzip - ./build-local ${SWIFT_VERSION} ${WORKDIR} - - name: Build Android SDK (Docker) - if: ${{ matrix.build-type == 'docker' }} - working-directory: swift-ci/sdks/android - run: | - ./build-docker ${SWIFT_VERSION} ${WORKDIR} - - name: Install Host Toolchain - if: ${{ matrix.build-type == 'docker' }} - working-directory: swift-ci/sdks/android - run: | - # when building in a Docker container, we don't have a local host toolchain, - # but we need one in order to run the SDK validation tests, so we install it now - HOST_OS=ubuntu$(lsb_release -sr) - source ./scripts/toolchain-vars.sh - mkdir -p ${WORKDIR}/host-toolchain - ./scripts/install-swift.sh ${WORKDIR}/host-toolchain/$SWIFT_BASE/usr - ls ${WORKDIR}/host-toolchain - ${WORKDIR}/host-toolchain/*/usr/bin/swift --version - - name: Get artifact info - id: info - shell: bash - run: | - set -ex - SWIFT_ROOT=$(dirname ${WORKDIR}/host-toolchain/*/usr) - echo "swift-root=${SWIFT_ROOT}" >> $GITHUB_OUTPUT - echo "swift-path=${SWIFT_ROOT}/usr/bin/swift" >> $GITHUB_OUTPUT - - ARTIFACT_PATH=$(realpath ${WORKDIR}/products/*.artifactbundle.tar.gz) - echo "artifact-path=${ARTIFACT_PATH}" >> $GITHUB_OUTPUT - echo "sdk-id=x86_64-unknown-linux-android28" >> $GITHUB_OUTPUT - - ARTIFACT_EXT=".artifactbundle.tar.gz" - ARTIFACT_NAME="$(basename ${ARTIFACT_PATH} ${ARTIFACT_EXT})" - # depending on whether we are building locally or in a container, add a maker to the name - if [[ "${{ matrix.build-type }}" == 'local' ]]; then - ARTIFACT_NAME="${ARTIFACT_NAME}-local" - fi - if [[ "${{ matrix.build-compiler }}" == '1' ]]; then - ARTIFACT_NAME="${ARTIFACT_NAME}-hostbuild" - fi - # artifacts need a unique name so we suffix with the matrix arch(s) - if [[ ! -z "${{ matrix.arch }}" ]]; then - ARTIFACT_NAME="${ARTIFACT_NAME}-$(echo ${{ matrix.arch }} | tr ',' '-')" - fi - ARTIFACT_NAME="${ARTIFACT_NAME}${ARTIFACT_EXT}" - - # There is no way to prevent even a single-file artifact from being zipped: - # https://github.com/actions/upload-artifact?tab=readme-ov-file#zip-archives - # so the actual artifact download will look like: - # swift-6.1-RELEASE_android-0.1-x86_64.artifactbundle.tar.gz.zip - echo "artifact-name=${ARTIFACT_NAME}" >> $GITHUB_OUTPUT - - name: Upload SDK artifactbundle - uses: actions/upload-artifact@v4 - with: - compression-level: 0 - name: ${{ steps.info.outputs.artifact-name }} - path: ${{ steps.info.outputs.artifact-path }} - - name: Cleanup - if: ${{ matrix.runner != 'self-hosted' }} - run: | - # need to free up some space or else when installing we get: No space left on device - df -h - rm -rf ${WORKDIR}/{build,source} - sudo docker image prune --all --force - sudo docker builder prune -a - df -h - - name: Install artifactbundle - if: ${{ matrix.runner != 'self-hosted' }} - shell: bash - run: | - set -ex - ${{ steps.info.outputs.swift-path }} sdk install ${{ steps.info.outputs.artifact-path }} - ${{ steps.info.outputs.swift-path }} sdk configure --show-configuration $(${{ steps.info.outputs.swift-path }} sdk list | head -n 1) ${{ steps.info.outputs.sdk-id }} - # recent releases require that ANDROID_NDK_ROOT *not* be set - # see https://github.com/swiftlang/swift-driver/pull/1879 - echo "ANDROID_NDK_ROOT=" >> $GITHUB_ENV - - - name: Create Demo Project - if: ${{ matrix.runner != 'self-hosted' }} - run: | - cd ${{ runner.temp }} - mkdir DemoProject - cd DemoProject - ${{ steps.info.outputs.swift-path }} --version - ${{ steps.info.outputs.swift-path }} package init - echo 'import Foundation' >> Sources/DemoProject/DemoProject.swift - echo 'import FoundationEssentials' >> Sources/DemoProject/DemoProject.swift - echo 'import FoundationXML' >> Sources/DemoProject/DemoProject.swift - echo 'import FoundationNetworking' >> Sources/DemoProject/DemoProject.swift - echo 'import Dispatch' >> Sources/DemoProject/DemoProject.swift - echo 'import Android' >> Sources/DemoProject/DemoProject.swift - - name: Test Demo Project on Android - uses: skiptools/swift-android-action@main - if: ${{ matrix.runner != 'self-hosted' }} - with: - # only test for the complete arch SDK build to speed up CI - #run-tests: ${{ matrix.arch == '' }} - package-path: ${{ runner.temp }}/DemoProject - installed-sdk: ${{ steps.info.outputs.sdk-id }} - installed-swift: ${{ steps.info.outputs.swift-root }} - - - name: Checkout swift-algorithms - if: ${{ matrix.runner != 'self-hosted' }} - uses: actions/checkout@v4 - with: - repository: apple/swift-algorithms - path: swift-algorithms - - name: Test swift-algorithms - if: ${{ matrix.runner != 'self-hosted' }} - uses: skiptools/swift-android-action@main - with: - package-path: swift-algorithms - installed-sdk: ${{ steps.info.outputs.sdk-id }} - installed-swift: ${{ steps.info.outputs.swift-root }} From 6cf9eb92e0a7f11007e805d21b09774e4373ab42 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Wed, 14 Jan 2026 17:16:00 -0500 Subject: [PATCH 4/8] Update adb check for sys.boot_completed --- .github/workflows/scripts/android/android-emulator-tests.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scripts/android/android-emulator-tests.sh b/.github/workflows/scripts/android/android-emulator-tests.sh index feef7d8..6c5fc41 100755 --- a/.github/workflows/scripts/android/android-emulator-tests.sh +++ b/.github/workflows/scripts/android/android-emulator-tests.sh @@ -96,7 +96,7 @@ log "Starting Android emulator" nohup emulator -no-metrics -partition-size 1024 -memory 4096 -wipe-data -no-window -no-snapshot -noaudio -no-boot-anim -avd "${ANDROID_EMULATOR_NAME}" & # wait briefly before starting to poll the emulator -sleep 20 +sleep 10 log "Waiting for Android emulator startup" EMULATOR_CHECK_SECONDS_ELAPSED=0 @@ -104,6 +104,7 @@ EMULATOR_CHECK_INTERVAL=5 # Seconds between status checks while true; do # Check if the boot is completed # 'adb shell getprop sys.boot_completed' returns 1 when done + adb shell getprop sys.boot_completed BOOT_STATUS=$(adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r') if [ "$BOOT_STATUS" == "1" ]; then @@ -112,8 +113,7 @@ while true; do fi if [ "$EMULATOR_CHECK_SECONDS_ELAPSED" -ge "$ANDROID_EMULATOR_TIMEOUT" ]; then - log "Timeout reached ($ANDROID_EMULATOR_TIMEOUT seconds). Aborting." - exit 1 + fatal "Timeout reached ($ANDROID_EMULATOR_TIMEOUT seconds). Aborting." fi sleep "$EMULATOR_CHECK_INTERVAL" From 81d8b2109a53b12e206d4bde85aebb010746492a Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Wed, 14 Jan 2026 17:26:26 -0500 Subject: [PATCH 5/8] Update adb check for sys.boot_completed --- .github/workflows/scripts/android/android-emulator-tests.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scripts/android/android-emulator-tests.sh b/.github/workflows/scripts/android/android-emulator-tests.sh index 6c5fc41..b1f4638 100755 --- a/.github/workflows/scripts/android/android-emulator-tests.sh +++ b/.github/workflows/scripts/android/android-emulator-tests.sh @@ -104,8 +104,9 @@ EMULATOR_CHECK_INTERVAL=5 # Seconds between status checks while true; do # Check if the boot is completed # 'adb shell getprop sys.boot_completed' returns 1 when done - adb shell getprop sys.boot_completed - BOOT_STATUS=$(adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r') + # Ignore failure status since it will fail with "adb: device offline" + adb shell getprop sys.boot_completed || true + BOOT_STATUS=$(adb shell getprop sys.boot_completed || true 2>/dev/null | tr -d '\r') if [ "$BOOT_STATUS" == "1" ]; then log "Emulator is ready" From a2722fb4090f6ac3a1927cc87c47e3546ea2ae90 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Wed, 14 Jan 2026 17:38:20 -0500 Subject: [PATCH 6/8] Update adb check for sys.boot_completed --- .github/workflows/scripts/android/android-emulator-tests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/scripts/android/android-emulator-tests.sh b/.github/workflows/scripts/android/android-emulator-tests.sh index b1f4638..e3c0bb6 100755 --- a/.github/workflows/scripts/android/android-emulator-tests.sh +++ b/.github/workflows/scripts/android/android-emulator-tests.sh @@ -98,14 +98,13 @@ nohup emulator -no-metrics -partition-size 1024 -memory 4096 -wipe-data -no-wind # wait briefly before starting to poll the emulator sleep 10 -log "Waiting for Android emulator startup" EMULATOR_CHECK_SECONDS_ELAPSED=0 EMULATOR_CHECK_INTERVAL=5 # Seconds between status checks while true; do + log "Waiting for Android emulator startup ($EMULATOR_CHECK_SECONDS_ELAPSED)" # Check if the boot is completed # 'adb shell getprop sys.boot_completed' returns 1 when done # Ignore failure status since it will fail with "adb: device offline" - adb shell getprop sys.boot_completed || true BOOT_STATUS=$(adb shell getprop sys.boot_completed || true 2>/dev/null | tr -d '\r') if [ "$BOOT_STATUS" == "1" ]; then From b3ba408f45215663699785a94587a8a39e6b3ca0 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Wed, 14 Jan 2026 17:40:47 -0500 Subject: [PATCH 7/8] Update adb check for sys.boot_completed --- .../workflows/scripts/android/android-emulator-tests.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/scripts/android/android-emulator-tests.sh b/.github/workflows/scripts/android/android-emulator-tests.sh index e3c0bb6..51d580d 100755 --- a/.github/workflows/scripts/android/android-emulator-tests.sh +++ b/.github/workflows/scripts/android/android-emulator-tests.sh @@ -95,13 +95,13 @@ log "Starting Android emulator" # launch the emulator in the background nohup emulator -no-metrics -partition-size 1024 -memory 4096 -wipe-data -no-window -no-snapshot -noaudio -no-boot-anim -avd "${ANDROID_EMULATOR_NAME}" & -# wait briefly before starting to poll the emulator -sleep 10 - EMULATOR_CHECK_SECONDS_ELAPSED=0 EMULATOR_CHECK_INTERVAL=5 # Seconds between status checks while true; do + sleep "$EMULATOR_CHECK_INTERVAL" + ((EMULATOR_CHECK_SECONDS_ELAPSED+=EMULATOR_CHECK_INTERVAL)) log "Waiting for Android emulator startup ($EMULATOR_CHECK_SECONDS_ELAPSED)" + # Check if the boot is completed # 'adb shell getprop sys.boot_completed' returns 1 when done # Ignore failure status since it will fail with "adb: device offline" @@ -115,9 +115,6 @@ while true; do if [ "$EMULATOR_CHECK_SECONDS_ELAPSED" -ge "$ANDROID_EMULATOR_TIMEOUT" ]; then fatal "Timeout reached ($ANDROID_EMULATOR_TIMEOUT seconds). Aborting." fi - - sleep "$EMULATOR_CHECK_INTERVAL" - ((EMULATOR_CHECK_SECONDS_ELAPSED+=EMULATOR_CHECK_INTERVAL)) done log "Prepare Swift test package" From cecb78e0d63a2dcc1c23de58f15c1ca3ee2460e9 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Wed, 14 Jan 2026 17:41:50 -0500 Subject: [PATCH 8/8] Syntax cleanup in android-emulator-tests.sh --- .github/workflows/scripts/android/android-emulator-tests.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/scripts/android/android-emulator-tests.sh b/.github/workflows/scripts/android/android-emulator-tests.sh index 51d580d..1cd32a3 100755 --- a/.github/workflows/scripts/android/android-emulator-tests.sh +++ b/.github/workflows/scripts/android/android-emulator-tests.sh @@ -110,9 +110,7 @@ while true; do if [ "$BOOT_STATUS" == "1" ]; then log "Emulator is ready" break; - fi - - if [ "$EMULATOR_CHECK_SECONDS_ELAPSED" -ge "$ANDROID_EMULATOR_TIMEOUT" ]; then + elif [ "$EMULATOR_CHECK_SECONDS_ELAPSED" -ge "$ANDROID_EMULATOR_TIMEOUT" ]; then fatal "Timeout reached ($ANDROID_EMULATOR_TIMEOUT seconds). Aborting." fi done