Skip to content

build(android): v3/v4 APK signing + widen versionCode (Phase 3 hardening)#252

Merged
RyRy79261 merged 1 commit into
mainfrom
build/android-signing-versioncode
Jun 20, 2026
Merged

build(android): v3/v4 APK signing + widen versionCode (Phase 3 hardening)#252
RyRy79261 merged 1 commit into
mainfrom
build/android-signing-versioncode

Conversation

@RyRy79261

@RyRy79261 RyRy79261 commented Jun 20, 2026

Copy link
Copy Markdown
Owner

What

Two research-confirmed Android build hardening items (Phase 3, no new dependencies):

v3/v4 APK signing

minSdk is 24, so v1 (JAR) signing is unnecessary. Drop it; add v3 (enables future signing-key rotation) + v4 (incremental install), keep v2.

  • The signing key is unchanged → existing installs update normally, and the App Link cert fingerprint (assetlinks.json) is unaffected.

versionCode overflow widening

major*10000 + minor*100 + patch collides at minor/patch ≥ 100 (e.g. 1.100.0 == 2.0.0). Widened to major*1000000 + minor*1000 + patch.

  • Stays monotonically above the last released code (v1.33.0 = 13300 < 1033000), so Obtainium update detection + any future Play upload keep working.
  • Updated the authoritative formula in apps/native/scripts/sync.mjs (writes version.properties, which build.gradle reads) and the currently-unused mirror in android-release.yml.

Validation

Note

Deferred Phase 3 item still pending your call: moving the Bearer token from localStorage → Android Keystore needs a third-party secure-storage plugin (@aparajita/capacitor-secure-storage) — flagged separately for approval.

Summary by CodeRabbit

  • Chores
    • Updated Android app signing configuration to use newer signing schemes (v2, v3, v4)
    • Enhanced version code calculation formula to support improved release versioning across future updates

…ing)

Research-confirmed follow-ups (no new deps):
- Signing: minSdk is 24, so drop v1 (JAR) signing and add v3 (enables future
  signing-key rotation) + v4 (incremental install), keeping v2. The signing KEY
  is unchanged, so existing installs update normally and the App Link cert
  fingerprint (assetlinks.json) is unaffected.
- versionCode: widen from major*10000+minor*100+patch (collides at minor/patch
  >= 100) to major*1000000+minor*1000+patch. Stays monotonically above the last
  released code (v1.33.0 = 13300 < 1033000). Updated the authoritative formula in
  apps/native/scripts/sync.mjs and the (currently unused) mirror in
  android-release.yml.
@vercel

vercel Bot commented Jun 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
intake-tracker Ready Ready Preview, Comment Jun 20, 2026 1:59am

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR widens the Android versionCode semver formula from major*10000 + minor*100 + patch to major*1000000 + minor*1000 + patch in both the CI release workflow and the local sync script. It also updates the Gradle signing configuration to disable v1 signing and enable v2, v3, and v4 signing schemes.

Changes

Android Release Configuration

Layer / File(s) Summary
versionCode formula widening
apps/native/scripts/sync.mjs, .github/workflows/android-release.yml
Both the local sync script and the CI workflow version-extraction step replace major*10000 + minor*100 + patch with major*1000000 + minor*1000 + patch, with updated inline comments.
Gradle signing scheme update
apps/native/android/app/build.gradle
signingConfigs.release disables enableV1Signing and explicitly enables enableV2Signing, enableV3Signing, and enableV4Signing, replacing the prior v1+v2-only setup.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 Hopping through the semver fields,
A million-fold the version yields!
No more v1, we've shed that coat,
v2, v3, v4 afloat.
The rabbit signs the build with glee —
Major times a million, you see! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: APK signing updates (v3/v4 support) and versionCode widening, both tied to Phase 3 hardening.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch build/android-signing-versioncode

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.

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report for apps/web

Status Category Percentage Covered / Total
🔵 Lines 56.28% (🎯 54%) 6673 / 11856
🔵 Statements 54.9% (🎯 53%) 7121 / 12970
🔵 Functions 45.93% (🎯 45%) 1480 / 3222
🔵 Branches 46.64% (🎯 44%) 4002 / 8580
Generated in workflow #472 for commit d10b2de by the Vitest Coverage Report Action

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/native/scripts/sync.mjs (1)

20-23: ⚡ Quick win

Add explicit semver bounds/validation before computing versionCode.

This widened formula is still collision-prone when minor or patch reaches 1000+, and it also accepts NaN components silently. A small guard here prevents invalid or non-injective versionCode values from being written at Line 23.

Proposed patch
 const [major, minor, patch] = version.split('.').map(Number);
+if (![major, minor, patch].every(Number.isInteger)) {
+  throw new Error(`Invalid semver in package.json: "${version}"`);
+}
+if (major < 0 || minor < 0 || patch < 0) {
+  throw new Error(`Semver components must be non-negative: "${version}"`);
+}
+if (minor > 999 || patch > 999) {
+  throw new Error(
+    `minor/patch must be <= 999 for versionCode mapping safety: "${version}"`,
+  );
+}
 // versionCode = major*1000000 + minor*1000 + patch (matches android-release.yml).
 // Widened from *10000/*100, which collided at minor/patch >= 100; the new scheme
 // stays monotonically above already-released codes (v1.33.0 = 13300 < 1033000).
 const versionCode = major * 1000000 + minor * 1000 + patch;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/native/scripts/sync.mjs` around lines 20 - 23, The versionCode
calculation at line 23 lacks validation for the major, minor, and patch
components, which can lead to silent failures and collisions when minor or patch
values reach 1000 or higher. Add explicit bounds checking and validation before
computing versionCode to ensure that major, minor, and patch are valid numbers
(not NaN or undefined), that minor and patch do not exceed 999, and that any
validation failures throw an error or exit early with a descriptive message.
This prevents invalid or non-injective versionCode values from being silently
computed and written.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/native/scripts/sync.mjs`:
- Around line 20-23: The versionCode calculation at line 23 lacks validation for
the major, minor, and patch components, which can lead to silent failures and
collisions when minor or patch values reach 1000 or higher. Add explicit bounds
checking and validation before computing versionCode to ensure that major,
minor, and patch are valid numbers (not NaN or undefined), that minor and patch
do not exceed 999, and that any validation failures throw an error or exit early
with a descriptive message. This prevents invalid or non-injective versionCode
values from being silently computed and written.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 906013d5-f893-4f42-a35d-839870a00a08

📥 Commits

Reviewing files that changed from the base of the PR and between 130b380 and d10b2de.

📒 Files selected for processing (3)
  • .github/workflows/android-release.yml
  • apps/native/android/app/build.gradle
  • apps/native/scripts/sync.mjs

@RyRy79261 RyRy79261 merged commit 455cca3 into main Jun 20, 2026
24 checks passed
@RyRy79261 RyRy79261 deleted the build/android-signing-versioncode branch June 20, 2026 10:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant