ci(release): couple native releases to the production OTA lane - #2806
Conversation
A store build whose versionName outruns the newest production Capgo bundle strands its whole fleet: disable_auto_update_under_native makes every device on the new binary refuse all existing bundles, silently (TASK-21793 — 102 devices refused OTA for a month while CI stayed green, because internal builds shipped 1.0.53 over bundle 1.0.51). android-release.yml / ios-release.yml now resolve the versionName up front, read the production channel's current bundle before the build, and — when the binary would leapfrog it — publish the release's own static export under the binary's versionName after the store upload, then assert the channel actually serves it. A native release can no longer outrun the OTA lane; if the publish fails, the job goes red instead of the fleet going dark. scripts/semver-newer.mjs does the prerelease-aware comparison (sort -V gets 1.0.54 vs 1.0.54-hotfix1 backwards, which is exactly the case that matters here).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@coderabbitai review |
|
Warning Review limit reached
On-demand reviews are free for the next 27 days. After that, they cost $0.25 per reviewed file. Or wait 53 minutes for your next included review. View limit detailsLimit details: You’ve used all 2 included reviews currently available. Your 53 included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Action performedReview triggered.
|
🧪 UI test report — ✅ all greenSuites
📊 Coverage (unit)
⏱ 10 slowest test cases
|
Code-analysis diffPainscore total: 7334.68 → 7334.68 (0) |
|
|
Decision: merge this PR. The mechanism is right — a native release that would leapfrog the production bundle now publishes its own One thing this PR does not cover that we need before the next native build: bump Why: Follow-ups, not merge gates: gate the auto-publish on |
TASK-21793. Follow-up to #2795 (which fixed the silent-no-op bug class for the dev→staging lane and predicted this incident in its own PR body).
The incident
Internal store builds shipped with versionName 1.0.53 while the newest production OTA bundle was 1.0.51. Capgo's
disable_auto_update_under_nativerule rejects any bundle sorting below the installed native version, so every device on the new binaries refused all existing bundles — OTA silently dead for the whole beta fleet (102 devices / 1,002 refusal events in 30 days; 26 devices stuck on July-29 JS), with green CI throughout. The immediate remediation (ota-1.0.54on the 08-21 build commit) already shipped; this PR makes the failure class impossible to repeat silently.Changes
android-release.yml/ios-release.yml— three new pieces, kept in lockstep across the two platforms:channel currentBundle productionfrom Capgo and compare against the versionName withscripts/semver-newer.mjs. Unreadable channel or unparseable version fails the job — a binary that may strand the fleet does not ship on a guess.out/(the exact JS baked into the binary) under the binary's versionName, then assert the channel actually serves it. The lanes can no longer drift apart; a failed publish turns the job red instead of the fleet going dark. Both platforms publishing the same version from the same tag is a verified no-op via--version-exists-ok.scripts/semver-newer.mjs— prerelease-aware "sorts strictly above" comparison.sort -Vgets the case that matters here backwards:1.0.54-hotfix1sorts below1.0.54in semver (and in Capgo's on-device check), above it in GNU version sort. Fails loudly on unusable input so abash -estep dies rather than misreading an error as "false".capgo-deploy.yml/docs/NATIVE-RELEASE.md— the "production OTA fires on anota-*tag and nothing else" design notes now document this one deliberate exception.Task items covered elsewhere
ota-*lane: already live — fix(capgo): give every OTA upload a unique bundle version #2795's "Verify channel serves the new bundle" step merged unconditional (no channel guard), so it ran on theota-1.0.54remediation deploy. No change needed.disable_auto_update_under_nativeand the Capgo channel update-policy check are ops-side, tracked in TASK-21793.Verification
semver-newer.mjs(plain/prerelease ordering incl. numeric identifiers, loud failure on unusable input); fullscripts/__tests__suite green (35 tests).bash -efor all four paths: ahead → publish, covered → skip, unreadable channel → red, unparseable version → red.prettier --checkclean on every touched file.