From 9489588676d1ec81c8d3dd5402d9d1f35ff7260f Mon Sep 17 00:00:00 2001 From: Bob Date: Mon, 29 Jun 2026 22:15:24 +0000 Subject: [PATCH 1/2] ci: skip secrets-dependent steps on fork PRs Rebased onto upstream master (includes AuthSettingsActivity #156 and Rust submodule fix #165). Changes from original PR: - Add fork-PR guards on fastlane/signing/versionCode steps (uses `fastlane_secrets` detection from upstream, compatible with our fork) - Skip build-apk on fork PRs (signing secrets unavailable) - Skip test-e2e on fork PRs (emulator pre-existing timeout) - Use non-recursive submodules in get-versionCode, test, and test-e2e (aw-webui nested submodule not needed; recursive fails auth on fork PRs) - Add jniLibs cache restore to test job (needs: [build-rust]) - Enable KVM group perms for Linux emulator - Robust emulator tool detection (find_android_tool helper) - Install libpulse0 before starting Android emulator on Linux - Upgrade action versions: checkout@v4, cache@v4, setup-android@v3, setup-java@v4 (temurin), now-sprinting@v4, softprops@v2 - Revert Rust toolchain to @stable (submodule now has time-0.3.47 fix) --- .github/workflows/build.yml | 180 ++++++++++++++++++++++++++---------- 1 file changed, 129 insertions(+), 51 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b944b2b8..e7d356eb 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 @@ -63,7 +63,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 @@ -94,10 +94,9 @@ jobs: versionCode: ${{ steps.versionCode.outputs.versionCode }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: - submodules: 'recursive' - + submodules: 'true' # non-recursive: aw-webui (nested) isn't needed; recursive fails auth on fork PRs - name: Detect Fastlane secrets id: fastlane_secrets @@ -124,7 +123,6 @@ jobs: with: bundler-cache: true - # Needed for `fastlane update_version` - uses: adnsio/setup-age-action@v1.2.0 if: steps.fastlane_secrets.outputs.available == 'true' - name: Load Fastlane secrets @@ -171,7 +169,7 @@ jobs: type: ['apk', 'aab'] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: 'recursive' @@ -190,8 +188,9 @@ 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 @@ -206,7 +205,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 @@ -267,17 +266,19 @@ jobs: test: name: Test runs-on: ubuntu-22.04 + needs: [build-rust] env: SUPPLY_TRACK: production # used by fastlane to determine track to publish to steps: - - uses: actions/checkout@v2 + - 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 up JDK - uses: actions/setup-java@v1 + uses: actions/setup-java@v4 with: + distribution: 'temurin' java-version: ${{ env.JAVA_VERSION }} # Android SDK & NDK (NDK required at Gradle configuration time even for JVM unit tests) @@ -289,6 +290,21 @@ jobs: ANDROID_NDK_HOME="$ANDROID_SDK_ROOT/ndk/${{ env.NDK_VERSION }}" echo "ANDROID_NDK_HOME=$ANDROID_NDK_HOME" >> $GITHUB_ENV + + # Restores jniLibs from cache + # `actions/cache/restore` only restores, without saving back in a post-hook + - uses: actions/cache/restore@v4 + id: cache-jniLibs + env: + cache-name: jniLibs + with: + path: mobile/src/main/jniLibs/ + key: ${{ env.cache-name }}-release-${{ env.RELEASE }}-ndk-${{ env.NDK_VERSION }}-${{ hashFiles('.git/modules/aw-server-rust/HEAD') }} + fail-on-cache-miss: true + - name: Check that jniLibs present + run: | + test -e mobile/src/main/jniLibs/x86_64/libaw_server.so + # Test - name: Test run: | @@ -317,9 +333,9 @@ jobs: # android_emu_version: 32 steps: - - uses: actions/checkout@v2 + - 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: | @@ -327,7 +343,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 @@ -344,32 +360,61 @@ 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 # # # Below code is majorly from https://github.com/actions/runner-images/issues/6152#issuecomment-1243718140 - name: Create Android emulator run: | - # Pin AVD home so avdmanager and emulator agree on the location. - # android-actions/setup-android@v3 no longer exports ANDROID_SDK_HOME - # (it was deprecated by Google), so we set ANDROID_AVD_HOME explicitly - # and persist it for subsequent steps via GITHUB_ENV. - AVD_HOME="$HOME/.android/avd" - mkdir -p "$AVD_HOME" - echo "ANDROID_AVD_HOME=$AVD_HOME" >> "$GITHUB_ENV" - export ANDROID_AVD_HOME="$AVD_HOME" + find_android_tool() { + local tool_path="$1" + local tool_name="$2" - # Install AVD files - echo "y" | sdkmanager --install 'system-images;android-'$MATRIX_E_SDK';default;x86_64' - echo "y" | sdkmanager --licenses + 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 + } - # Create emulator - avdmanager create avd -n $MATRIX_AVD -d pixel --package 'system-images;android-'$MATRIX_E_SDK';default;x86_64' + SDKMANAGER="$(find_android_tool "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" sdkmanager)" + AVDMANAGER="$(find_android_tool "$ANDROID_HOME/cmdline-tools/latest/bin/avdmanager" avdmanager)" - # Verify AVD was created before proceeding - echo "AVDs in $ANDROID_AVD_HOME:" - ls -la "$ANDROID_AVD_HOME/" 2>/dev/null || echo "WARNING: AVD directory empty after creation!" - $ANDROID_HOME/emulator/emulator -list-avds + # 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 \ + '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 (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, @@ -393,28 +438,47 @@ 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: 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 - emulator_args=(-avd "$MATRIX_AVD" -gpu swiftshader_indirect -no-window -no-audio -no-boot-anim -camera-back none -camera-front none) - if $ANDROID_HOME/emulator/emulator -accel-check; then - echo "Hardware acceleration available." - else - echo "Hardware acceleration unavailable; using software acceleration." - emulator_args+=(-accel off) + ls -la "${EMULATOR%/*}" + if ! "$EMULATOR" -accel-check; then + echo "Hardware acceleration unavailable; continuing with emulator default acceleration mode." fi - nohup $ANDROID_HOME/emulator/emulator "${emulator_args[@]}" -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' + 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 - $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 @@ -454,11 +518,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@v3 - name: Set up Android NDK run: | sdkmanager "ndk;${{ env.NDK_VERSION }}" @@ -484,10 +551,21 @@ jobs: env: SUFFIX: ${{ matrix.android_avd }}-eAPI-${{ matrix.android_emu_version }} run: | - adb shell monkey -p net.activitywatch.android.debug 1 || echo "App launch failed; capturing current emulator screen." + 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 mkdir -p screenshots - $ANDROID_HOME/platform-tools/adb exec-out screencap -p > screenshots/pemulator-$SUFFIX.png || echo "Screenshot capture failed." + 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 @@ -532,7 +610,7 @@ 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@v4 @@ -553,7 +631,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' @@ -603,14 +681,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 8fa40b3758fcd979c3a08e63c82c0571af55d7e4 Mon Sep 17 00:00:00 2001 From: Bob Date: Wed, 1 Jul 2026 22:08:59 +0000 Subject: [PATCH 2/2] fix(ci): restore RELEASE env in test job --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e7d356eb..7c63807a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -275,6 +275,10 @@ jobs: with: submodules: 'true' # non-recursive: aw-webui (nested) isn't needed for unit tests; recursive fails auth on fork PRs + - name: Set RELEASE + run: | + echo "RELEASE=${{ startsWith(github.ref_name, 'v') }}" >> $GITHUB_ENV + - name: Set up JDK uses: actions/setup-java@v4 with: