feat(android): support bundled JS in debug builds#350
Conversation
| @@ -46,4 +47,22 @@ object Utils { | |||
| fun isExpoProject(project: Project): Boolean { | |||
| return project.findProject(EXPO_PROJECT_LOCATOR) != null | |||
| } | |||
|
|
|||
| fun getBundledAssetsVariantName(variant: LibraryVariant): String { | |||
There was a problem hiding this comment.
This LibraryVariant API will be removed in AGP9. We already have another PR which reduces and refactors the usages of old API here.
I suggest to use the new API com.android.build.api.variant.LibraryVariant as the work in this function can be achieved with this newer API as well.
There was a problem hiding this comment.
Adjusted 👌 I kept the mapping logic, but removed the new dependency on deprecated com.android.build.gradle.api.LibraryVariant.
| val bundledAssetsVariantName = Utils.getBundledAssetsVariantName(variant) | ||
| val capitalizedBundledAssetsVariantName = bundledAssetsVariantName.capitalized() | ||
|
|
||
| if (bundledAssetsVariantName != variant.name || capitalizedVariantName.contains("Release")) { |
There was a problem hiding this comment.
Can you explain why we need to introduce bundledAssetsVariantName ? I am thinking that maybe we can remove the if-statement and have this run for both debug and release build types. Since the scope of this PR suggests to have JS Bundle in debug build as well, we can perhaps safely remove the if-statement.
There was a problem hiding this comment.
Applied this simplification.
The important part is not whether the current variant is debug or release, but which variant should provide the bundled assets. For debuggable variants that is the sibling release variant; for non-debuggable variants it is the variant itself.
So VariantProcessor now always depends on the mapped createBundle...JsAndAssets task. That is simpler and also covers custom non-debuggable build types better than the previous conditional.
| "createBundle${capitalizedVariantName}JsAndAssets", | ||
| "createBundle${capitalizedBundledAssetsVariantName}JsAndAssets", | ||
| // outputs for RN >= 0.82 | ||
| "react/${variant.name}", | ||
| "react/$bundledAssetsVariantName", |
There was a problem hiding this comment.
I am not sure whether we need this change. See the context below
|
From my end, same comments as from @hurali97 |
There was a problem hiding this comment.
Pull request overview
This PR fixes non-deterministic Android debug AAR packaging in the brownfield Gradle plugin by ensuring debug (and other debuggable) library variants consume bundled JS/assets produced by their corresponding release variant, and by explicitly wiring the required bundle tasks into the debug build graph.
Changes:
- Introduces a helper to map a debuggable variant name to the corresponding release bundle-producing variant (e.g.,
debug -> release,freeDebug -> freeRelease). - Updates library variant pre-build dependencies so debug AAR assembly runs the mapped release JS/assets bundling task (and Expo updates resources task when applicable).
- Updates Android source set wiring so debug variants pick up generated assets/resources from the mapped release outputs (supporting both RN <= 0.81 and RN >= 0.82 output layouts).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Utils.kt | Adds variant-name mapping utility to select the correct bundle-producing variant for debuggable builds. |
| gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/VariantProcessor.kt | Makes pre<Variant>Build depend on the mapped release createBundle*JsAndAssets (and Expo resources) tasks so clean debug packaging is deterministic. |
| gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/plugin/RNSourceSets.kt | Rewires debug variant source sets to read JS/assets/res from the mapped release-generated output directories. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
Fixes Android debug AAR packaging so a clean
brownfield package:android --variant debugbuild embeds the JavaScript bundle instead of depending on stale outputs from a prior release build.Root cause
Android debug packaging was not deterministic from a clean build.
The brownfield plugin correctly guarded React Native bundling so it only ran for release variants, but debug AAR assembly still expected the generated JS/assets to already exist. In practice this meant debug packaging only appeared to work when a previous release build had already left
index.android.bundlebehind.What changed
debug -> releasefreeDebug -> freeReleaseValidation
yarn brownfield:plugin:publish:localcd apps/RNApp/android && ./gradlew -p BrownfieldLib cleancd apps/RNApp && yarn exec brownfield package:android --module-name :BrownfieldLib --variant debug:app:createBundleReleaseJsAndAssetsassets/index.android.bundleImpact
Debug AARs built from a clean checkout are now self-sufficient at the packaging layer. This removes the accidental dependency on a prior release build and is the prerequisite for running Android brownfield consumers without Metro in debug packaging flows.