-
-
Notifications
You must be signed in to change notification settings - Fork 1k
[Tauri] Add APK signing #4685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Tauri] Add APK signing #4685
Conversation
WalkthroughThis pull request adds Android APK and AAB signing capabilities to the CI/CD workflows. It implements debug signing for preview builds and conditional release signing for production, includes a keystore management guide, and adds SDK version constraints. Changes
Sequence Diagram(s)sequenceDiagram
actor Trigger as Trigger
participant CI as CI Workflow
participant Keystore as Keystore
participant APK as Build Artifact
participant Upload as Artifact Upload
Trigger->>CI: Build triggered
CI->>Keystore: Check/Generate debug keystore
Keystore-->>CI: Debug keystore ready
CI->>APK: zipalign unsigned APK
APK-->>CI: Aligned APK
CI->>APK: apksigner sign (v1)
APK-->>CI: Debug-signed APK
CI->>Upload: Upload debug-signed APK
Upload-->>Trigger: Debug artifact available
Note over CI,Upload: CI builds always use debug signing
sequenceDiagram
actor Trigger as Trigger
participant Release as Release Workflow
participant Secrets as GitHub Secrets
participant Keystore as Keystore Management
participant Signing as Signing Service
participant Upload as Artifact Upload
Trigger->>Release: Release triggered
Release->>Secrets: Check for release secrets
alt Secrets Present
Secrets-->>Keystore: Decode base64 keystore
Keystore-->>Keystore: Create release keystore
Keystore-->>Signing: Release keystore available
else Secrets Missing
Secrets-->>Keystore: No secrets found
Keystore-->>Signing: Generate debug keystore (fallback)
Note over Keystore,Signing: Fallback to debug signing
end
Signing->>Signing: zipalign APK
Signing->>Signing: apksigner sign APK (v1)
Signing->>Signing: jarsigner sign AAB (if release keystore)
Signing-->>Upload: Signed APK/AAB ready
Upload-->>Trigger: Release artifacts uploaded
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The previous implementation had the wrong order: 1. It signed the unsigned APK in-place 2. Then tried to zipalign from the unsigned APK to a signed APK This caused installation failures with 'You can't install the app on your device'. The correct order is: 1. Zipalign the unsigned APK to create an aligned APK 2. Sign the aligned APK 3. Move to final signed APK name 4. Verify the signature Also added signature verification step to catch issues early.
This ensures the APK can only be installed on Android 9.0 (Pie) and beyond. Previous minSdkVersion was 22 (Android 5.1).
Added android.minSdkVersion to tauri.conf.json bundle configuration. Reverted the Capacitor android/variables.gradle change since that folder will be replaced by Tauri's generated Android project.
…\n- Zipalign before signing\n- Use apksigner to produce modern signatures (fixes install failures)\n- Verify with apksigner verify\n- Remove committed debug.keystore and ignore keystore files
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (4)
.github/workflows/release.yml (3)
203-211: Artifact paths will match both release and debug signed APKs/AABs.The glob patterns on lines 208-209 use
*-signed.apkand*-signed.aab, which match both-release-signedand-debug-signedvariants. This flexibly handles the fallback case (when release keystore is unavailable) but means both artifact types could be uploaded. This is acceptable given the design, but consider whether you want to differentiate in artifact naming or add a verification step to confirm the signing type.
154-183: APK signing process is sound, but inconsistent error handling with CI workflow.The APK signing logic correctly zipaligns before signing and includes verification. However, when no unsigned APK is found, this script only warns (line 182), whereas the CI workflow (ci.yml, line 188) exits with
exit 1. This inconsistency could mask build failures in release workflows.Consider making error handling consistent: either both warn or both fail.
119-201: Consider extracting APK signing logic to reduce duplication with CI workflow.The APK signing process here (zipalign + apksigner + verify) is nearly identical to the logic in
ci.ymllines 181-214. While the context differs (release vs debug fallback), extracting this to a shared shell script or GitHub Action would improve maintainability.This is optional but recommended for long-term maintenance.
.github/workflows/ci.yml (1)
181-214: Minor: Redundant BUILD_TOOLS_VERSION computation.Line 196 determines the build tools version inline for the zipalign command, and then line 200 recomputes the same value. Consider refactoring to compute it once at the start of the script:
set -euo pipefail + BUILD_TOOLS_VERSION=$(ls ${ANDROID_HOME}/build-tools | tail -1) UNSIGNED_APK=$(find src-tauri/gen/android/app/build/outputs/apk -name "*-unsigned.apk" | head -1) ... # Use $BUILD_TOOLS_VERSION directly - ${ANDROID_HOME}/build-tools/$(ls ${ANDROID_HOME}/build-tools | tail -1)/zipalign -v -p 4 + ${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/zipalign -v -p 4 ... - BUILD_TOOLS_VERSION=$(ls ${ANDROID_HOME}/build-tools | tail -1) ${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/apksigner sign \
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
.github/ANDROID_SIGNING.md(1 hunks).github/workflows/ci.yml(1 hunks).github/workflows/release.yml(1 hunks).gitignore(1 hunks)src-tauri/tauri.conf.json(1 hunks)
🔇 Additional comments (5)
src-tauri/tauri.conf.json (1)
31-34: LGTM!Configuration is correct. Android minSdkVersion 28 (Android 9.0+) is a reasonable baseline for modern app development.
.gitignore (1)
55-58: LGTM!Keystore ignore patterns are comprehensive and correctly prevent sensitive signing keys from being committed.
.github/workflows/ci.yml (2)
160-179: LGTM!Debug keystore generation is correct, idempotent, and uses safe parameters. The check for existing keystore prevents unnecessary regeneration.
222-229: LGTM!Artifact naming and path patterns correctly reference the debug-signed APK output. The glob pattern properly matches the nested directory structure.
.github/ANDROID_SIGNING.md (1)
1-118: LGTM! Comprehensive and well-organized documentation.The signing guide clearly explains both debug and release signing flows, with correct keytool/jarsigner commands, GitHub Secrets setup, verification steps, and security best practices. The troubleshooting section covers common issues.
Note: The behavior described in lines 58-69 (release signing with secrets) depends on fixing the critical condition check in
.github/workflows/release.ymlline 103 (see earlier comment). Once that's fixed, this documentation will fully align with the workflows.
|



Summary by CodeRabbit
Documentation
New Features
Chores