Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions packages/core/sentry.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,37 @@ tasks.register("cleanupTemporarySentryJsonConfiguration") {
plugins.withId('com.android.application') {
def androidComponents = extensions.getByName("androidComponents")

// Collect ApplicationVariant objects in onVariants - do NOT access tasks here.
// Calling tasks.findAll or tasks.matching{}.each{} inside onVariants forces task realization
// during AGP's variant configuration phase, which disrupts the Artifacts API
// transform chain used by other plugins (e.g. those calling
// variant.artifacts.use(...).toTransform(SingleArtifact.APK)). The result is
// that those plugins' APK output ends up in build/intermediates/ instead of
// build/outputs/, causing downstream tooling to fail to locate the final APK.
def releaseVariants = []
androidComponents.onVariants(androidComponents.selector().all()) { v ->
if (!v.name.toLowerCase().contains("debug")) {
releaseVariants << v
}
}

// All task-level operations must happen in afterEvaluate, not inside onVariants.
// By the time afterEvaluate runs, all plugins have registered their onVariants
// callbacks and the AGP Artifacts API transform chain is fully established.
project.afterEvaluate {
if (releaseVariants.isEmpty()) {
project.logger.warn("[sentry] No release variants collected, onVariants may have run after afterEvaluate. Sourcemap upload tasks will not be registered.")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misleading warning for projects with only debug variants

Low Severity

The warning assumes releaseVariants is empty because onVariants ran after afterEvaluate, but it could also be empty because the project legitimately has no release variants (only debug). The warning message "onVariants may have run after afterEvaluate" is misleading in this case and could confuse developers working on debug-only configurations or sample projects. The code cannot distinguish between timing issues and the legitimate absence of release variants.

Fix in Cursor Fix in Web

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This warning is inaccurate. It should not be possible for onVariants to have been invoked afterEvaluate as it is called when the plugin is applied, which should not be in or after afterEvaluate in this case. Though it could indicate no release variants configured, as the AI review stated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wdyt of simplifying the message to [sentry] No release variants found. Source map upload tasks will not be registered.?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds great. The one you've got in #5714 looks good too!

}
releaseVariants.each { v ->
// separately we then hook into the bundle task of react native to inject
// sourcemap generation parameters. In case for whatever reason no release
// was found for the asset folder we just bail.
def bundleTasks = tasks.findAll { task -> (task.name.startsWith("createBundle") || task.name.startsWith("bundle")) && task.name.endsWith("JsAndAssets") && !task.name.contains("Debug") && task.enabled }
bundleTasks.each { bundleTask ->
tasks.matching { task ->
(task.name.startsWith("createBundle") || task.name.startsWith("bundle")) &&
task.name.endsWith("JsAndAssets") &&
!task.name.contains("Debug")
}.each { bundleTask ->
if (!bundleTask.enabled) return
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inefficient nested loop processes each bundle task multiple times

Medium Severity

The nested loop structure iterates over all release variants in the outer loop and all bundle tasks in the inner loop, causing each bundle task to be processed N times (once per variant). Lines 98-112 execute for every (variant, bundleTask) combination, but extractCurrentVariants only returns non-null for one matching variant per bundle task. This means (N-1)×M iterations do unnecessary work (extracting task properties, calling forceSourceMapOutputFromBundleTask) before returning early on line 122. The loops should be restructured to process each bundle task once with its matching variant.

Fix in Cursor Fix in Web

def shouldCleanUp
def sourcemapOutput
def bundleOutput
Expand All @@ -95,7 +119,7 @@ plugins.withId('com.android.application') {
// .join('\n')

def currentVariants = extractCurrentVariants(bundleTask, v)
if (currentVariants == null) return
if (currentVariants == null || currentVariants.isEmpty()) return

def previousCliTask = null
def applicationVariant = null
Expand Down Expand Up @@ -304,9 +328,10 @@ plugins.withId('com.android.application') {
previousCliTask.configure { finalizedBy cliCleanUpTask }

def packageTasks = tasks.matching {
task -> ("package${applicationVariant}".equalsIgnoreCase(task.name) || "package${applicationVariant}Bundle".equalsIgnoreCase(task.name)) && task.enabled
task -> ("package${applicationVariant}".equalsIgnoreCase(task.name) || "package${applicationVariant}Bundle".equalsIgnoreCase(task.name))
}
packageTasks.configureEach { packageTask ->
if (!packageTask.enabled) return
packageTask.dependsOn modulesTask
packageTask.finalizedBy modulesCleanUpTask
}
Expand Down
Loading