From e757db178a76a137884f92761ac48098c0246e30 Mon Sep 17 00:00:00 2001 From: Tony Giorgio Date: Fri, 9 Jan 2026 01:05:38 -0600 Subject: [PATCH 1/9] ci: parallelize Android builds for faster CI Split Android build into parallel jobs: 1. build-frontend: Build frontend once (shared) 2. build-rust (4x parallel): Compile each target separately - aarch64-linux-android - armv7-linux-androideabi - i686-linux-android - x86_64-linux-android 3. package-android: Download all .so files, run Gradle Each Rust job has its own sccache keyed by target for better cache hits. Expected improvement: ~10min -> ~5min (parallel Rust + Gradle) Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- .github/workflows/android-build.yml | 283 +++++++++++++++++++--------- 1 file changed, 191 insertions(+), 92 deletions(-) diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml index 3f411f3de..1bb942dc9 100644 --- a/.github/workflows/android-build.yml +++ b/.github/workflows/android-build.yml @@ -6,21 +6,18 @@ on: pull_request: branches: [ master ] +env: + VITE_OPEN_SECRET_API_URL: ${{ github.event_name == 'pull_request' && 'https://enclave.secretgpt.ai' || 'https://enclave.trymaple.ai' }} + VITE_MAPLE_BILLING_API_URL: ${{ github.event_name == 'pull_request' && 'https://billing-dev.opensecret.cloud' || 'https://billing.opensecret.cloud' }} + VITE_CLIENT_ID: ba5a14b5-d915-47b1-b7b1-afda52bc5fc6 + jobs: - build-android: + # Build frontend once, shared by all jobs + build-frontend: runs-on: ubuntu-latest-8-cores steps: - uses: actions/checkout@v4 - - name: Setup Java - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: '21' - - - name: Setup Android SDK - uses: android-actions/setup-android@v3 - - name: Setup Bun uses: oven-sh/setup-bun@v1 with: @@ -36,10 +33,48 @@ jobs: restore-keys: | ${{ runner.os }}-bun- + - name: Install frontend dependencies + working-directory: ./frontend + run: bun install + + - name: Build frontend + working-directory: ./frontend + run: bun run build + + - name: Upload frontend dist + uses: actions/upload-artifact@v4 + with: + name: frontend-dist + path: frontend/dist + retention-days: 1 + + # Build each Rust target in parallel + build-rust: + runs-on: ubuntu-latest-8-cores + needs: build-frontend + strategy: + fail-fast: false + matrix: + include: + - target: aarch64-linux-android + jni_dir: arm64-v8a + short_name: aarch64 + - target: armv7-linux-androideabi + jni_dir: armeabi-v7a + short_name: armv7 + - target: i686-linux-android + jni_dir: x86 + short_name: i686 + - target: x86_64-linux-android + jni_dir: x86_64 + short_name: x86_64 + steps: + - uses: actions/checkout@v4 + - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - targets: aarch64-linux-android,armv7-linux-androideabi,x86_64-linux-android,i686-linux-android + targets: ${{ matrix.target }} - name: Setup Android NDK uses: nttld/setup-ndk@v1 @@ -48,16 +83,6 @@ jobs: ndk-version: r27c add-to-path: true - - name: Cache Gradle - uses: actions/cache@v4 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('frontend/src-tauri/gen/android/**/*.gradle*', 'frontend/src-tauri/gen/android/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - name: Install sccache run: | SCCACHE_VERSION=0.8.2 @@ -65,44 +90,164 @@ jobs: curl -L "$SCCACHE_URL" | tar xz sudo mv sccache-v${SCCACHE_VERSION}-x86_64-unknown-linux-musl/sccache /usr/local/bin/ chmod +x /usr/local/bin/sccache - sccache --version - name: Cache sccache uses: actions/cache@v4 with: path: ~/.cache/sccache - key: ${{ runner.os }}-sccache-android-${{ hashFiles('**/Cargo.lock') }} + key: ${{ runner.os }}-sccache-android-${{ matrix.short_name }}-${{ hashFiles('**/Cargo.lock') }} restore-keys: | + ${{ runner.os }}-sccache-android-${{ matrix.short_name }}- ${{ runner.os }}-sccache-android- - ${{ runner.os }}-sccache- - - name: Cache Cargo bin (Tauri CLI) + - name: Cache Cargo registry uses: actions/cache@v4 with: - path: ~/.cargo/bin/ - key: ${{ runner.os }}-cargo-bin-tauri-cli-2.9.2 + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} restore-keys: | - ${{ runner.os }}-cargo-bin-tauri-cli- - ${{ runner.os }}-cargo-bin- + ${{ runner.os }}-cargo-registry- - name: Install Linux dependencies run: | sudo apt-get update sudo apt-get install -y libssl-dev + - name: Configure build environment + run: | + echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV + echo "SCCACHE_DIR=$HOME/.cache/sccache" >> $GITHUB_ENV + echo "SCCACHE_CACHE_SIZE=2G" >> $GITHUB_ENV + + NDK_HOME=${{ steps.setup-ndk.outputs.ndk-path }} + + # Set up cross-compilation environment for this target + case "${{ matrix.target }}" in + aarch64-linux-android) + echo "AR_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" >> $GITHUB_ENV + echo "CC_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang" >> $GITHUB_ENV + echo "CXX_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang++" >> $GITHUB_ENV + echo "RANLIB_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib" >> $GITHUB_ENV + sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/aarch64-linux-android-ranlib + ;; + armv7-linux-androideabi) + echo "AR_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" >> $GITHUB_ENV + echo "CC_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang" >> $GITHUB_ENV + echo "CXX_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang++" >> $GITHUB_ENV + echo "RANLIB_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib" >> $GITHUB_ENV + sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/armv7a-linux-androideabi-ranlib + ;; + i686-linux-android) + echo "AR_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" >> $GITHUB_ENV + echo "CC_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android24-clang" >> $GITHUB_ENV + echo "CXX_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android24-clang++" >> $GITHUB_ENV + echo "RANLIB_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib" >> $GITHUB_ENV + sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/i686-linux-android-ranlib + ;; + x86_64-linux-android) + echo "AR_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" >> $GITHUB_ENV + echo "CC_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang" >> $GITHUB_ENV + echo "CXX_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang++" >> $GITHUB_ENV + echo "RANLIB_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib" >> $GITHUB_ENV + sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/x86_64-linux-android-ranlib + ;; + esac + + - name: Build Rust library for ${{ matrix.target }} + working-directory: ./frontend/src-tauri + run: | + cargo build --release --target ${{ matrix.target }} --lib + + - name: Show sccache stats + run: sccache --show-stats + + - name: Upload native library + uses: actions/upload-artifact@v4 + with: + name: android-lib-${{ matrix.short_name }} + path: frontend/src-tauri/target/${{ matrix.target }}/release/*.so + retention-days: 1 + + # Package everything with Gradle + package-android: + runs-on: ubuntu-latest-8-cores + needs: build-rust + steps: + - uses: actions/checkout@v4 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '21' + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + + - name: Setup Bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: 1.2.2 + + - name: Cache Bun dependencies + uses: actions/cache@v4 + with: + path: | + ~/.bun/install/cache + frontend/node_modules + key: ${{ runner.os }}-bun-${{ hashFiles('frontend/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun- + + - name: Setup Android NDK + uses: nttld/setup-ndk@v1 + id: setup-ndk + with: + ndk-version: r27c + add-to-path: true + + - name: Cache Gradle + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('frontend/src-tauri/gen/android/**/*.gradle*', 'frontend/src-tauri/gen/android/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + - name: Install frontend dependencies working-directory: ./frontend run: bun install - - name: Install Tauri CLI + - name: Download frontend dist + uses: actions/download-artifact@v4 + with: + name: frontend-dist + path: frontend/dist + + - name: Download all native libraries + uses: actions/download-artifact@v4 + with: + pattern: android-lib-* + path: native-libs + + - name: Place native libraries in jniLibs run: | - if ! command -v cargo-tauri &> /dev/null; then - cargo install tauri-cli --version "2.9.2" --locked - else - echo "Tauri CLI already installed" - fi - env: - CARGO_CFG_TARGET_OS: linux + # Create jniLibs directories + mkdir -p frontend/src-tauri/gen/android/app/src/main/jniLibs/{arm64-v8a,armeabi-v7a,x86,x86_64} + + # Copy libraries to correct locations + cp native-libs/android-lib-aarch64/*.so frontend/src-tauri/gen/android/app/src/main/jniLibs/arm64-v8a/ + cp native-libs/android-lib-armv7/*.so frontend/src-tauri/gen/android/app/src/main/jniLibs/armeabi-v7a/ + cp native-libs/android-lib-i686/*.so frontend/src-tauri/gen/android/app/src/main/jniLibs/x86/ + cp native-libs/android-lib-x86_64/*.so frontend/src-tauri/gen/android/app/src/main/jniLibs/x86_64/ + + # Verify + echo "=== Native libraries placed ===" + find frontend/src-tauri/gen/android/app/src/main/jniLibs -name "*.so" -exec ls -la {} \; - name: Setup Android signing env: @@ -116,10 +261,8 @@ jobs: echo "password=$ANDROID_KEY_PASSWORD" >> keystore.properties echo "storeFile=$RUNNER_TEMP/keystore.jks" >> keystore.properties - - name: Generate tauri.properties (Workaround for Tauri 2.9.x bug) + - name: Generate tauri.properties run: | - # Workaround for Tauri 2.9.x not generating tauri.properties correctly - # See: https://github.com/tauri-apps/tauri/issues/YOUR_ISSUE_NUMBER VERSION=$(jq -r '.version' frontend/src-tauri/tauri.conf.json) VERSION_CODE=$(jq -r '.bundle.android.versionCode' frontend/src-tauri/tauri.conf.json) @@ -132,69 +275,25 @@ jobs: echo "Generated tauri.properties with version $VERSION and versionCode $VERSION_CODE" - - name: Configure sccache - run: | - echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV - echo "SCCACHE_DIR=$HOME/.cache/sccache" >> $GITHUB_ENV - echo "SCCACHE_CACHE_SIZE=2G" >> $GITHUB_ENV - - - name: Build Tauri Android App (Signed Release) - working-directory: ./frontend + - name: Build APK and AAB with Gradle + working-directory: ./frontend/src-tauri/gen/android run: | export ANDROID_HOME=$ANDROID_SDK_ROOT export NDK_HOME=${{ steps.setup-ndk.outputs.ndk-path }} - - # Set up Android NDK toolchain paths - export PATH=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH - - # Set up cross-compilation environment variables for each target - export AR_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar - export CC_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang - export CXX_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang++ - export RANLIB_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib - - export AR_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar - export CC_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang - export CXX_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang++ - export RANLIB_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib - - export AR_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar - export CC_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang - export CXX_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang++ - export RANLIB_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib - - export AR_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar - export CC_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android24-clang - export CXX_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android24-clang++ - export RANLIB_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib - - # Create symlinks for ranlib that OpenSSL expects - sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/aarch64-linux-android-ranlib - sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/armv7a-linux-androideabi-ranlib - sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/x86_64-linux-android-ranlib - sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/i686-linux-android-ranlib - - cargo tauri android build - env: - VITE_OPEN_SECRET_API_URL: ${{ github.event_name == 'pull_request' && 'https://enclave.secretgpt.ai' || 'https://enclave.trymaple.ai' }} - VITE_MAPLE_BILLING_API_URL: ${{ github.event_name == 'pull_request' && 'https://billing-dev.opensecret.cloud' || 'https://billing.opensecret.cloud' }} - VITE_CLIENT_ID: ba5a14b5-d915-47b1-b7b1-afda52bc5fc6 - - - name: Show sccache stats - run: sccache --show-stats + + # Build both APK and AAB in parallel + ./gradlew assembleUniversalRelease bundleUniversalRelease --parallel - name: Upload Android APK uses: actions/upload-artifact@v4 with: name: maple-android-apk - path: | - frontend/src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk + path: frontend/src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk retention-days: 5 - name: Upload Android AAB uses: actions/upload-artifact@v4 with: name: maple-android-aab - path: | - frontend/src-tauri/gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab - retention-days: 5 \ No newline at end of file + path: frontend/src-tauri/gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab + retention-days: 5 From 697a9c3b54728962b223cce503b1cb2c6fc78964 Mon Sep 17 00:00:00 2001 From: Tony Giorgio Date: Fri, 9 Jan 2026 01:16:15 -0600 Subject: [PATCH 2/9] fix: add CARGO_TARGET_*_LINKER for Android cross-compilation The linker must be explicitly set when using cargo build directly (vs cargo tauri android build which sets it internally). Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- .github/workflows/android-build.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml index 1bb942dc9..7d3acd535 100644 --- a/.github/workflows/android-build.yml +++ b/.github/workflows/android-build.yml @@ -123,9 +123,10 @@ jobs: NDK_HOME=${{ steps.setup-ndk.outputs.ndk-path }} - # Set up cross-compilation environment for this target + # Set up cross-compilation environment for this target (CC, AR, RANLIB, and LINKER) case "${{ matrix.target }}" in aarch64-linux-android) + echo "CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang" >> $GITHUB_ENV echo "AR_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" >> $GITHUB_ENV echo "CC_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang" >> $GITHUB_ENV echo "CXX_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang++" >> $GITHUB_ENV @@ -133,6 +134,7 @@ jobs: sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/aarch64-linux-android-ranlib ;; armv7-linux-androideabi) + echo "CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang" >> $GITHUB_ENV echo "AR_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" >> $GITHUB_ENV echo "CC_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang" >> $GITHUB_ENV echo "CXX_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang++" >> $GITHUB_ENV @@ -140,6 +142,7 @@ jobs: sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/armv7a-linux-androideabi-ranlib ;; i686-linux-android) + echo "CARGO_TARGET_I686_LINUX_ANDROID_LINKER=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android24-clang" >> $GITHUB_ENV echo "AR_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" >> $GITHUB_ENV echo "CC_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android24-clang" >> $GITHUB_ENV echo "CXX_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android24-clang++" >> $GITHUB_ENV @@ -147,6 +150,7 @@ jobs: sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/i686-linux-android-ranlib ;; x86_64-linux-android) + echo "CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang" >> $GITHUB_ENV echo "AR_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" >> $GITHUB_ENV echo "CC_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang" >> $GITHUB_ENV echo "CXX_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang++" >> $GITHUB_ENV From e24f76d27fa666fc30c0413fd14268ea4822fb69 Mon Sep 17 00:00:00 2001 From: Tony Giorgio Date: Fri, 9 Jan 2026 01:28:17 -0600 Subject: [PATCH 3/9] fix: generate tauri.settings.gradle and remove unnecessary bun install - Generate tauri.settings.gradle in aarch64 job (contains Tauri plugin paths) - Upload as artifact and download in package-android job - Remove unnecessary bun install/setup from package-android (Gradle doesn't need node_modules) Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- .github/workflows/android-build.yml | 68 +++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml index 7d3acd535..30c0a6ab9 100644 --- a/.github/workflows/android-build.yml +++ b/.github/workflows/android-build.yml @@ -159,6 +159,49 @@ jobs: ;; esac + - name: Cache Cargo bin (Tauri CLI) + if: matrix.short_name == 'aarch64' + uses: actions/cache@v4 + with: + path: ~/.cargo/bin/ + key: ${{ runner.os }}-cargo-bin-tauri-cli-2.9.2 + restore-keys: | + ${{ runner.os }}-cargo-bin-tauri-cli- + + - name: Install Tauri CLI (aarch64 only, for generating gradle files) + if: matrix.short_name == 'aarch64' + run: | + if ! command -v cargo-tauri &> /dev/null; then + cargo install tauri-cli --version "2.9.2" --locked + fi + env: + CARGO_CFG_TARGET_OS: linux + + - name: Generate tauri.settings.gradle (aarch64 only) + if: matrix.short_name == 'aarch64' + working-directory: ./frontend + run: | + # Run tauri android build which will generate the gradle files, then fail at Rust compile (that's ok) + # We just need the tauri.settings.gradle file + cargo tauri android build 2>&1 || true + + # Verify the file was generated + if [ -f "src-tauri/gen/android/tauri.settings.gradle" ]; then + echo "tauri.settings.gradle generated successfully" + cat src-tauri/gen/android/tauri.settings.gradle + else + echo "ERROR: tauri.settings.gradle was not generated" + exit 1 + fi + + - name: Upload tauri.settings.gradle (aarch64 only) + if: matrix.short_name == 'aarch64' + uses: actions/upload-artifact@v4 + with: + name: tauri-settings-gradle + path: frontend/src-tauri/gen/android/tauri.settings.gradle + retention-days: 1 + - name: Build Rust library for ${{ matrix.target }} working-directory: ./frontend/src-tauri run: | @@ -190,21 +233,6 @@ jobs: - name: Setup Android SDK uses: android-actions/setup-android@v3 - - name: Setup Bun - uses: oven-sh/setup-bun@v1 - with: - bun-version: 1.2.2 - - - name: Cache Bun dependencies - uses: actions/cache@v4 - with: - path: | - ~/.bun/install/cache - frontend/node_modules - key: ${{ runner.os }}-bun-${{ hashFiles('frontend/bun.lockb') }} - restore-keys: | - ${{ runner.os }}-bun- - - name: Setup Android NDK uses: nttld/setup-ndk@v1 id: setup-ndk @@ -222,10 +250,6 @@ jobs: restore-keys: | ${{ runner.os }}-gradle- - - name: Install frontend dependencies - working-directory: ./frontend - run: bun install - - name: Download frontend dist uses: actions/download-artifact@v4 with: @@ -238,6 +262,12 @@ jobs: pattern: android-lib-* path: native-libs + - name: Download tauri.settings.gradle + uses: actions/download-artifact@v4 + with: + name: tauri-settings-gradle + path: frontend/src-tauri/gen/android + - name: Place native libraries in jniLibs run: | # Create jniLibs directories From f852c52cb9138f6aa487995e906376ddbda2bf34 Mon Sep 17 00:00:00 2001 From: Tony Giorgio Date: Fri, 9 Jan 2026 01:36:20 -0600 Subject: [PATCH 4/9] refactor: move gradle file generation to dedicated parallel job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add generate-gradle-files job that runs in parallel with build-rust - Keeps build-rust jobs clean (just Rust compilation) - package-android now depends on both build-rust and generate-gradle-files Job structure: build-frontend ─┬─> build-rust (4x parallel) ─┬─> package-android └─> generate-gradle-files ────┘ Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- .github/workflows/android-build.yml | 111 +++++++++++++++++----------- 1 file changed, 67 insertions(+), 44 deletions(-) diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml index 30c0a6ab9..b1f89a018 100644 --- a/.github/workflows/android-build.yml +++ b/.github/workflows/android-build.yml @@ -48,6 +48,72 @@ jobs: path: frontend/dist retention-days: 1 + # Generate Tauri gradle files (runs in parallel with build-rust) + generate-gradle-files: + runs-on: ubuntu-latest-8-cores + steps: + - uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: 1.2.2 + + - name: Cache Bun dependencies + uses: actions/cache@v4 + with: + path: | + ~/.bun/install/cache + frontend/node_modules + key: ${{ runner.os }}-bun-${{ hashFiles('frontend/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun- + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Cache Cargo bin (Tauri CLI) + uses: actions/cache@v4 + with: + path: ~/.cargo/bin/ + key: ${{ runner.os }}-cargo-bin-tauri-cli-2.9.2 + restore-keys: | + ${{ runner.os }}-cargo-bin-tauri-cli- + + - name: Install frontend dependencies + working-directory: ./frontend + run: bun install + + - name: Install Tauri CLI + run: | + if ! command -v cargo-tauri &> /dev/null; then + cargo install tauri-cli --version "2.9.2" --locked + fi + env: + CARGO_CFG_TARGET_OS: linux + + - name: Generate tauri.settings.gradle + working-directory: ./frontend + run: | + # Run tauri android build - it will generate gradle files then fail at Rust compile (expected) + cargo tauri android build 2>&1 || true + + # Verify the file was generated + if [ -f "src-tauri/gen/android/tauri.settings.gradle" ]; then + echo "tauri.settings.gradle generated successfully:" + cat src-tauri/gen/android/tauri.settings.gradle + else + echo "ERROR: tauri.settings.gradle was not generated" + exit 1 + fi + + - name: Upload tauri.settings.gradle + uses: actions/upload-artifact@v4 + with: + name: tauri-settings-gradle + path: frontend/src-tauri/gen/android/tauri.settings.gradle + retention-days: 1 + # Build each Rust target in parallel build-rust: runs-on: ubuntu-latest-8-cores @@ -159,49 +225,6 @@ jobs: ;; esac - - name: Cache Cargo bin (Tauri CLI) - if: matrix.short_name == 'aarch64' - uses: actions/cache@v4 - with: - path: ~/.cargo/bin/ - key: ${{ runner.os }}-cargo-bin-tauri-cli-2.9.2 - restore-keys: | - ${{ runner.os }}-cargo-bin-tauri-cli- - - - name: Install Tauri CLI (aarch64 only, for generating gradle files) - if: matrix.short_name == 'aarch64' - run: | - if ! command -v cargo-tauri &> /dev/null; then - cargo install tauri-cli --version "2.9.2" --locked - fi - env: - CARGO_CFG_TARGET_OS: linux - - - name: Generate tauri.settings.gradle (aarch64 only) - if: matrix.short_name == 'aarch64' - working-directory: ./frontend - run: | - # Run tauri android build which will generate the gradle files, then fail at Rust compile (that's ok) - # We just need the tauri.settings.gradle file - cargo tauri android build 2>&1 || true - - # Verify the file was generated - if [ -f "src-tauri/gen/android/tauri.settings.gradle" ]; then - echo "tauri.settings.gradle generated successfully" - cat src-tauri/gen/android/tauri.settings.gradle - else - echo "ERROR: tauri.settings.gradle was not generated" - exit 1 - fi - - - name: Upload tauri.settings.gradle (aarch64 only) - if: matrix.short_name == 'aarch64' - uses: actions/upload-artifact@v4 - with: - name: tauri-settings-gradle - path: frontend/src-tauri/gen/android/tauri.settings.gradle - retention-days: 1 - - name: Build Rust library for ${{ matrix.target }} working-directory: ./frontend/src-tauri run: | @@ -220,7 +243,7 @@ jobs: # Package everything with Gradle package-android: runs-on: ubuntu-latest-8-cores - needs: build-rust + needs: [build-rust, generate-gradle-files] steps: - uses: actions/checkout@v4 From c7fc1df0a5c1af025e2412effdfdbf476aefc483 Mon Sep 17 00:00:00 2001 From: Tony Giorgio Date: Fri, 9 Jan 2026 01:44:11 -0600 Subject: [PATCH 5/9] fix: upload both tauri.settings.gradle and tauri.build.gradle.kts Tauri generates two gradle files that are needed for packaging: - tauri.settings.gradle (in gen/android/) - tauri.build.gradle.kts (in gen/android/app/) Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- .github/workflows/android-build.yml | 40 +++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml index b1f89a018..75e667830 100644 --- a/.github/workflows/android-build.yml +++ b/.github/workflows/android-build.yml @@ -92,26 +92,33 @@ jobs: env: CARGO_CFG_TARGET_OS: linux - - name: Generate tauri.settings.gradle + - name: Generate Tauri gradle files working-directory: ./frontend run: | # Run tauri android build - it will generate gradle files then fail at Rust compile (expected) cargo tauri android build 2>&1 || true - # Verify the file was generated - if [ -f "src-tauri/gen/android/tauri.settings.gradle" ]; then - echo "tauri.settings.gradle generated successfully:" + # Verify the files were generated + if [ -f "src-tauri/gen/android/tauri.settings.gradle" ] && [ -f "src-tauri/gen/android/app/tauri.build.gradle.kts" ]; then + echo "=== tauri.settings.gradle ===" cat src-tauri/gen/android/tauri.settings.gradle + echo "" + echo "=== tauri.build.gradle.kts ===" + cat src-tauri/gen/android/app/tauri.build.gradle.kts else - echo "ERROR: tauri.settings.gradle was not generated" + echo "ERROR: Tauri gradle files were not generated" + ls -la src-tauri/gen/android/ + ls -la src-tauri/gen/android/app/ || true exit 1 fi - - name: Upload tauri.settings.gradle + - name: Upload Tauri gradle files uses: actions/upload-artifact@v4 with: - name: tauri-settings-gradle - path: frontend/src-tauri/gen/android/tauri.settings.gradle + name: tauri-gradle-files + path: | + frontend/src-tauri/gen/android/tauri.settings.gradle + frontend/src-tauri/gen/android/app/tauri.build.gradle.kts retention-days: 1 # Build each Rust target in parallel @@ -285,11 +292,22 @@ jobs: pattern: android-lib-* path: native-libs - - name: Download tauri.settings.gradle + - name: Download Tauri gradle files uses: actions/download-artifact@v4 with: - name: tauri-settings-gradle - path: frontend/src-tauri/gen/android + name: tauri-gradle-files + path: tauri-gradle-files + + - name: Place Tauri gradle files + run: | + # Move files to correct locations (artifact preserves directory structure from common prefix) + cp tauri-gradle-files/tauri.settings.gradle frontend/src-tauri/gen/android/ + mkdir -p frontend/src-tauri/gen/android/app + cp tauri-gradle-files/app/tauri.build.gradle.kts frontend/src-tauri/gen/android/app/ + + echo "=== Tauri gradle files placed ===" + ls -la frontend/src-tauri/gen/android/tauri.settings.gradle + ls -la frontend/src-tauri/gen/android/app/tauri.build.gradle.kts - name: Place native libraries in jniLibs run: | From 9a4e2d5007c824015c0d2bb8f9d8aab702b4c47f Mon Sep 17 00:00:00 2001 From: Tony Giorgio Date: Fri, 9 Jan 2026 12:21:51 -0600 Subject: [PATCH 6/9] fix: make Android packaging job self-contained Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- .github/workflows/android-build.yml | 93 +++++++++++++------ .../opensecret/maple/kotlin/RustPlugin.kt | 10 ++ 2 files changed, 77 insertions(+), 26 deletions(-) diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml index 75e667830..6a93fa0ea 100644 --- a/.github/workflows/android-build.yml +++ b/.github/workflows/android-build.yml @@ -48,7 +48,7 @@ jobs: path: frontend/dist retention-days: 1 - # Generate Tauri gradle files (runs in parallel with build-rust) + # Generate Tauri Android files required by the Gradle build (runs in parallel with build-rust) generate-gradle-files: runs-on: ubuntu-latest-8-cores steps: @@ -92,33 +92,59 @@ jobs: env: CARGO_CFG_TARGET_OS: linux - - name: Generate Tauri gradle files + - name: Generate Tauri Android files working-directory: ./frontend run: | # Run tauri android build - it will generate gradle files then fail at Rust compile (expected) cargo tauri android build 2>&1 || true - # Verify the files were generated - if [ -f "src-tauri/gen/android/tauri.settings.gradle" ] && [ -f "src-tauri/gen/android/app/tauri.build.gradle.kts" ]; then - echo "=== tauri.settings.gradle ===" - cat src-tauri/gen/android/tauri.settings.gradle - echo "" - echo "=== tauri.build.gradle.kts ===" - cat src-tauri/gen/android/app/tauri.build.gradle.kts - else - echo "ERROR: Tauri gradle files were not generated" - ls -la src-tauri/gen/android/ - ls -la src-tauri/gen/android/app/ || true + # Verify required generated files exist + REQUIRED_FILES=( + "src-tauri/gen/android/tauri.settings.gradle" + "src-tauri/gen/android/app/tauri.build.gradle.kts" + "src-tauri/gen/android/app/src/main/assets/tauri.conf.json" + "src-tauri/gen/android/app/proguard-tauri.pro" + ) + + for f in "${REQUIRED_FILES[@]}"; do + if [ ! -f "$f" ]; then + echo "ERROR: Missing generated file: $f" + exit 1 + fi + done + + GENERATED_DIR=$(find src-tauri/gen/android/app/src/main/java -type d -name generated -print -quit || true) + if [ -z "$GENERATED_DIR" ]; then + echo "ERROR: Missing generated Kotlin sources directory under src-tauri/gen/android/app/src/main/java" exit 1 fi - - name: Upload Tauri gradle files + if ! find "$GENERATED_DIR" -type f -name "*.kt" -print -quit | grep -q .; then + echo "ERROR: No generated Kotlin sources found in $GENERATED_DIR" + exit 1 + fi + + echo "=== Generated files OK ===" + echo "tauri.settings.gradle:" + sed -n '1,200p' src-tauri/gen/android/tauri.settings.gradle + echo "" + echo "tauri.build.gradle.kts:" + cat src-tauri/gen/android/app/tauri.build.gradle.kts + echo "" + echo "generated sources dir: $GENERATED_DIR" + ls -la "$GENERATED_DIR" | head -50 + + - name: Upload Tauri Android generated files uses: actions/upload-artifact@v4 with: - name: tauri-gradle-files + name: tauri-android-generated path: | frontend/src-tauri/gen/android/tauri.settings.gradle + frontend/src-tauri/gen/android/.tauri/** frontend/src-tauri/gen/android/app/tauri.build.gradle.kts + frontend/src-tauri/gen/android/app/src/main/assets/tauri.conf.json + frontend/src-tauri/gen/android/app/src/main/java/**/generated/** + frontend/src-tauri/gen/android/app/proguard-tauri.pro retention-days: 1 # Build each Rust target in parallel @@ -144,6 +170,12 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Download frontend dist + uses: actions/download-artifact@v4 + with: + name: frontend-dist + path: frontend/dist + - name: Install Rust uses: dtolnay/rust-toolchain@stable with: @@ -254,6 +286,16 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Cache Cargo registry (for tauri-android Gradle projects) + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-registry- + - name: Setup Java uses: actions/setup-java@v4 with: @@ -292,22 +334,21 @@ jobs: pattern: android-lib-* path: native-libs - - name: Download Tauri gradle files + - name: Download Tauri Android generated files uses: actions/download-artifact@v4 with: - name: tauri-gradle-files - path: tauri-gradle-files + name: tauri-android-generated + path: tauri-android-generated - - name: Place Tauri gradle files + - name: Place Tauri Android generated files run: | - # Move files to correct locations (artifact preserves directory structure from common prefix) - cp tauri-gradle-files/tauri.settings.gradle frontend/src-tauri/gen/android/ - mkdir -p frontend/src-tauri/gen/android/app - cp tauri-gradle-files/app/tauri.build.gradle.kts frontend/src-tauri/gen/android/app/ - - echo "=== Tauri gradle files placed ===" + # Copy generated files into the checked out Android project + cp -R tauri-android-generated/. frontend/src-tauri/gen/android/ + + echo "=== Tauri generated files placed ===" ls -la frontend/src-tauri/gen/android/tauri.settings.gradle ls -la frontend/src-tauri/gen/android/app/tauri.build.gradle.kts + ls -la frontend/src-tauri/gen/android/app/src/main/assets/tauri.conf.json - name: Place native libraries in jniLibs run: | @@ -357,7 +398,7 @@ jobs: export NDK_HOME=${{ steps.setup-ndk.outputs.ndk-path }} # Build both APK and AAB in parallel - ./gradlew assembleUniversalRelease bundleUniversalRelease --parallel + ./gradlew assembleUniversalRelease bundleUniversalRelease --parallel -PskipRustBuild=true - name: Upload Android APK uses: actions/upload-artifact@v4 diff --git a/frontend/src-tauri/gen/android/buildSrc/src/main/java/cloud/opensecret/maple/kotlin/RustPlugin.kt b/frontend/src-tauri/gen/android/buildSrc/src/main/java/cloud/opensecret/maple/kotlin/RustPlugin.kt index 4aa7fcaf6..5502889b4 100644 --- a/frontend/src-tauri/gen/android/buildSrc/src/main/java/cloud/opensecret/maple/kotlin/RustPlugin.kt +++ b/frontend/src-tauri/gen/android/buildSrc/src/main/java/cloud/opensecret/maple/kotlin/RustPlugin.kt @@ -17,6 +17,11 @@ open class RustPlugin : Plugin { override fun apply(project: Project) = with(project) { config = extensions.create("rust", Config::class.java) + val skipRustBuild = + (findProperty("skipRustBuild") as? String)?.toBooleanStrictOrNull() == true || + (findProperty("skipRustBuild") as? Boolean) == true || + hasProperty("skipRustBuild") + val defaultAbiList = listOf("arm64-v8a", "armeabi-v7a", "x86", "x86_64"); val abiList = (findProperty("abiList") as? String)?.split(',') ?: defaultAbiList @@ -47,6 +52,11 @@ open class RustPlugin : Plugin { } afterEvaluate { + if (skipRustBuild) { + logger.lifecycle("RustPlugin: skipping Rust build tasks (-PskipRustBuild)") + return@afterEvaluate + } + for (profile in listOf("debug", "release")) { val profileCapitalized = profile.replaceFirstChar { it.uppercase() } val buildTask = tasks.maybeCreate( From 45e1c2a88bb976882115f92fb031033a7f40b154 Mon Sep 17 00:00:00 2001 From: Tony Giorgio Date: Fri, 9 Jan 2026 12:38:06 -0600 Subject: [PATCH 7/9] fix: generate Android CI files via tauri android init Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- .github/workflows/android-build.yml | 38 +++++++++++++++-------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml index 6a93fa0ea..338f9e400 100644 --- a/.github/workflows/android-build.yml +++ b/.github/workflows/android-build.yml @@ -54,23 +54,18 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Setup Bun - uses: oven-sh/setup-bun@v1 - with: - bun-version: 1.2.2 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable - - name: Cache Bun dependencies + - name: Cache Cargo registry uses: actions/cache@v4 with: path: | - ~/.bun/install/cache - frontend/node_modules - key: ${{ runner.os }}-bun-${{ hashFiles('frontend/bun.lockb') }} + ~/.cargo/registry + ~/.cargo/git + key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} restore-keys: | - ${{ runner.os }}-bun- - - - name: Install Rust - uses: dtolnay/rust-toolchain@stable + ${{ runner.os }}-cargo-registry- - name: Cache Cargo bin (Tauri CLI) uses: actions/cache@v4 @@ -80,10 +75,6 @@ jobs: restore-keys: | ${{ runner.os }}-cargo-bin-tauri-cli- - - name: Install frontend dependencies - working-directory: ./frontend - run: bun install - - name: Install Tauri CLI run: | if ! command -v cargo-tauri &> /dev/null; then @@ -95,8 +86,13 @@ jobs: - name: Generate Tauri Android files working-directory: ./frontend run: | - # Run tauri android build - it will generate gradle files then fail at Rust compile (expected) - cargo tauri android build 2>&1 || true + set -euo pipefail + + # Ensure all Tauri + plugin crates exist in the cargo registry so tauri.settings.gradle can be generated. + cargo fetch --locked --manifest-path src-tauri/Cargo.toml + + # Generate Android project + required autogen files without compiling Rust. + cargo tauri android init --ci --force # Verify required generated files exist REQUIRED_FILES=( @@ -237,6 +233,7 @@ jobs: echo "CXX_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang++" >> $GITHUB_ENV echo "RANLIB_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib" >> $GITHUB_ENV sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/aarch64-linux-android-ranlib + sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/bin/aarch64-linux-android-ranlib ;; armv7-linux-androideabi) echo "CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang" >> $GITHUB_ENV @@ -245,6 +242,9 @@ jobs: echo "CXX_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang++" >> $GITHUB_ENV echo "RANLIB_armv7_linux_androideabi=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib" >> $GITHUB_ENV sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/armv7a-linux-androideabi-ranlib + sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/arm-linux-androideabi-ranlib + sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/bin/armv7a-linux-androideabi-ranlib + sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/bin/arm-linux-androideabi-ranlib ;; i686-linux-android) echo "CARGO_TARGET_I686_LINUX_ANDROID_LINKER=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android24-clang" >> $GITHUB_ENV @@ -253,6 +253,7 @@ jobs: echo "CXX_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android24-clang++" >> $GITHUB_ENV echo "RANLIB_i686_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib" >> $GITHUB_ENV sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/i686-linux-android-ranlib + sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/bin/i686-linux-android-ranlib ;; x86_64-linux-android) echo "CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang" >> $GITHUB_ENV @@ -261,6 +262,7 @@ jobs: echo "CXX_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android24-clang++" >> $GITHUB_ENV echo "RANLIB_x86_64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib" >> $GITHUB_ENV sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/local/bin/x86_64-linux-android-ranlib + sudo ln -sf $NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib /usr/bin/x86_64-linux-android-ranlib ;; esac From 189fccf4f23b5e09a67f5859461e32ff3f244464 Mon Sep 17 00:00:00 2001 From: Tony Giorgio Date: Fri, 9 Jan 2026 12:43:24 -0600 Subject: [PATCH 8/9] fix: use supported tauri android init flags Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- .github/workflows/android-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml index 338f9e400..1fdf44dce 100644 --- a/.github/workflows/android-build.yml +++ b/.github/workflows/android-build.yml @@ -92,7 +92,7 @@ jobs: cargo fetch --locked --manifest-path src-tauri/Cargo.toml # Generate Android project + required autogen files without compiling Rust. - cargo tauri android init --ci --force + cargo tauri android init --ci # Verify required generated files exist REQUIRED_FILES=( From 79e2d438733b9b871017c9ede4140a81257ac65a Mon Sep 17 00:00:00 2001 From: Tony Giorgio Date: Fri, 9 Jan 2026 13:04:10 -0600 Subject: [PATCH 9/9] fix: handle nested output from tauri android init Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- .github/workflows/android-build.yml | 56 ++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml index 1fdf44dce..0f2e58135 100644 --- a/.github/workflows/android-build.yml +++ b/.github/workflows/android-build.yml @@ -93,13 +93,53 @@ jobs: # Generate Android project + required autogen files without compiling Rust. cargo tauri android init --ci + + # The repo contains a tracked Android Gradle project at src-tauri/gen/android. + # Depending on Tauri CLI behavior, `android init` may generate into a subdir like + # src-tauri/gen/android/. We always copy the generated artifacts back + # into src-tauri/gen/android so downstream jobs have a stable path. + ANDROID_GEN_DIR="src-tauri/gen/android" + + TAURI_SETTINGS_PATH=$(find "$ANDROID_GEN_DIR" -maxdepth 3 -name tauri.settings.gradle -print -quit || true) + if [ -z "$TAURI_SETTINGS_PATH" ]; then + echo "ERROR: tauri.settings.gradle not found anywhere under $ANDROID_GEN_DIR" + echo "=== Contents of $ANDROID_GEN_DIR (depth 3) ===" + find "$ANDROID_GEN_DIR" -maxdepth 3 -type f -print | sort | head -200 + exit 1 + fi + + GENERATED_PROJECT_DIR=$(dirname "$TAURI_SETTINGS_PATH") + echo "Found tauri.settings.gradle at: $TAURI_SETTINGS_PATH" + + if [ "$GENERATED_PROJECT_DIR" != "$ANDROID_GEN_DIR" ]; then + echo "Copying generated Android files from $GENERATED_PROJECT_DIR -> $ANDROID_GEN_DIR" + + cp "$GENERATED_PROJECT_DIR/tauri.settings.gradle" "$ANDROID_GEN_DIR/tauri.settings.gradle" + + mkdir -p "$ANDROID_GEN_DIR/app/src/main/assets" + cp "$GENERATED_PROJECT_DIR/app/tauri.build.gradle.kts" "$ANDROID_GEN_DIR/app/tauri.build.gradle.kts" + cp "$GENERATED_PROJECT_DIR/app/src/main/assets/tauri.conf.json" "$ANDROID_GEN_DIR/app/src/main/assets/tauri.conf.json" + cp "$GENERATED_PROJECT_DIR/app/proguard-tauri.pro" "$ANDROID_GEN_DIR/app/proguard-tauri.pro" + + SRC_GENERATED_DIR=$(find "$GENERATED_PROJECT_DIR/app/src/main/java" -type d -name generated -print -quit || true) + if [ -z "$SRC_GENERATED_DIR" ]; then + echo "ERROR: Missing generated Kotlin sources directory under $GENERATED_PROJECT_DIR/app/src/main/java" + exit 1 + fi + + REL_GENERATED_DIR=${SRC_GENERATED_DIR#"$GENERATED_PROJECT_DIR/"} + DEST_GENERATED_PARENT="$ANDROID_GEN_DIR/$(dirname "$REL_GENERATED_DIR")" + rm -rf "$ANDROID_GEN_DIR/$REL_GENERATED_DIR" + mkdir -p "$DEST_GENERATED_PARENT" + cp -R "$SRC_GENERATED_DIR" "$DEST_GENERATED_PARENT/" + fi # Verify required generated files exist REQUIRED_FILES=( - "src-tauri/gen/android/tauri.settings.gradle" - "src-tauri/gen/android/app/tauri.build.gradle.kts" - "src-tauri/gen/android/app/src/main/assets/tauri.conf.json" - "src-tauri/gen/android/app/proguard-tauri.pro" + "$ANDROID_GEN_DIR/tauri.settings.gradle" + "$ANDROID_GEN_DIR/app/tauri.build.gradle.kts" + "$ANDROID_GEN_DIR/app/src/main/assets/tauri.conf.json" + "$ANDROID_GEN_DIR/app/proguard-tauri.pro" ) for f in "${REQUIRED_FILES[@]}"; do @@ -109,9 +149,9 @@ jobs: fi done - GENERATED_DIR=$(find src-tauri/gen/android/app/src/main/java -type d -name generated -print -quit || true) + GENERATED_DIR=$(find "$ANDROID_GEN_DIR/app/src/main/java" -type d -name generated -print -quit || true) if [ -z "$GENERATED_DIR" ]; then - echo "ERROR: Missing generated Kotlin sources directory under src-tauri/gen/android/app/src/main/java" + echo "ERROR: Missing generated Kotlin sources directory under $ANDROID_GEN_DIR/app/src/main/java" exit 1 fi @@ -122,10 +162,10 @@ jobs: echo "=== Generated files OK ===" echo "tauri.settings.gradle:" - sed -n '1,200p' src-tauri/gen/android/tauri.settings.gradle + sed -n '1,200p' "$ANDROID_GEN_DIR/tauri.settings.gradle" echo "" echo "tauri.build.gradle.kts:" - cat src-tauri/gen/android/app/tauri.build.gradle.kts + cat "$ANDROID_GEN_DIR/app/tauri.build.gradle.kts" echo "" echo "generated sources dir: $GENERATED_DIR" ls -la "$GENERATED_DIR" | head -50