Skip to content

Commit 6e0c31b

Browse files
antonisclaude
andcommitted
fix(android): resolve AGP variant data inside onVariants, not afterEvaluate
AGP Variant objects (outputs, applicationId, versionCode/versionName providers) are only valid inside the onVariants callback. Using them inside project.afterEvaluate{} can trigger late variant API access errors. Pre-extract all AGP-dependent data as plain values before registering the afterEvaluate block: - variantName (String) from v.name - variantApplicationId (String) from v.applicationId.get() - variantOutputsData (List<Map>) from v.outputs with all providers resolved Update extractCurrentVariants() to accept these plain values instead of the AGP Variant object so no AGP API is called outside onVariants. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 34b4c82 commit 6e0c31b

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

packages/core/sentry.gradle

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,20 @@ plugins.withId('com.android.application') {
7676
//
7777
// Capitalization: only the first character is upper-cased so that flavored variants
7878
// like "freeRelease" become "FreeRelease" (not "Freerelease" from Groovy capitalize()).
79-
def variantCapitalized = v.name.substring(0, 1).toUpperCase() + v.name.substring(1)
79+
// All AGP Variant API accesses (outputs, applicationId, versionCode/Name providers)
80+
// must happen here inside onVariants — the variant object is not valid after this
81+
// callback returns.
82+
def variantName = v.name
83+
def variantCapitalized = variantName.substring(0, 1).toUpperCase() + variantName.substring(1)
84+
def variantApplicationId = v.applicationId.get()
85+
def variantOutputsData = v.outputs.collect { output ->
86+
[baseName: output.baseName, versionCode: output.versionCode.getOrElse(0), versionName: output.versionName.getOrElse('')]
87+
}
8088
project.afterEvaluate {
8189
def sentryBundleTaskName = ["createBundle${variantCapitalized}JsAndAssets", "bundle${variantCapitalized}JsAndAssets"].find { tasks.names.contains(it) }
8290
if (sentryBundleTaskName == null) {
8391
project.logger.warn(
84-
"[sentry] No React Native bundle task found for variant '${v.name}'. " +
92+
"[sentry] No React Native bundle task found for variant '${variantName}'. " +
8593
"Expected 'createBundle${variantCapitalized}JsAndAssets' or " +
8694
"'bundle${variantCapitalized}JsAndAssets' — neither is registered. " +
8795
"Source maps will NOT be uploaded for this variant.")
@@ -111,7 +119,7 @@ plugins.withId('com.android.application') {
111119
// .findAll{!['class', 'active'].contains(it.key)}
112120
// .join('\n')
113121

114-
def currentVariants = extractCurrentVariants(bundleTask, v)
122+
def currentVariants = extractCurrentVariants(bundleTask, variantName, variantApplicationId, variantOutputsData)
115123
if (currentVariants == null || currentVariants.isEmpty()) return
116124

117125
def previousCliTask = null
@@ -516,7 +524,7 @@ def forceSourceMapOutputFromBundleTask(bundleTask) {
516524
}
517525

518526
/** compose array with one item - current build flavor name */
519-
static extractCurrentVariants(bundleTask, variant) {
527+
static extractCurrentVariants(bundleTask, String variantName, String applicationId, List outputsData) {
520528
// examples: bundleLocalReleaseJsAndAssets, createBundleYellowDebugJsAndAssets
521529
def pattern = Pattern.compile("(?:create)?(?:B|b)undle([A-Z][A-Za-z0-9_]+)JsAndAssets")
522530

@@ -529,15 +537,13 @@ static extractCurrentVariants(bundleTask, variant) {
529537
}
530538

531539
def currentVariants = null
532-
if (variant.name.equalsIgnoreCase(currentRelease)) {
540+
if (variantName.equalsIgnoreCase(currentRelease)) {
533541
currentVariants = [:]
534-
def variantName = variant.name
535-
variant.outputs.each { output ->
536-
def defaultVersionCode = output.versionCode.getOrElse(0)
542+
outputsData.each { output ->
543+
def defaultVersionCode = output.versionCode
537544
def versionCode = System.getenv('SENTRY_DIST') ?: defaultVersionCode
538-
def appId = variant.applicationId.get()
539-
def versionName = output.versionName.getOrElse('') // may be empty if not set
540-
def defaultReleaseName = "${appId}@${versionName}+${versionCode}"
545+
def versionName = output.versionName // may be empty if not set
546+
def defaultReleaseName = "${applicationId}@${versionName}+${versionCode}"
541547
def releaseName = System.getenv('SENTRY_RELEASE') ?: defaultReleaseName
542548

543549
def outputName = output.baseName

0 commit comments

Comments
 (0)