name: Android release package on: workflow_call: workflow_dispatch: permissions: contents: read concurrency: group: android-release-${{ github.ref }} cancel-in-progress: false defaults: run: shell: bash jobs: build: name: Build signed Android APK and AAB runs-on: ubuntu-24.04 timeout-minutes: 90 env: CARGO_TERM_COLOR: always steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Set up JDK 21 uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 with: distribution: temurin java-version: "21.0.11+10.0.LTS" - name: Set up Gradle uses: gradle/actions/setup-gradle@3f131e8634966bd73d06cc69884922b02e6faf92 # v6.2.0 with: gradle-home-cache-strict-match: true - name: Install Rust 1.91 uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # v1 with: toolchain: "1.91.0" targets: aarch64-linux-android,x86_64-linux-android - name: Cache Cargo uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: | ~/.cargo/registry ~/.cargo/git target key: android-release-cargo-1.91.0-${{ hashFiles('Cargo.lock') }} restore-keys: | android-release-cargo-1.91.0- - name: Set up Android SDK uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3 with: packages: "platform-tools platforms;android-36 build-tools;36.0.0" - name: Set up Android NDK id: setup-ndk uses: nttld/setup-ndk@ed92fe6cadad69be94a966a7ee3271275e62f779 # v1 with: ndk-version: r27c link-to-sdk: true add-to-path: false - name: Export Android NDK location run: | echo "ANDROID_NDK_HOME=${{ steps.setup-ndk.outputs.ndk-path }}" >> "$GITHUB_ENV" echo "ANDROID_NDK_ROOT=${{ steps.setup-ndk.outputs.ndk-path }}" >> "$GITHUB_ENV" - name: Resolve canonical version id: version run: | packaging/version/resolve-version.sh verify >/dev/null echo "app=$(packaging/version/resolve-version.sh product)" >> "$GITHUB_OUTPUT" echo "code=$(packaging/version/resolve-version.sh android-code)" >> "$GITHUB_OUTPUT" - name: Validate signing configuration env: KEYSTORE_BASE64: ${{ secrets.ANDROID_UPLOAD_KEYSTORE_BASE64 }} KEYSTORE_PASSWORD: ${{ secrets.ANDROID_UPLOAD_KEYSTORE_PASSWORD }} KEY_ALIAS: ${{ secrets.ANDROID_UPLOAD_KEY_ALIAS }} KEY_PASSWORD: ${{ secrets.ANDROID_UPLOAD_KEY_PASSWORD }} UPLOAD_CERT_SHA256: ${{ vars.ANDROID_UPLOAD_CERT_SHA256 }} run: | for name in \ KEYSTORE_BASE64 \ KEYSTORE_PASSWORD \ KEY_ALIAS \ KEY_PASSWORD \ UPLOAD_CERT_SHA256; do if [ -z "${!name:-}" ]; then echo "Missing Android release signing configuration: $name" >&2 exit 1 fi done - name: Decode upload keystore env: KEYSTORE_BASE64: ${{ secrets.ANDROID_UPLOAD_KEYSTORE_BASE64 }} run: | keystore="$RUNNER_TEMP/vnidrop-upload.jks" printf '%s' "$KEYSTORE_BASE64" | base64 --decode > "$keystore" chmod 600 "$keystore" test -s "$keystore" echo "VNIDROP_ANDROID_KEYSTORE_PATH=$keystore" >> "$GITHUB_ENV" - name: Build and verify signed release env: VNIDROP_ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_UPLOAD_KEYSTORE_PASSWORD }} VNIDROP_ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_UPLOAD_KEY_ALIAS }} VNIDROP_ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_UPLOAD_KEY_PASSWORD }} VNIDROP_ANDROID_UPLOAD_CERT_SHA256: ${{ vars.ANDROID_UPLOAD_CERT_SHA256 }} run: packaging/android/build-release.sh - name: Remove upload keystore if: always() run: rm -f "$RUNNER_TEMP/vnidrop-upload.jks" - name: Upload Android artifacts uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: vnidrop-${{ steps.version.outputs.app }}-android-release path: build/release/android/ if-no-files-found: error retention-days: 90 compression-level: 0 - name: Summarize Android package run: | echo "### Android release package" >> "$GITHUB_STEP_SUMMARY" echo "- Version: ${{ steps.version.outputs.app }}" >> "$GITHUB_STEP_SUMMARY" echo "- Version code: ${{ steps.version.outputs.code }}" >> "$GITHUB_STEP_SUMMARY" echo "- Signing: upload certificate verified" >> "$GITHUB_STEP_SUMMARY"