Skip to content
Merged
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,32 @@ fun ApplicationAndroidComponentsExtension.configure(
tmpDir.mkdirs()

onVariants { variant ->
// Validate distribution configuration for this variant
val updateSdkVariants = extension.distribution.updateSdkVariants.get()
val variantName = variant.name

if (updateSdkVariants.contains(variantName)) {
val isVariantAllowed =
isVariantAllowed(extension, variant.name, variant.flavorName, variant.buildType)

// Check if updateSdkVariants contains a variant that is ignored
if (!isVariantAllowed) {
throw IllegalArgumentException(
"Invalid configuration: updateSdkVariants contains variant '$variantName' which is in ignoredVariants. " +
"You cannot use the auto-update SDK in variants where the Sentry SDK is disabled."
)
}

// Check if updateSdkVariants is set but distribution uploads are disabled
val distributionEnabled = extension.distribution.enabled.get()
if (!distributionEnabled) {
throw IllegalArgumentException(
"Invalid configuration: updateSdkVariants contains variant '$variantName' but buildDistribution.enabled is false. " +
"It doesn't make sense to embed the auto-update SDK without uploading the build."
)
}
}

if (isVariantAllowed(extension, variant.name, variant.flavorName, variant.buildType)) {
val paths = OutputPaths(project, variant.name)
val sentryTelemetryProvider =
Expand Down Expand Up @@ -230,7 +256,7 @@ fun ApplicationAndroidComponentsExtension.configure(
.toTransform(SingleArtifact.MERGED_MANIFEST)
}
val sizeAnalysisEnabled = extension.sizeAnalysis.enabled.get() == true
val distributionEnabled = extension.distribution.enabledVariants.get().contains(variant.name)
val distributionEnabled = extension.distribution.enabled.get() == true
if (sizeAnalysisEnabled || distributionEnabled) {
variant.configureUploadAppTasks(
project,
Expand Down Expand Up @@ -396,11 +422,13 @@ private fun ApplicationVariant.configureDistributionPropertiesTask(
sentryProject: String?,
): TaskProvider<GenerateDistributionPropertiesTask>? {
val variantName = name
if (extension.distribution.enabledVariants.get().contains(variantName)) {
val updateSdkVariants = extension.distribution.updateSdkVariants.get()

if (updateSdkVariants.contains(variantName)) {
val variant = AndroidVariant74(this)
// Distribution uses a custom auto-install implementation instead of the standard
// InstallStrategy approach (see AutoInstall.kt) because it requires variant-specific
// installation based on extension.distribution.enabledVariants, whereas other integrations
// installation based on extension.distribution.updateSdkVariants, whereas other integrations
// are installed globally when their dependencies are detected.
if (extension.autoInstallation.enabled.get()) {
val sentryVersion = extension.autoInstallation.sentryVersion.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal const val SENTRY_GROUP = "io.sentry"
// Note: sentry-android-distribution is not included here because it requires variant-specific
// installation logic. Unlike other integrations that are installed globally when their
// dependencies are detected, distribution must be installed per-variant based on
// extension.distribution.enabledVariants. See
// extension.distribution.updateSdkVariants. See
// AndroidComponentsConfig.configureDistributionPropertiesTask.
private val strategies =
listOf(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
package io.sentry.android.gradle.extensions

import io.sentry.android.gradle.util.CiUtils.isCi
import javax.inject.Inject
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.provider.SetProperty
import org.jetbrains.annotations.ApiStatus.Experimental

@Experimental
open class DistributionExtension @Inject constructor(objects: ObjectFactory) {
open class DistributionExtension
@Inject
constructor(objects: ObjectFactory, providerFactory: ProviderFactory) {

/**
* Set of Android build variants that should have distribution enabled.
* Controls whether build distribution uploads are enabled.
*
* Note: The global ignore settings (ignoredVariants, ignoredBuildTypes, ignoredFlavors) have no
* relation to distribution and do not affect which variants are enabled here.
* Defaults to false.
*/
val enabledVariants: SetProperty<String> =
val enabled: Property<Boolean> =
objects.property(Boolean::class.java).convention(providerFactory.isCi() && false)

/**
* Set of Android build variants that should have the auto-update SDK added and auth token
* embedded.
*
* This must be a subset of variants not in ignoredVariants. It is a build-time error to specify a
* variant that is ignored by the Sentry plugin.
*
* Note: This controls auto-update SDK installation only. The [enabled] property controls whether
* builds are uploaded for distribution.
*/
val updateSdkVariants: SetProperty<String> =
objects.setProperty(String::class.java).convention(emptySet())

/** Auth token used for distribution operations. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,47 @@
package io.sentry.android.gradle.extensions

import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
import org.gradle.testfixtures.ProjectBuilder
import org.junit.Test

class DistributionExtensionTest {

@Test
fun `enabledVariants is empty by default`() {
fun `enabled is false by default`() {
val project = ProjectBuilder.builder().build()
val extension = project.objects.newInstance(DistributionExtension::class.java)

assertTrue(extension.enabledVariants.get().isEmpty())
assertFalse(extension.enabled.get())
}

@Test
fun `enabledVariants can be configured with variant names`() {
fun `enabled can be configured`() {
val project = ProjectBuilder.builder().build()
val extension = project.objects.newInstance(DistributionExtension::class.java)

extension.enabledVariants.set(setOf("freeDebug", "paidRelease"))
extension.enabled.set(true)

assertEquals(setOf("freeDebug", "paidRelease"), extension.enabledVariants.get())
assertTrue(extension.enabled.get())
}

@Test
fun `updateSdkVariants is empty by default`() {
val project = ProjectBuilder.builder().build()
val extension = project.objects.newInstance(DistributionExtension::class.java)

assertTrue(extension.updateSdkVariants.get().isEmpty())
}

@Test
fun `updateSdkVariants can be configured with variant names`() {
val project = ProjectBuilder.builder().build()
val extension = project.objects.newInstance(DistributionExtension::class.java)

extension.updateSdkVariants.set(setOf("freeDebug", "paidRelease"))

assertEquals(setOf("freeDebug", "paidRelease"), extension.updateSdkVariants.get())
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,8 @@ class SentryPluginAutoInstallTest :
includeProguardMapping = false
autoInstallation.enabled = true
distribution {
enabledVariants = ["debug"]
enabled = true
updateSdkVariants = ["debug"]
}
}
"""
Expand Down Expand Up @@ -483,7 +484,8 @@ class SentryPluginAutoInstallTest :
includeProguardMapping = false
autoInstallation.enabled = false
distribution {
enabledVariants = ["debug"]
enabled = true
updateSdkVariants = ["debug"]
}
}
"""
Expand Down
Loading