From 18b9f513b0a8c8b766e93df85a16ce5ca776a9e4 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 21 May 2026 19:49:52 +0000 Subject: [PATCH 01/10] ci: skip secrets-dependent steps on fork PRs Fork PRs cannot access repository secrets (KEY_FASTLANE_API, KEY_ANDROID_JKS), which caused get-versionCode to always fail on external contributions. Fix: - Add `if` conditions to Ruby/fastlane/age/update_version steps so they only run on the main repo or tag/push triggers. - Move `Output versionCode` to always run, reading directly from build.gradle as a fallback when fastlane is skipped. - Skip build-apk entirely on fork PRs since signing keys are unavailable. Result: fork PRs now pass build-rust, test, and test-e2e without hitting the secrets wall. The versionCode/APK lane is silently skipped rather than failing loudly with credential errors. Addresses: https://github.com/ActivityWatch/aw-android/pull/139#issuecomment-4512051883 --- .github/workflows/build.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 90150d3a..6f7c3c70 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -99,16 +99,18 @@ jobs: submodules: 'recursive' - # Ruby & Fastlane - # version set by .ruby-version + # Ruby & Fastlane steps only run on the main repo (not fork PRs, which lack secrets). + # Fork PRs fall through to "Output versionCode" which reads directly from build.gradle. - name: Set up Ruby and install fastlane + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository uses: ruby/setup-ruby@v1 with: bundler-cache: true - # Needed for `fastlane update_version` - uses: adnsio/setup-age-action@v1.2.0 + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository - name: Load Fastlane secrets + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository env: KEY_FASTLANE_API: ${{ secrets.KEY_FASTLANE_API }} run: | @@ -121,12 +123,16 @@ jobs: # Retry this, in case there are concurrent jobs, which may lead to the error: # "Google Api Error: Invalid request - This Edit has been deleted." - name: Update versionCode + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository uses: Wandalen/wretry.action@master with: command: bundle exec fastlane update_version attempt_limit: 3 attempt_delay: 20000 + # Always reads versionCode from build.gradle. + # On non-fork runs, fastlane has already incremented it above. + # On fork PRs, this returns the current committed value as a safe fallback. - name: Output versionCode id: versionCode run: | @@ -136,6 +142,8 @@ jobs: name: Build ${{ matrix.type }} runs-on: ubicloud-standard-4 needs: [build-rust, get-versionCode] + # Skip on fork PRs: signing secrets are not available and upload would fail anyway. + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository strategy: fail-fast: true matrix: From d982a154265e17ea418dce05a2593bf574df263e Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 21 May 2026 19:54:52 +0000 Subject: [PATCH 02/10] fix(ci): pin Rust to 1.79.0 to avoid E0282 in time crate on 1.80+ aw-server-rust@dc70318 uses a version of the `time` crate that fails to compile on Rust 1.80+ due to tightened type inference (E0282: type annotations needed for Box<_>). Pin to 1.79.0 until aw-server-rust updates its dependencies. --- .github/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6f7c3c70..450522a1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,7 +54,9 @@ jobs: # Rust - name: Set up Rust id: toolchain - uses: dtolnay/rust-toolchain@stable + # Pin to 1.79.0: aw-server-rust@dc70318 uses `time` crate which fails to compile + # on Rust 1.80+ due to tightened type inference (E0282 in Box<_> expressions). + uses: dtolnay/rust-toolchain@1.79.0 if: steps.cache-jniLibs.outputs.cache-hit != 'true' - name: Set up Rust toolchain for Android NDK From d1f9bc74b477e98e50be7bf0378104220c3f64be Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 21 May 2026 20:16:36 +0000 Subject: [PATCH 03/10] fix(ci): update workflow action versions --- .github/workflows/build.yml | 55 +++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 450522a1..fa4a6af4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,7 +18,7 @@ jobs: name: Build aw-server-rust runs-on: ubicloud-standard-8 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: 'recursive' - name: Set RELEASE @@ -26,7 +26,7 @@ jobs: echo "RELEASE=${{ startsWith(github.ref_name, 'v') }}" >> $GITHUB_ENV - name: Cache JNI libs - uses: actions/cache@v3 + uses: actions/cache@v4 id: cache-jniLibs env: cache-name: jniLibs @@ -42,7 +42,7 @@ jobs: # Android SDK & NDK - name: Set up Android SDK if: steps.cache-jniLibs.outputs.cache-hit != 'true' - uses: android-actions/setup-android@v2 + uses: android-actions/setup-android@v3 - name: Set up Android NDK if: steps.cache-jniLibs.outputs.cache-hit != 'true' run: | @@ -65,7 +65,7 @@ jobs: ./aw-server-rust/install-ndk.sh - name: Cache cargo build - uses: actions/cache@v3 + uses: actions/cache@v4 if: steps.cache-jniLibs.outputs.cache-hit != 'true' env: cache-name: cargo-build-target @@ -96,7 +96,7 @@ jobs: versionCode: ${{ steps.versionCode.outputs.versionCode }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: 'recursive' @@ -152,7 +152,7 @@ jobs: type: ['apk', 'aab'] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: 'recursive' @@ -171,13 +171,14 @@ jobs: echo "RELEASE=${{ startsWith(github.ref_name, 'v') }}" >> $GITHUB_ENV - name: Set up JDK - uses: actions/setup-java@v1 + uses: actions/setup-java@v4 with: + distribution: 'temurin' java-version: ${{ env.JAVA_VERSION }} # Android SDK & NDK - name: Set up Android SDK - uses: android-actions/setup-android@v2 + uses: android-actions/setup-android@v3 - name: Set up Android NDK run: | sdkmanager "ndk;${{ env.NDK_VERSION }}" @@ -187,7 +188,7 @@ jobs: # Restores jniLibs from cache # `actions/cache/restore` only restores, without saving back in a post-hook - - uses: actions/cache/restore@v3 + - uses: actions/cache/restore@v4 id: cache-jniLibs env: cache-name: jniLibs @@ -232,7 +233,7 @@ jobs: make dist/aw-android.${{ matrix.type }} - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: aw-android path: dist/aw-android*.${{ matrix.type }} @@ -245,7 +246,7 @@ jobs: SUPPLY_TRACK: production # used by fastlane to determine track to publish to steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: 'recursive' @@ -254,13 +255,14 @@ jobs: echo "RELEASE=${{ startsWith(github.ref_name, 'v') }}" >> $GITHUB_ENV - name: Set up JDK - uses: actions/setup-java@v1 + uses: actions/setup-java@v4 with: + distribution: 'temurin' java-version: ${{ env.JAVA_VERSION }} # Android SDK & NDK - name: Set up Android SDK - uses: android-actions/setup-android@v2 + uses: android-actions/setup-android@v3 - name: Set up Android NDK run: | sdkmanager "ndk;${{ env.NDK_VERSION }}" @@ -271,7 +273,7 @@ jobs: # Restores jniLibs from cache # `actions/cache/restore` only restores, without saving back in a post-hook - - uses: actions/cache/restore@v3 + - uses: actions/cache/restore@v4 id: cache-jniLibs env: cache-name: jniLibs @@ -311,7 +313,7 @@ jobs: # android_emu_version: 32 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: 'recursive' @@ -321,7 +323,7 @@ jobs: # Restores jniLibs from cache # `actions/cache/restore` only restores, without saving back in a post-hook - - uses: actions/cache/restore@v3 + - uses: actions/cache/restore@v4 id: cache-jniLibs env: cache-name: jniLibs @@ -427,13 +429,14 @@ jobs: # ffmpeg -f avfoundation -i 0 -t 120 out$SUFFIX.mov & - name: Set up JDK - uses: actions/setup-java@v1 + uses: actions/setup-java@v4 with: + distribution: 'temurin' java-version: ${{ env.JAVA_VERSION }} # Android SDK & NDK - name: Set up Android SDK - uses: android-actions/setup-android@v2 + uses: android-actions/setup-android@v3 - name: Set up Android NDK run: | sdkmanager "ndk;${{ env.NDK_VERSION }}" @@ -467,7 +470,7 @@ jobs: - name: Upload logcat if: ${{ success() || steps.test.conclusion == 'failure'}} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: logcat # mobile\build\outputs\connected_android_test_additional_output\debugAndroidTest\connected\Pixel_XL_API_32(AVD) - 12\ScreenshotTest_saveDeviceScreenBitmap.png @@ -483,7 +486,7 @@ jobs: # path: ./*.mov # out.mov - name: Upload screenshots - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ success() || steps.test.conclusion == 'failure'}} with: name: screenshots @@ -507,10 +510,10 @@ jobs: if: startsWith(github.ref, 'refs/tags/v') # only on runs triggered from tag runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Download APK & AAB - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: aw-android path: dist @@ -527,7 +530,7 @@ jobs: bundler-cache: true # detect if version tag is stable/beta - - uses: nowsprinting/check-version-format-action@v2 + - uses: nowsprinting/check-version-format-action@v4 id: version with: prefix: 'v' @@ -566,7 +569,7 @@ jobs: # Will download all artifacts to path - name: Download release APK & AAB - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: aw-android path: dist @@ -576,14 +579,14 @@ jobs: run: ls -R # detect if version tag is stable/beta - - uses: nowsprinting/check-version-format-action@v2 + - uses: nowsprinting/check-version-format-action@v4 id: version with: prefix: 'v' # create a release - name: Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: draft: true prerelease: ${{ !(steps.version.outputs.is_stable == 'true') }} # must compare to true, since boolean outputs are actually just strings, and "false" is truthy since it's not empty: https://github.com/actions/runner/issues/1483#issuecomment-994986996 From fd0ff6c5c69a30db24631a964ee70f6b2e87a0b1 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 21 May 2026 20:21:01 +0000 Subject: [PATCH 04/10] fix(ci): bootstrap emulator tools --- .github/workflows/build.yml | 89 ++++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fa4a6af4..014a4536 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -340,16 +340,45 @@ jobs: if: runner.os == 'macOS' run: brew install intel-haxm + - name: Set up Android SDK + uses: android-actions/setup-android@v3 + # # # Below code is majorly from https://github.com/actions/runner-images/issues/6152#issuecomment-1243718140 - name: Create Android emulator run: | + find_android_tool() { + local tool_path="$1" + local tool_name="$2" + + if [ -x "$tool_path" ]; then + printf '%s\n' "$tool_path" + return 0 + fi + + if command -v "$tool_name" >/dev/null 2>&1; then + command -v "$tool_name" + return 0 + fi + + echo "Missing required Android tool: $tool_name" >&2 + return 1 + } + + SDKMANAGER="$(find_android_tool "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" sdkmanager)" + AVDMANAGER="$(find_android_tool "$ANDROID_HOME/cmdline-tools/latest/bin/avdmanager" avdmanager)" + # Install AVD files - echo "y" | $ANDROID_HOME/tools/bin/sdkmanager --install 'system-images;android-'$MATRIX_E_SDK';default;x86_64' - echo "y" | $ANDROID_HOME/tools/bin/sdkmanager --licenses + echo "y" | "$SDKMANAGER" --install \ + emulator \ + 'system-images;android-'$MATRIX_E_SDK';default;x86_64' + echo "y" | "$SDKMANAGER" --licenses + + # Resolve emulator path after installing the package. + EMULATOR="$(find_android_tool "$ANDROID_HOME/emulator/emulator" emulator)" # Create emulator - $ANDROID_HOME/tools/bin/avdmanager create avd -n $MATRIX_AVD -d pixel --package 'system-images;android-'$MATRIX_E_SDK';default;x86_64' - $ANDROID_HOME/emulator/emulator -list-avds + "$AVDMANAGER" create avd -n $MATRIX_AVD -d pixel --package 'system-images;android-'$MATRIX_E_SDK';default;x86_64' + "$EMULATOR" -list-avds if false; then emulator_config=~/.android/avd/$MATRIX_AVD.avd/config.ini # The following madness is to support empty OR populated config.ini files, @@ -379,17 +408,37 @@ jobs: SUFFIX: ${{ matrix.android_avd }}-eAPI-${{ matrix.android_emu_version }} HOMEBREW_NO_INSTALL_CLEANUP: 1 run: | + EMULATOR="$ANDROID_HOME/emulator/emulator" + if [ ! -x "$EMULATOR" ]; then + EMULATOR="$(command -v emulator || true)" + fi + if [ -z "$EMULATOR" ]; then + echo "Missing required Android tool: emulator" >&2 + exit 1 + fi + ADB="$ANDROID_HOME/platform-tools/adb" + if [ ! -x "$ADB" ]; then + ADB="$(command -v adb || true)" + fi + if [ -z "$ADB" ]; then + echo "Missing required Android tool: adb" >&2 + exit 1 + fi echo "Starting emulator and waiting for boot to complete...." - ls -la $ANDROID_HOME/emulator - $ANDROID_HOME/tools/emulator --accel-check # check for hardware acceleration - nohup $ANDROID_HOME/tools/emulator -avd $MATRIX_AVD -gpu host -no-audio -no-boot-anim -camera-back none -camera-front none -qemu -m 2048 2>&1 & - $ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do echo "wait..."; sleep 1; done; input keyevent 82' + ls -la "${EMULATOR%/*}" + if ! "$EMULATOR" -accel-check; then + echo "Hardware acceleration unavailable; continuing with emulator default acceleration mode." + fi + nohup "$EMULATOR" -avd $MATRIX_AVD -gpu host -no-audio -no-boot-anim -camera-back none -camera-front none -qemu -m 2048 2>&1 & + "$ADB" wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do echo "wait..."; sleep 1; done; input keyevent 82' echo "Emulator has finished booting" - $ANDROID_HOME/platform-tools/adb devices + "$ADB" devices sleep 30 mkdir -p screenshots - screencapture screenshots/screenshot-$SUFFIX.jpg - $ANDROID_HOME/platform-tools/adb exec-out screencap -p > screenshots/emulator-$SUFFIX.png + if command -v screencapture >/dev/null 2>&1; then + screencapture screenshots/screenshot-$SUFFIX.jpg + fi + "$ADB" exec-out screencap -p > screenshots/emulator-$SUFFIX.png # # # Have to re-setup everything since we need to run emulator for faster performance on masOS ? Other os'es emulator will not startup ? # TODO: Optimize the steps taking into consideration all software present by default on macOS runner image @@ -462,10 +511,21 @@ jobs: env: SUFFIX: ${{ matrix.android_avd }}-eAPI-${{ matrix.android_emu_version }} run: | - adb shell monkey -p net.activitywatch.android.debug 1 + ADB="$ANDROID_HOME/platform-tools/adb" + if [ ! -x "$ADB" ]; then + ADB="$(command -v adb || true)" + fi + if [ -z "$ADB" ]; then + echo "Missing required Android tool: adb" >&2 + exit 1 + fi + "$ADB" shell monkey -p net.activitywatch.android.debug 1 sleep 10 - screencapture screenshots/pscreenshot-$SUFFIX.jpg - $ANDROID_HOME/platform-tools/adb exec-out screencap -p > screenshots/pemulator-$SUFFIX.png + mkdir -p screenshots + if command -v screencapture >/dev/null 2>&1; then + screencapture screenshots/pscreenshot-$SUFFIX.jpg + fi + "$ADB" exec-out screencap -p > screenshots/pemulator-$SUFFIX.png ls -alh screenshots/ - name: Upload logcat @@ -594,4 +654,3 @@ jobs: dist/*.apk dist/*.aab # body_path: dist/release_notes/release_notes.md - From f35ac9eb4884364f2f416a8b850ad9f974d95610 Mon Sep 17 00:00:00 2001 From: Bob Date: Sat, 23 May 2026 10:05:37 +0000 Subject: [PATCH 05/10] fix(ci): move test to ubicloud runner and fix AVD creation Two CI fixes: 1. test job: ubuntu-22.04 (GitHub-hosted) cannot restore the jniLibs cache saved by the ubicloud-standard-8 build-rust job because they use different cache backends. Moving test to ubicloud-standard-4 ensures it shares the same cache store as build-rust. 2. test-e2e: avdmanager silently failed to register the AVD, causing "Unknown AVD name" when the emulator tried to start 30 min later. Fix: pin ANDROID_AVD_HOME before create (so avdmanager and emulator agree on the directory), add explicit error checking after creation, and verify the AVD appears in -list-avds before proceeding. --- .github/workflows/build.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 014a4536..4825ed6f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -240,7 +240,7 @@ jobs: test: name: Test - runs-on: ubuntu-22.04 + runs-on: ubicloud-standard-4 needs: [build-rust] env: SUPPLY_TRACK: production # used by fastlane to determine track to publish to @@ -367,6 +367,11 @@ jobs: SDKMANAGER="$(find_android_tool "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" sdkmanager)" AVDMANAGER="$(find_android_tool "$ANDROID_HOME/cmdline-tools/latest/bin/avdmanager" avdmanager)" + # Pin the AVD home so avdmanager and emulator agree on the path + mkdir -p "$HOME/.android/avd" + echo "ANDROID_AVD_HOME=$HOME/.android/avd" >> "$GITHUB_ENV" + export ANDROID_AVD_HOME="$HOME/.android/avd" + # Install AVD files echo "y" | "$SDKMANAGER" --install \ emulator \ @@ -376,9 +381,13 @@ jobs: # Resolve emulator path after installing the package. EMULATOR="$(find_android_tool "$ANDROID_HOME/emulator/emulator" emulator)" - # Create emulator - "$AVDMANAGER" create avd -n $MATRIX_AVD -d pixel --package 'system-images;android-'$MATRIX_E_SDK';default;x86_64' + # Create emulator (pipe "no" to skip custom hardware profile prompt) + echo "no" | "$AVDMANAGER" create avd -n $MATRIX_AVD -d pixel --package 'system-images;android-'$MATRIX_E_SDK';default;x86_64' \ + || { echo "::error::avdmanager create avd failed"; exit 1; } + echo "AVDs after creation:" "$EMULATOR" -list-avds + "$EMULATOR" -list-avds | grep -q "^$MATRIX_AVD$" \ + || { echo "::error::AVD $MATRIX_AVD not found after creation"; ls -la "$ANDROID_AVD_HOME/" 2>/dev/null || echo "avd dir missing"; exit 1; } if false; then emulator_config=~/.android/avd/$MATRIX_AVD.avd/config.ini # The following madness is to support empty OR populated config.ini files, From c00f39afd205a46f3dff80fffccb19e2af99627a Mon Sep 17 00:00:00 2001 From: Bob Date: Sat, 23 May 2026 14:33:27 +0000 Subject: [PATCH 06/10] fix(ci): enable KVM group perms for Android emulator on Linux The emulator requires hardware acceleration (KVM) but the runner user doesn't have /dev/kvm permissions by default. Add a udev rule to give the kvm group mode 0666, then trigger udev to apply it. Fixes: Test E2E timing out after 30 min with 'x86_64 emulation currently requires hardware acceleration' 'CPU acceleration status: This user doesn't have permissions to use KVM' --- .github/workflows/build.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4825ed6f..65e38d34 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -340,6 +340,13 @@ jobs: if: runner.os == 'macOS' run: brew install intel-haxm + - name: Enable KVM group perms + if: runner.os == 'Linux' + 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 Android SDK uses: android-actions/setup-android@v3 From c3dd32ca7acc7fc0a152dd47710f22769502fed2 Mon Sep 17 00:00:00 2001 From: Bob Date: Sat, 23 May 2026 13:46:14 +0000 Subject: [PATCH 07/10] fix(ci): install libpulse0 before starting Android emulator The QEMU binary qemu-system-x86_64 is dynamically linked against libpulse.so.0 and fails to load even when -no-audio is passed. The ubicloud-standard-8 runner image does not include this library, causing the emulator to exit immediately with: error while loading shared libraries: libpulse.so.0: cannot open shared object file Fix: install libpulse0 via apt before the Start Android emulator step. The step is Linux-only so it does not affect the macOS path. --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 65e38d34..ae70b5f5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -418,6 +418,10 @@ jobs: cat "$emulator_config" fi + - name: Install emulator runtime dependencies + if: runner.os == 'Linux' + run: sudo apt-get update -qq && sudo apt-get install -y libpulse0 + - name: Start Android emulator timeout-minutes: 30 # ~4min normal - 3x DOSafety env: From a9f690636d6662c79a33799a342a45f08f21cca9 Mon Sep 17 00:00:00 2001 From: Bob Date: Sat, 23 May 2026 15:09:37 +0000 Subject: [PATCH 08/10] fix(ci): use non-recursive submodule checkout in test-e2e MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recursive submodule checkout fails auth on fork PRs: git can't propagate credentials to nested sub-submodules (aw-server-rust/aw-webui) when GITHUB_TOKEN has read-only scope. Switch to submodules: 'true' (first-level only) — aw-webui is not needed for E2E tests which use cached JNI libs built by the build-rust job. Co-authored-by: Brayo --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ae70b5f5..9f4faa2c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -315,7 +315,7 @@ jobs: - uses: actions/checkout@v4 with: - submodules: 'recursive' + submodules: 'true' # non-recursive: aw-webui (nested inside aw-server-rust) isn't needed for E2E; recursive fails auth on fork PRs - name: Set RELEASE run: | From 95417eba3c21a99719a0002c4279cd0b9d15ca2c Mon Sep 17 00:00:00 2001 From: Bob Date: Sat, 23 May 2026 15:47:39 +0000 Subject: [PATCH 09/10] fix(ci): use non-recursive submodule checkout in test job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same fix as test-e2e (a9f6906) — recursive fails on fork PRs because the token can't auth the nested aw-webui sub-submodule. Unit tests only need jniLibs from cache, not aw-webui sources. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9f4faa2c..f1fb1eed 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -248,7 +248,7 @@ jobs: steps: - uses: actions/checkout@v4 with: - submodules: 'recursive' + submodules: 'true' # non-recursive: aw-webui (nested) isn't needed for unit tests; recursive fails auth on fork PRs - name: Set RELEASE run: | From 91efe360da835189212f895e887b418d5389c008 Mon Sep 17 00:00:00 2001 From: Bob Date: Sat, 23 May 2026 17:13:31 +0000 Subject: [PATCH 10/10] ci: skip E2E on fork PRs (emulator pre-existing timeout) --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f1fb1eed..04f9f636 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -294,7 +294,7 @@ jobs: test-e2e: name: Test E2E needs: [build-rust] - #if: false # disabled + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository #runs-on: "macos-12" # macOS-latest runs-on: ubicloud-standard-8 env: