Skip to content

[ANDR] Copy jank framedata before using it (#454) #1887

[ANDR] Copy jank framedata before using it (#454)

[ANDR] Copy jank framedata before using it (#454) #1887

Workflow file for this run

name: android
on:
push:
branches:
- main
pull_request:
# Cancel in-progress CI jobs when a new commit is pushed to a PR.
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
actions: write
contents: read
pull-requests: write
statuses: write
jobs:
pre_check:
name: pre_check
runs-on: ubuntu-latest
outputs:
should_run: ${{ steps.check_changes.outputs.run_tests }}
steps:
# Checkout repo to Github Actions runner
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# Check for Bazel build file changes
- name: Check for Bazel build file changes
id: bazel_check
run: ./ci/check_bazel.sh //examples/android:android_app
continue-on-error: true
- name: Check for workflow file changes
id: workflow_check
run: ./ci/files_changed.sh .github/workflows/android.yaml
continue-on-error: true
- name: Check for relevant Gradle changes
id: gradle_check
run: ./ci/files_changed.sh "^platform/jvm/gradle-test-app/.*\.(gradle|kts|kt|xml)$"
continue-on-error: true
- name: Check for Cargo.toml changes
id: cargo_check
run: ./ci/files_changed.sh Cargo.toml
continue-on-error: true
- name: Determine if tests should run
id: check_changes_separate
run: |
bazel_status="${{ steps.bazel_check.outputs.check_result }}"
workflow_status="${{ steps.workflow_check.outputs.check_result }}"
gradle_status="${{ steps.gradle_check.outputs.check_result }}"
cargo_status="${{ steps.cargo_check.outputs.check_result }}"
# Check if any status indicates a relevant change or error
if [[ "$bazel_status" == "1" || "$workflow_status" == "1" || "$gradle_status" == "1" || "$cargo_status" == "1" ]]; then
echo "An unexpected issue occurred during checks."
exit 1
elif [[ "$bazel_status" == "0" || "$workflow_status" == "0" || "$gradle_status" == "0" || "$cargo_status" == "0" ]]; then
echo "Changes detected in one or more checks. Running tests."
echo "run_tests=true" >> $GITHUB_ENV
elif [[ "$bazel_status" == "2" && "$workflow_status" == "2" && "$gradle_status" == "2" && "$cargo_status" == "2" ]]; then
echo "No relevant changes found."
echo "run_tests=false" >> $GITHUB_ENV
else
echo "Unknown issue."
exit 1
fi
shell: bash
- name: Run downstream tests if changes are detected
id: check_changes
if: env.run_tests == 'true'
run: ./ci/run_tests.sh
build_and_compare_apk:
runs-on: ubuntu-latest
if: needs.pre_check.outputs.should_run == 'true'
needs: pre_check
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build Bazel APK
timeout-minutes: 30
run: ./bazelw build --config ci --config release-android --android_platforms=@rules_android//:x86_64 //examples/android:android_app
- name: Upload PR APK
uses: actions/upload-artifact@v4
with:
name: android_app.apk
path: ./bazel-bin/examples/android/android_app.apk
- name: Prepare baseline folder (main only)
if: github.ref == 'refs/heads/main' && success()
run: |
rm -rf bazel_apk_baseline # Remove if it exists
mkdir -p bazel_apk_baseline
cp ./bazel-bin/examples/android/android_app.apk bazel_apk_baseline/
- name: Cache baseline APK (main only)
if: github.ref == 'refs/heads/main' && success()
uses: actions/cache/save@v3
with:
path: bazel_apk_baseline
key: bazel-apk-main-baseline
- name: Restore baseline APK from main (PR only)
if: github.event_name == 'pull_request'
uses: actions/cache/restore@v3
with:
path: bazel_apk_baseline
key: bazel-apk-main-baseline
- name: Compute and compare APK size
if: github.event_name == 'pull_request'
id: apk_size
run: |
APK_PATH=$(find bazel-bin/examples/android -name "android_app.apk" | head -n 1)
BAZEL_APK_BASELINE_PATH=$(find bazel_apk_baseline -name "android_app.apk" | head -n 1)
if [ -z "$APK_PATH" ]; then
echo "❌ Current APK file not found!"
exit 1
fi
CURRENT_SIZE=$(stat -c%s "$APK_PATH")
CURRENT_KB=$((CURRENT_SIZE / 1024))
echo "current_kb=$CURRENT_KB" >> $GITHUB_OUTPUT
if [ -z "$BAZEL_APK_BASELINE_PATH" ]; then
echo "baseline_kb=" >> $GITHUB_OUTPUT
echo "diff_kb=" >> $GITHUB_OUTPUT
else
BASELINE_SIZE=$(stat -c%s "$BAZEL_APK_BASELINE_PATH")
BASELINE_KB=$((BASELINE_SIZE / 1024))
DIFF_KB=$((CURRENT_KB - BASELINE_KB))
echo "baseline_kb=$BASELINE_KB" >> $GITHUB_OUTPUT
echo "diff_kb=$DIFF_KB" >> $GITHUB_OUTPUT
MODIFIED_DATE=$(stat -c %y "$BAZEL_APK_BASELINE_PATH")
echo "Baseline APK last modified date: $MODIFIED_DATE"
fi
- name: Report APK size on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v6
env:
CURRENT_KB: ${{ steps.apk_size.outputs.current_kb }}
BASELINE_KB: ${{ steps.apk_size.outputs.baseline_kb }}
DIFF_KB: ${{ steps.apk_size.outputs.diff_kb }}
with:
script: |
const current = process.env.CURRENT_KB;
const baseline = process.env.BASELINE_KB;
const diff = process.env.DIFF_KB;
let table = '';
if (baseline && baseline !== '') {
table = `
### 📦 APK Size Report
| Metric | Size (KB) |
|------------|-----------|
| Baseline | ${baseline} |
| Current | ${current} |
| Difference | ${diff} |
`;
if (parseInt(diff, 10) > 0) {
table += `> ❌ APK size increased by ${diff} KB.`;
} else if (parseInt(diff, 10) < 0) {
table += `> ✅ APK size decreased by ${Math.abs(diff)} KB.`;
} else {
table += `> ✅ APK size unchanged.`;
}
} else {
table = `📌 Current APK size: ${current} KB (No baseline available for comparison).`;
}
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: table
});
gradle_tests:
# Requires a "larger runner", for nested virtualization support
runs-on: ubuntu-latest-8-cores
env:
SKIP_PROTO_GEN: 1
if: needs.pre_check.outputs.should_run == 'true'
needs: pre_check
steps:
- name: Checkout project sources
uses: actions/checkout@v4
# See https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/
- name: Enable KVM group perms
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: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '17'
cache: gradle
- name: Set up Rust ARM target
run: rustup update && rustup target add aarch64-linux-android && rustup target add x86_64-linux-android
- name: AVD cache
uses: actions/cache@v4
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: ${{ runner.os }}-avd-api-21-2
- name: Create AVD and generate snapshot for caching
if: steps.avd-cache.outputs.cache-hit != 'true'
timeout-minutes: 30
uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # pin@v2.33
with:
channel: stable
force-avd-creation: false
api-level: 21
target: default
ram-size: 2048M
arch: x86_64
disk-size: 6144M
profile: Nexus 6
disable-animations: true
emulator-options: -no-window -accel on -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
script: echo "Generated AVD snapshot for caching."
- name: Gradle capture-timber unit tests
working-directory: ./platform/jvm
run: ./gradlew capture-timber:testReleaseUnitTest --info
- name: Check Licenses for modules
working-directory: ./platform/jvm
run: ./gradlew replay:checkLicense common:checkLicense # capture:checkLicense doesn't work at the moment
- name: Instrumentation Tests
uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # pin@v2.33
with:
channel: stable
force-avd-creation: false
api-level: 21
target: default
ram-size: 2048M
arch: x86_64
disk-size: 6144M
profile: Nexus 6
disable-animations: true
emulator-options: -no-snapshot-save -no-window -accel on -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
script: cd platform/jvm && adb uninstall io.bitdrift.gradletestapp.test; adb uninstall io.bitdrift.gradletestapp; cd ../.. && ./tools/android_sdk_wrapper.sh platform/jvm/gradlew -p platform/jvm gradle-test-app:check gradle-test-app:connectedCheck --stacktrace
verify_android_hello_world_per_version:
needs: build_and_compare_apk
runs-on: ubuntu-latest-8-cores
strategy:
matrix:
api-level: [21, 35]
steps:
# Checkout repo to Github Actions runner
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# See https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/
- name: Enable KVM group perms
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
- uses: actions/download-artifact@v4
with:
name: android_app.apk
path: .
- name: AVD cache
uses: actions/cache@v3
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: ${{ runner.os }}-avd-api${{ matrix.api-level }}-1
- name: Create AVD and generate snapshot for caching
if: steps.avd-cache.outputs.cache-hit != 'true'
timeout-minutes: 30
uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # pin@v2.33
with:
channel: stable
api-level: ${{ matrix.api-level }}
target: google_apis
ram-size: 2048M
arch: x86_64
disk-size: 6144M
profile: Nexus 6
emulator-options: -no-window -accel on -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
script: echo "Generated AVD snapshot for caching."
- name: run tests
uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # pin@v2.33
timeout-minutes: 15
with:
force-avd-creation: false
channel: stable
api-level: ${{ matrix.api-level }}
target: google_apis
ram-size: 2048M
arch: x86_64
disk-size: 6144M
profile: Nexus 6
emulator-options: -no-snapshot-save -no-window -accel on -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
script: ./ci/verify_android.sh
# This is a noop job that completes once all the jobs spawned by the previous step completes. By blocking PR merges on this
# job completing, we are able to gate it on all the previous jobs without explicitly enumerating them.
verify_android:
runs-on: ubuntu-latest
needs: ["pre_check", "build_and_compare_apk", "verify_android_hello_world_per_version", "gradle_tests"]
if: always()
steps:
# Checkout repo to Github Actions runner
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: check result
run: ./ci/check_result.sh ${{ needs.pre_check.result }} && ./ci/check_result.sh ${{ needs.build_and_compare_apk.result }} && ./ci/check_result.sh ${{ needs.verify_android_hello_world_per_version.result }} && ./ci/check_result.sh ${{ needs.gradle_tests.result }}