fix(android): AAB upload + exclude x86 from release to fix 100 MB APK limit (#3783)#3784
Merged
Conversation
The play_store_upload lane uploaded five APKs including the universal APK
(~240 MB), which exceeds Google Play's hard 100 MB single-APK limit and
failed the whole upload edit:
Google Api Error: Invalid request - APK of size 251620080 is too large.
Build an Android App Bundle (AAB) and upload that to Play instead. Play
generates/signs optimized per-device APKs server-side, so the single-APK
ceiling no longer applies. The build lane still runs `assemble`, so the
universal/split APKs remain available to e2e (BrowserStack), Huawei
AppGallery, and the GCS archive. The old multi-APK upload is kept
commented out and flagged as legacy.
Closes #3783
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Real Android devices are ARM-only; x86/x86_64 exist only for emulators. Strip them from release builds to shrink the Play AAB and the universal APK consumed by Huawei + BrowserStack. - build.gradle: ndk.abiFilters on the release buildType (hard packaging guarantee; strips x86 even from 3rd-party prebuilt .so) - Fastfile: reactNativeArchitectures=armeabi-v7a,arm64-v8a on the release assemble+bundle lanes (skips compiling x86 native libs, drops the orphan x86 split APKs) - ci/tasks/build.sh: post-build guard fails the release if the AAB or universal APK ships any lib/x86 Debug builds keep all 4 ABIs for emulator e2e (Detox Pixel_API_34, Appium generic_x86). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
esaugomez31
approved these changes
May 28, 2026
Contributor
Author
|
Fix: blinkbitcoin/blink-mobile-deployments#496 — adds Ordering note: the current latest prod build (v2.4.46) predates this PR (still has x86 splits, no AAB in GCS), so a green Play deploy needs: merge #496 → run a fresh prod-build on current |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related Android release-distribution fixes:
Switch the Play Store upload from multi-APK to an Android App Bundle (AAB) — the universal APK (~240 MB) exceeds Google Play's hard 100 MB single-APK limit:
Play generates and signs optimized per-device APKs server-side from the AAB, so the single-APK ceiling no longer applies and users get smaller downloads.
Exclude x86 / x86_64 from release builds — those ABIs exist only for emulators; every real Android device is ARM. Dropping them shrinks the AAB and the universal APK (240 MB → 119 MB) and removes dead weight from what ships. A CI guard prevents silent re-introduction.
Closes #3783.
Changes
android/fastlane/Fastfilebuildlane: addgradle(task: "bundle", build_type: "Release")to produceapp/build/outputs/bundle/release/app-release.aab. The existingassemblestep is kept, so the universal/split APKs are still built (see below).buildlane: passreactNativeArchitectures = "armeabi-v7a,arm64-v8a"to the releaseassemble+bundlegradle calls. This skips compiling the unused x86 native libs (faster CI) and stops emitting the orphanapp-x86*-release.apksplit APKs.play_store_uploadlane: uploadaab:instead ofapk_paths:. The old multi-APK call is kept commented out and flagged as legacy for reference, with an inline rationale.android/app/build.gradlendk { abiFilters "armeabi-v7a", "arm64-v8a" }to thereleasebuildType. This is the hard packaging guarantee: it strips x86 from the universal APK and the AAB even if a third-party AAR ships prebuilt x86.so— something thereactNativeArchitecturesproperty alone cannot catch.debugis untouched, so it keeps all 4 ABIs for emulator e2e.ci/tasks/build.shapp-release.aaborapp-universal-release.apkcontains anylib/x86. It piggybacks on the build that already runs (≈ twounzip | greps), and guards against a silent regression — e.g.abiFiltersdropped, x86 re-added toreactNativeArchitectures, or the legacyapk_pathsupload re-enabled — quietly putting x86 back into the Play AAB.Why the APKs are still built
The universal/split APKs are consumed elsewhere and must not be removed:
ci/tasks/e2e-test-android.sh:21ci/pipeline.ymlhuawei_store_upload) uploads the universal APKci/tasks/build.shalready copies all ofapp/build/outputs/*, so the AAB is archived to GCS automatically — no extra copy step needed.Why x86 exclusion is scoped to release only
x86/x86_64 are exactly what the emulator-based e2e tests need, and they load the debug APK:
e2e/config/wdio.conf.js— Appium ongeneric_x86, loadsapp-universal-debug.apk.detoxrc.js— Detox on thePixel_API_34AVD (x86_64), loadsapp-universal-debug.apkThe release artifacts all run on ARM hardware (Play devices, Huawei devices, BrowserStack real devices), so they don't need x86. Debug builds are left with all 4 ABIs, so emulator e2e is unaffected.
Verification
Ran a real local release build (
assembleRelease+bundleRelease, RN 0.76.9, new arch on) and inspected thelib/ABIs of every artifact withunzip -l:app-release.aabarm64-v8a,armeabi-v7aapp-universal-release.apk(119 MB)arm64-v8a,armeabi-v7aapp-arm64-v8a-release.apkarm64-v8aapp-armeabi-v7a-release.apkarmeabi-v7aapp-x86-release.apkapp-x86_64-release.apkreactNativeArchitecturesarm-only, no x86 split APKs are produced at all.base/lib/x86/,base/lib/x86_64/, andlib/x86/while allowingarm64-v8a/armeabi-v7a.Notes / follow-ups for the maintainer
abi == null, so it skips the per-ABI× 10_000_000multiplier the split APKs use). Google Play version codes are permanent. Since the oversized-APK upload has been failing and rolling the whole edit back, those inflated codes were most likely never registered and the plain code should be free. Please confirm the highest internal-track versionCode in the Play Console is below the AAB's base code before the first AAB upload; if not, bumpbuild-number-android(ops action, no code change).build.gradleis now obsolete for Play (those APKs no longer go there). Retiring it in favor of a single monotonic versionCode is good future cleanup but is intentionally out of scope here.Acceptance criteria
app/build/outputs/bundle/release/app-release.aabplay_store_uploaduploads the.aab(noapk_paths)lib/x86)lib/x86in the AAB/universal APKpromote_to_*,public_phased_percent) unchanged — they promote tracks only, upload no binary🤖 Generated with Claude Code