build(android): v3/v4 APK signing + widen versionCode (Phase 3 hardening)#252
Conversation
…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.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe PR widens the Android ChangesAndroid Release Configuration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
Coverage Report for apps/web
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/native/scripts/sync.mjs (1)
20-23: ⚡ Quick winAdd explicit semver bounds/validation before computing
versionCode.This widened formula is still collision-prone when
minororpatchreaches1000+, and it also acceptsNaNcomponents silently. A small guard here prevents invalid or non-injectiveversionCodevalues 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
📒 Files selected for processing (3)
.github/workflows/android-release.ymlapps/native/android/app/build.gradleapps/native/scripts/sync.mjs
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.
assetlinks.json) is unaffected.versionCode overflow widening
major*10000 + minor*100 + patchcollides at minor/patch ≥ 100 (e.g.1.100.0==2.0.0). Widened tomajor*1000000 + minor*1000 + patch.apps/native/scripts/sync.mjs(writesversion.properties, whichbuild.gradlereads) and the currently-unused mirror inandroid-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