Merge pull request #5 from iamjosephmj/feat/app-bundle-integrity #16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Instrumented smoke tests for the :deviceintelligence SDK. | |
| # | |
| # Runs the 11-test suite under :deviceintelligence:src/androidTest on | |
| # three API levels in parallel — 28 (minSdk floor), 33 (modal target | |
| # SDK), 35 (latest stable + 16 KB page-size path) — each on its own | |
| # AGP-managed emulator inside a GitHub Actions runner. Linux runners | |
| # gained KVM/nested-virt support in mid-2024, which is what makes | |
| # managed devices viable without a third-party emulator action. | |
| # | |
| # Image-source choice per API: | |
| # - API 33 / 35: aosp_atd (Android Test Device — headless, ~250 MB, | |
| # boots in seconds, purpose-built for CI smoke runs). | |
| # - API 28: aosp default image (~700 MB, ~30 sec boot). ATD images | |
| # only exist from API 30+, so the floor entry uses the standard | |
| # AOSP system image. | |
| # | |
| # Local invocation mirror (single device): | |
| # ./gradlew :deviceintelligence:api33DebugAndroidTest | |
| # Full matrix: | |
| # ./gradlew :deviceintelligence:allDevicesDebugAndroidTest | |
| name: Instrumented tests | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: instrumented-tests-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| smoke: | |
| name: SDK smoke (API ${{ matrix.api-level }}) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| strategy: | |
| # Independent per-API insight. A flake or genuine regression on | |
| # one API level should not cancel the others — knowing it only | |
| # repros on API 28 (or only on 35) is exactly the actionable | |
| # signal this matrix exists to surface. | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - api-level: 28 | |
| system-image: "system-images;android-28;default;x86_64" | |
| gradle-task: api28DebugAndroidTest | |
| - api-level: 33 | |
| system-image: "system-images;android-33;aosp_atd;x86_64" | |
| gradle-task: api33DebugAndroidTest | |
| - api-level: 35 | |
| system-image: "system-images;android-35;aosp_atd;x86_64" | |
| gradle-task: api35DebugAndroidTest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-java@v5 | |
| with: | |
| distribution: temurin | |
| java-version: 17 | |
| # KVM is the gate for AGP managed devices on Linux. Without it | |
| # the emulator falls back to TCG (software CPU) which times out | |
| # on CI. The runner ships kvm-ok / kvm modules; this step ensures | |
| # the user namespace has access. | |
| - 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 Android SDK (matches AGP / CMake / NDK in module build.gradle.kts) | |
| shell: bash | |
| run: | | |
| set -eu | |
| export ANDROID_SDK_ROOT="$HOME/android-sdk" | |
| export ANDROID_HOME="$ANDROID_SDK_ROOT" | |
| mkdir -p "$ANDROID_SDK_ROOT/cmdline-tools" | |
| curl -sSLo /tmp/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip | |
| unzip -qo /tmp/cmdline-tools.zip -d "$ANDROID_SDK_ROOT/cmdline-tools" | |
| mv "$ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools" "$ANDROID_SDK_ROOT/cmdline-tools/latest" | |
| export PATH="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/emulator:$PATH" | |
| mkdir -p "$ANDROID_SDK_ROOT/licenses" | |
| printf '\n24333f8a63b6825ea9c5514f748d145ef07021\n' > "$ANDROID_SDK_ROOT/licenses/android-sdk-license" | |
| printf '\n84831b9409646a918e30573bab4c9c91346d8abd\n' > "$ANDROID_SDK_ROOT/licenses/android-sdk-preview-license" | |
| # GitHub Actions runs `bash -eo pipefail`, so a `yes | sdkmanager` | |
| # pipeline fails the step when sdkmanager finishes and closes | |
| # stdin: `yes` then gets SIGPIPE on its next write and exits | |
| # non-zero, which under pipefail propagates as a pipeline | |
| # failure even though sdkmanager itself succeeded. Drop | |
| # pipefail just for the license / install pipes; restore it | |
| # immediately after so the rest of the script keeps strict | |
| # pipe semantics. | |
| set +o pipefail | |
| yes | sdkmanager --sdk_root="$ANDROID_SDK_ROOT" --licenses | |
| # `yes |` on the install command too: the system image (ATD | |
| # or default) may carry an additional vendor evaluation | |
| # license that `--licenses` does NOT pre-accept (it's | |
| # prompted at install-time, not registered as an SDK license | |
| # hash). | |
| yes | sdkmanager --sdk_root="$ANDROID_SDK_ROOT" --install \ | |
| "platform-tools" "emulator" \ | |
| "platforms;android-36" "build-tools;36.0.0" \ | |
| "ndk;27.0.12077973" "cmake;3.22.1" \ | |
| "${{ matrix.system-image }}" | |
| set -o pipefail | |
| { | |
| echo "ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT" | |
| echo "ANDROID_HOME=$ANDROID_SDK_ROOT" | |
| echo "PATH=$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/emulator:$PATH" | |
| } >> "$GITHUB_ENV" | |
| - name: Run :deviceintelligence:${{ matrix.gradle-task }} | |
| run: | | |
| chmod +x ./gradlew | |
| ./gradlew :deviceintelligence:${{ matrix.gradle-task }} \ | |
| --no-daemon \ | |
| --stacktrace \ | |
| -Pandroid.testoptions.manageddevices.emulator.gpu=swiftshader_indirect | |
| - name: Upload test report (always) | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: instrumented-test-report-api${{ matrix.api-level }} | |
| path: | | |
| deviceintelligence/build/reports/androidTests/managedDevice/** | |
| deviceintelligence/build/outputs/androidTest-results/managedDevice/** | |
| if-no-files-found: ignore | |
| retention-days: 7 |