Skip to content

Conversation

@haslinghuis
Copy link
Member

@haslinghuis haslinghuis commented Oct 28, 2025

  • Signing is mandatory to be able to install the APK
  • Update minimal supported SDK to 28 (Android 9.0)

Summary by CodeRabbit

  • Documentation

    • Added comprehensive Android APK signing guide covering debug and release signing workflows.
  • New Features

    • Android APKs and AABs now automatically signed during builds (debug for CI, release for production).
    • Release signing supports GitHub Secrets configuration for secure keystore management.
  • Chores

    • Updated minimum Android SDK version to 28.
    • Added keystore files to version control ignore patterns.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 28, 2025

Walkthrough

This 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

Cohort / File(s) Summary
Android Signing Documentation
​.github/ANDROID_SIGNING.md
New comprehensive guide covering debug and release signing workflows, keystore creation, GitHub Secrets configuration, verification procedures, installation instructions, and security best practices.
CI Workflow Updates
​.github/workflows/ci.yml
Adds debug keystore generation and APK signing steps for tauri-android-preview using zipalign and apksigner; updates artifact upload to reference debug-signed APK.
Release Workflow Updates
​.github/workflows/release.yml
Implements conditional release keystore creation from secrets with fallback to debug keystore; adds signing logic for both APKs (with zipalign and v1 signing support) and AABs (release keystore only); updates artifact upload paths.
Configuration & Ignores
​.gitignore, src-tauri/tauri.conf.json
Adds ignore patterns for keystore files (​*.keystore, ​*.jks, debug.keystore); sets minSdkVersion to 28 in Tauri bundle configuration.

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
Loading
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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • .github/workflows/release.yml: Requires careful review of the conditional keystore creation logic (decode base64 from secrets, fallback handling) and signing command sequences with dual-keystore support.
  • .github/workflows/ci.yml: Review signing step integration, keystore generation, and zipalign/apksigner invocation correctness.
  • .github/ANDROID_SIGNING.md: Verify documentation accuracy regarding secret names, signing procedures, and Play Store publication requirements.
  • .gitignore and src-tauri/tauri.conf.json: Straightforward additions but should confirm keystore file patterns are comprehensive and minSdkVersion value is appropriate.

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description Check ⚠️ Warning The pull request description is extremely minimal, consisting of only two bullet points that identify what was changed (APK signing and SDK version) but lack the depth and structure suggested by the repository template. The template emphasizes important considerations such as following coding style guidelines, confirming proper branch usage, describing commit structure, referencing related issues with "Fixes #", and testing verification. The provided description does not address these guidelines or provide substantive context about the changes, their rationale, testing performed, or any issues being resolved. While the description is not entirely off-topic and does convey basic information about the PR's purpose, it falls short of demonstrating engagement with the template's expectations for a complete pull request description.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title "[Tauri] Add APK signing" directly and accurately reflects the primary objective of the changeset. The PR introduces comprehensive APK signing functionality across multiple files including a new signing guide, updates to both CI and release workflows to implement signing with keystores, keystore file ignore patterns, and a minSDK version constraint. The title is concise, specific, and clearly communicates the main change without vagueness or unnecessary noise.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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.
@haslinghuis haslinghuis mentioned this pull request Oct 28, 2025
12 tasks
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
@haslinghuis haslinghuis changed the title Add APK signing [Tauri] Add APK signing Oct 28, 2025
nerdCopter
nerdCopter previously approved these changes Oct 28, 2025
@haslinghuis
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 28, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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.apk and *-signed.aab, which match both -release-signed and -debug-signed variants. 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.yml lines 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

📥 Commits

Reviewing files that changed from the base of the PR and between 02c04e4 and 52516d1.

📒 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.yml line 103 (see earlier comment). Once that's fixed, this documentation will fully align with the workflows.

@sonarqubecloud
Copy link

@haslinghuis haslinghuis merged commit f9879f4 into betaflight:tauri Oct 28, 2025
10 checks passed
@haslinghuis haslinghuis deleted the tauri-sign-apk branch October 28, 2025 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants