From 6fe218d7e67d40e16001581c4a458a3312cb7ad1 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 6 Oct 2025 11:17:08 +0200 Subject: [PATCH 1/6] Add GenerateDistributionPropertiesTask for distribution options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements EME-397 by adding a Gradle task to generate distribution properties that will be bundled into the app and read by the SDK. The task generates sentry-distribution.properties with: - io.sentry.distribution.org-slug - io.sentry.distribution.project-slug - io.sentry.distribution.org-auth-token - io.sentry.distribution.build-configuration Values are sourced from the existing SentryPluginExtension (org, projectName, authToken) and the variant's build type. The task only runs for variants enabled in distribution.enabledVariants. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../android/gradle/AndroidComponentsConfig.kt | 30 ++++ .../gradle/sourcecontext/OutputPaths.kt | 1 + .../GenerateDistributionPropertiesTask.kt | 87 +++++++++ .../GenerateDistributionPropertiesTaskTest.kt | 165 ++++++++++++++++++ 4 files changed, 283 insertions(+) create mode 100644 plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt create mode 100644 plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt diff --git a/plugin-build/src/main/kotlin/io/sentry/android/gradle/AndroidComponentsConfig.kt b/plugin-build/src/main/kotlin/io/sentry/android/gradle/AndroidComponentsConfig.kt index 5bc3bda96..745105f50 100644 --- a/plugin-build/src/main/kotlin/io/sentry/android/gradle/AndroidComponentsConfig.kt +++ b/plugin-build/src/main/kotlin/io/sentry/android/gradle/AndroidComponentsConfig.kt @@ -22,6 +22,7 @@ import io.sentry.android.gradle.instrumentation.SpanAddingClassVisitorFactory import io.sentry.android.gradle.services.SentryModulesService import io.sentry.android.gradle.sourcecontext.OutputPaths import io.sentry.android.gradle.sourcecontext.SourceContext +import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask import io.sentry.android.gradle.tasks.InjectSentryMetaPropertiesIntoAssetsTask import io.sentry.android.gradle.tasks.PropertiesFileOutputTask import io.sentry.android.gradle.tasks.SentryGenerateIntegrationListTask @@ -103,6 +104,15 @@ fun ApplicationAndroidComponentsExtension.configure( ) generateProguardUuidTask?.let { tasksGeneratingProperties.add(it) } + val generateDistributionPropertiesTask = + variant.configureDistributionPropertiesTask( + project, + extension, + sentryTelemetryProvider, + paths, + ) + generateDistributionPropertiesTask?.let { tasksGeneratingProperties.add(it) } + sentryVariant.configureNativeSymbolsTask( project, extension, @@ -372,6 +382,26 @@ private fun ApplicationVariant.configureProguardMappingsTasks( } } +private fun ApplicationVariant.configureDistributionPropertiesTask( + project: Project, + extension: SentryPluginExtension, + sentryTelemetryProvider: Provider, + paths: OutputPaths, +): TaskProvider? { + val variantName = name + if (extension.distribution.enabledVariants.get().contains(variantName)) { + return GenerateDistributionPropertiesTask.register( + project = project, + extension = extension, + sentryTelemetryProvider = sentryTelemetryProvider, + output = paths.distributionPropertiesDir, + buildConfiguration = buildType ?: "unknown", + taskSuffix = name.capitalized, + ) + } + return null +} + /** * Configure the upload AAB and APK tasks and set them up as finalizers on the respective producer * tasks diff --git a/plugin-build/src/main/kotlin/io/sentry/android/gradle/sourcecontext/OutputPaths.kt b/plugin-build/src/main/kotlin/io/sentry/android/gradle/sourcecontext/OutputPaths.kt index 31f46387f..83298cfcc 100644 --- a/plugin-build/src/main/kotlin/io/sentry/android/gradle/sourcecontext/OutputPaths.kt +++ b/plugin-build/src/main/kotlin/io/sentry/android/gradle/sourcecontext/OutputPaths.kt @@ -15,4 +15,5 @@ class OutputPaths(private val project: Project, variantName: String) { val bundleIdDir = dir("$variantDirectory/bundle-id") val sourceDir = dir("$variantDirectory/source-to-bundle") val bundleDir = dir("$variantDirectory/source-bundle") + val distributionPropertiesDir = dir("$variantDirectory/distribution-properties") } diff --git a/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt b/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt new file mode 100644 index 000000000..7ed63dcd0 --- /dev/null +++ b/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt @@ -0,0 +1,87 @@ +package io.sentry.android.gradle.tasks + +import io.sentry.android.gradle.extensions.SentryPluginExtension +import io.sentry.android.gradle.telemetry.SentryTelemetryService +import io.sentry.android.gradle.telemetry.withSentryTelemetry +import io.sentry.android.gradle.util.info +import org.gradle.api.Project +import org.gradle.api.file.Directory +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.TaskProvider +import org.gradle.work.DisableCachingByDefault + +@DisableCachingByDefault +abstract class GenerateDistributionPropertiesTask : PropertiesFileOutputTask() { + + init { + description = "Generates distribution properties for Sentry" + } + + @get:Internal + override val outputFile: Provider + get() = output.file(SENTRY_DISTRIBUTION_OUTPUT) + + @get:Input @get:Optional abstract val orgSlug: Property + + @get:Input @get:Optional abstract val projectSlug: Property + + @get:Input @get:Optional abstract val orgAuthToken: Property + + @get:Input abstract val buildConfiguration: Property + + @TaskAction + fun generateProperties() { + val outputDir = output.get().asFile + outputDir.mkdirs() + + outputFile.get().asFile.writer().use { writer -> + orgSlug.orNull?.let { writer.appendLine("$ORG_SLUG_PROPERTY=$it") } + projectSlug.orNull?.let { writer.appendLine("$PROJECT_SLUG_PROPERTY=$it") } + orgAuthToken.orNull?.let { writer.appendLine("$ORG_AUTH_TOKEN_PROPERTY=$it") } + writer.appendLine("$BUILD_CONFIGURATION_PROPERTY=${buildConfiguration.get()}") + } + + logger.info { + "GenerateDistributionPropertiesTask - outputFile: $outputFile, " + + "orgSlug: ${orgSlug.orNull}, " + + "projectSlug: ${projectSlug.orNull}, " + + "buildConfiguration: ${buildConfiguration.get()}" + } + } + + companion object { + internal const val SENTRY_DISTRIBUTION_OUTPUT = "sentry-distribution.properties" + const val ORG_SLUG_PROPERTY = "io.sentry.distribution.org-slug" + const val PROJECT_SLUG_PROPERTY = "io.sentry.distribution.project-slug" + const val ORG_AUTH_TOKEN_PROPERTY = "io.sentry.distribution.org-auth-token" + const val BUILD_CONFIGURATION_PROPERTY = "io.sentry.distribution.build-configuration" + + fun register( + project: Project, + extension: SentryPluginExtension, + sentryTelemetryProvider: Provider?, + output: Provider? = null, + buildConfiguration: String, + taskSuffix: String = "", + ): TaskProvider { + return project.tasks.register( + "generateSentryDistributionProperties$taskSuffix", + GenerateDistributionPropertiesTask::class.java, + ) { task -> + output?.let { task.output.set(it) } + task.withSentryTelemetry(extension, sentryTelemetryProvider) + task.orgSlug.set(extension.org) + task.projectSlug.set(extension.projectName) + task.orgAuthToken.set(extension.authToken) + task.buildConfiguration.set(buildConfiguration) + task.outputs.upToDateWhen { false } + } + } + } +} diff --git a/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt b/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt new file mode 100644 index 000000000..c91eaac9e --- /dev/null +++ b/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt @@ -0,0 +1,165 @@ +package io.sentry.android.gradle.tasks + +import io.sentry.android.gradle.extensions.SentryPluginExtension +import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.BUILD_CONFIGURATION_PROPERTY +import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.ORG_AUTH_TOKEN_PROPERTY +import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.ORG_SLUG_PROPERTY +import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.PROJECT_SLUG_PROPERTY +import io.sentry.android.gradle.util.PropertiesUtil +import java.io.File +import kotlin.test.assertEquals +import kotlin.test.assertNull +import kotlin.test.assertTrue +import org.gradle.api.Project +import org.gradle.api.tasks.TaskProvider +import org.gradle.testfixtures.ProjectBuilder +import org.junit.Test + +class GenerateDistributionPropertiesTaskTest { + + @Test + fun `generate distribution properties with all fields`() { + val project = createProject() + val extension = project.extensions.findByName("sentry") as SentryPluginExtension + extension.org.set("test-org") + extension.projectName.set("test-project") + extension.authToken.set("test-token") + + val task: TaskProvider = + GenerateDistributionPropertiesTask.register( + project, + extension, + null, + project.layout.buildDirectory.dir("dummy/folder/"), + "debug", + "test", + ) + + task.get().generateProperties() + + val expectedFile = File(project.buildDir, "dummy/folder/sentry-distribution.properties") + assertTrue(expectedFile.exists()) + + val props = PropertiesUtil.load(expectedFile) + assertEquals("test-org", props.getProperty(ORG_SLUG_PROPERTY)) + assertEquals("test-project", props.getProperty(PROJECT_SLUG_PROPERTY)) + assertEquals("test-token", props.getProperty(ORG_AUTH_TOKEN_PROPERTY)) + assertEquals("debug", props.getProperty(BUILD_CONFIGURATION_PROPERTY)) + } + + @Test + fun `generate distribution properties with only build configuration`() { + val project = createProject() + val extension = project.extensions.findByName("sentry") as SentryPluginExtension + + val task: TaskProvider = + GenerateDistributionPropertiesTask.register( + project, + extension, + null, + project.layout.buildDirectory.dir("dummy/folder/"), + "release", + "test", + ) + + task.get().generateProperties() + + val expectedFile = File(project.buildDir, "dummy/folder/sentry-distribution.properties") + assertTrue(expectedFile.exists()) + + val props = PropertiesUtil.load(expectedFile) + assertNull(props.getProperty(ORG_SLUG_PROPERTY)) + assertNull(props.getProperty(PROJECT_SLUG_PROPERTY)) + assertNull(props.getProperty(ORG_AUTH_TOKEN_PROPERTY)) + assertEquals("release", props.getProperty(BUILD_CONFIGURATION_PROPERTY)) + } + + @Test + fun `generate distribution properties overrides on subsequent calls`() { + val project = createProject() + val extension = project.extensions.findByName("sentry") as SentryPluginExtension + extension.org.set("test-org-1") + extension.projectName.set("test-project-1") + extension.authToken.set("test-token-1") + + val task: TaskProvider = + GenerateDistributionPropertiesTask.register( + project, + extension, + null, + project.layout.buildDirectory.dir("dummy/folder/"), + "debug", + "test", + ) + + task.get().generateProperties() + + val expectedFile = File(project.buildDir, "dummy/folder/sentry-distribution.properties") + assertTrue(expectedFile.exists()) + + val props1 = PropertiesUtil.load(expectedFile) + assertEquals("test-org-1", props1.getProperty(ORG_SLUG_PROPERTY)) + assertEquals("test-project-1", props1.getProperty(PROJECT_SLUG_PROPERTY)) + assertEquals("test-token-1", props1.getProperty(ORG_AUTH_TOKEN_PROPERTY)) + + extension.org.set("test-org-2") + extension.projectName.set("test-project-2") + extension.authToken.set("test-token-2") + + task.get().generateProperties() + + val props2 = PropertiesUtil.load(expectedFile) + assertEquals("test-org-2", props2.getProperty(ORG_SLUG_PROPERTY)) + assertEquals("test-project-2", props2.getProperty(PROJECT_SLUG_PROPERTY)) + assertEquals("test-token-2", props2.getProperty(ORG_AUTH_TOKEN_PROPERTY)) + } + + @Test + fun `generate distribution properties for different build configurations`() { + val project = createProject() + val extension = project.extensions.findByName("sentry") as SentryPluginExtension + extension.org.set("test-org") + + val debugTask: TaskProvider = + GenerateDistributionPropertiesTask.register( + project, + extension, + null, + project.layout.buildDirectory.dir("dummy/debug/"), + "debug", + "Debug", + ) + + val releaseTask: TaskProvider = + GenerateDistributionPropertiesTask.register( + project, + extension, + null, + project.layout.buildDirectory.dir("dummy/release/"), + "release", + "Release", + ) + + debugTask.get().generateProperties() + releaseTask.get().generateProperties() + + val debugFile = File(project.buildDir, "dummy/debug/sentry-distribution.properties") + val releaseFile = File(project.buildDir, "dummy/release/sentry-distribution.properties") + + assertTrue(debugFile.exists()) + assertTrue(releaseFile.exists()) + + val debugProps = PropertiesUtil.load(debugFile) + val releaseProps = PropertiesUtil.load(releaseFile) + + assertEquals("debug", debugProps.getProperty(BUILD_CONFIGURATION_PROPERTY)) + assertEquals("release", releaseProps.getProperty(BUILD_CONFIGURATION_PROPERTY)) + } + + private fun createProject(): Project { + with(ProjectBuilder.builder().build()) { + plugins.apply("io.sentry.android.gradle") + return this + } + } +} From ea8ecbe2c1d010249a9a9581eef22b14d5feeb8a Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 6 Oct 2025 16:03:09 +0200 Subject: [PATCH 2/6] Refine GenerateDistributionPropertiesTask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Make task cacheable and use @OutputFile annotation - Simplify task by removing unnecessary directory creation and logging - Use variant name as build configuration instead of just build type - Reorder register() parameters for consistency - Remove redundant tests that don't add coverage 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../android/gradle/AndroidComponentsConfig.kt | 2 +- .../GenerateDistributionPropertiesTask.kt | 37 ++---- .../GenerateDistributionPropertiesTaskTest.kt | 109 ------------------ 3 files changed, 13 insertions(+), 135 deletions(-) diff --git a/plugin-build/src/main/kotlin/io/sentry/android/gradle/AndroidComponentsConfig.kt b/plugin-build/src/main/kotlin/io/sentry/android/gradle/AndroidComponentsConfig.kt index 745105f50..c4bccd4b3 100644 --- a/plugin-build/src/main/kotlin/io/sentry/android/gradle/AndroidComponentsConfig.kt +++ b/plugin-build/src/main/kotlin/io/sentry/android/gradle/AndroidComponentsConfig.kt @@ -395,8 +395,8 @@ private fun ApplicationVariant.configureDistributionPropertiesTask( extension = extension, sentryTelemetryProvider = sentryTelemetryProvider, output = paths.distributionPropertiesDir, - buildConfiguration = buildType ?: "unknown", taskSuffix = name.capitalized, + buildConfiguration = name, ) } return null diff --git a/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt b/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt index 7ed63dcd0..124137ca7 100644 --- a/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt +++ b/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt @@ -3,56 +3,44 @@ package io.sentry.android.gradle.tasks import io.sentry.android.gradle.extensions.SentryPluginExtension import io.sentry.android.gradle.telemetry.SentryTelemetryService import io.sentry.android.gradle.telemetry.withSentryTelemetry -import io.sentry.android.gradle.util.info import org.gradle.api.Project import org.gradle.api.file.Directory import org.gradle.api.file.RegularFile import org.gradle.api.provider.Property import org.gradle.api.provider.Provider +import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.TaskProvider -import org.gradle.work.DisableCachingByDefault -@DisableCachingByDefault +@CacheableTask abstract class GenerateDistributionPropertiesTask : PropertiesFileOutputTask() { init { - description = "Generates distribution properties for Sentry" + description = "Writes properties used to check for Build Distribution updates" } - @get:Internal + @get:OutputFile override val outputFile: Provider get() = output.file(SENTRY_DISTRIBUTION_OUTPUT) - @get:Input @get:Optional abstract val orgSlug: Property + @get:Input abstract val orgSlug: Property - @get:Input @get:Optional abstract val projectSlug: Property + @get:Input abstract val projectSlug: Property - @get:Input @get:Optional abstract val orgAuthToken: Property + @get:Input abstract val orgAuthToken: Property @get:Input abstract val buildConfiguration: Property @TaskAction fun generateProperties() { - val outputDir = output.get().asFile - outputDir.mkdirs() - outputFile.get().asFile.writer().use { writer -> orgSlug.orNull?.let { writer.appendLine("$ORG_SLUG_PROPERTY=$it") } projectSlug.orNull?.let { writer.appendLine("$PROJECT_SLUG_PROPERTY=$it") } orgAuthToken.orNull?.let { writer.appendLine("$ORG_AUTH_TOKEN_PROPERTY=$it") } writer.appendLine("$BUILD_CONFIGURATION_PROPERTY=${buildConfiguration.get()}") } - - logger.info { - "GenerateDistributionPropertiesTask - outputFile: $outputFile, " + - "orgSlug: ${orgSlug.orNull}, " + - "projectSlug: ${projectSlug.orNull}, " + - "buildConfiguration: ${buildConfiguration.get()}" - } } companion object { @@ -65,22 +53,21 @@ abstract class GenerateDistributionPropertiesTask : PropertiesFileOutputTask() { fun register( project: Project, extension: SentryPluginExtension, - sentryTelemetryProvider: Provider?, - output: Provider? = null, + sentryTelemetryProvider: Provider? = null, + output: Provider, + taskSuffix: String, buildConfiguration: String, - taskSuffix: String = "", ): TaskProvider { return project.tasks.register( "generateSentryDistributionProperties$taskSuffix", GenerateDistributionPropertiesTask::class.java, ) { task -> - output?.let { task.output.set(it) } + task.output.set(output) task.withSentryTelemetry(extension, sentryTelemetryProvider) task.orgSlug.set(extension.org) task.projectSlug.set(extension.projectName) task.orgAuthToken.set(extension.authToken) task.buildConfiguration.set(buildConfiguration) - task.outputs.upToDateWhen { false } } } } diff --git a/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt b/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt index c91eaac9e..472325b5e 100644 --- a/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt +++ b/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt @@ -47,115 +47,6 @@ class GenerateDistributionPropertiesTaskTest { assertEquals("debug", props.getProperty(BUILD_CONFIGURATION_PROPERTY)) } - @Test - fun `generate distribution properties with only build configuration`() { - val project = createProject() - val extension = project.extensions.findByName("sentry") as SentryPluginExtension - - val task: TaskProvider = - GenerateDistributionPropertiesTask.register( - project, - extension, - null, - project.layout.buildDirectory.dir("dummy/folder/"), - "release", - "test", - ) - - task.get().generateProperties() - - val expectedFile = File(project.buildDir, "dummy/folder/sentry-distribution.properties") - assertTrue(expectedFile.exists()) - - val props = PropertiesUtil.load(expectedFile) - assertNull(props.getProperty(ORG_SLUG_PROPERTY)) - assertNull(props.getProperty(PROJECT_SLUG_PROPERTY)) - assertNull(props.getProperty(ORG_AUTH_TOKEN_PROPERTY)) - assertEquals("release", props.getProperty(BUILD_CONFIGURATION_PROPERTY)) - } - - @Test - fun `generate distribution properties overrides on subsequent calls`() { - val project = createProject() - val extension = project.extensions.findByName("sentry") as SentryPluginExtension - extension.org.set("test-org-1") - extension.projectName.set("test-project-1") - extension.authToken.set("test-token-1") - - val task: TaskProvider = - GenerateDistributionPropertiesTask.register( - project, - extension, - null, - project.layout.buildDirectory.dir("dummy/folder/"), - "debug", - "test", - ) - - task.get().generateProperties() - - val expectedFile = File(project.buildDir, "dummy/folder/sentry-distribution.properties") - assertTrue(expectedFile.exists()) - - val props1 = PropertiesUtil.load(expectedFile) - assertEquals("test-org-1", props1.getProperty(ORG_SLUG_PROPERTY)) - assertEquals("test-project-1", props1.getProperty(PROJECT_SLUG_PROPERTY)) - assertEquals("test-token-1", props1.getProperty(ORG_AUTH_TOKEN_PROPERTY)) - - extension.org.set("test-org-2") - extension.projectName.set("test-project-2") - extension.authToken.set("test-token-2") - - task.get().generateProperties() - - val props2 = PropertiesUtil.load(expectedFile) - assertEquals("test-org-2", props2.getProperty(ORG_SLUG_PROPERTY)) - assertEquals("test-project-2", props2.getProperty(PROJECT_SLUG_PROPERTY)) - assertEquals("test-token-2", props2.getProperty(ORG_AUTH_TOKEN_PROPERTY)) - } - - @Test - fun `generate distribution properties for different build configurations`() { - val project = createProject() - val extension = project.extensions.findByName("sentry") as SentryPluginExtension - extension.org.set("test-org") - - val debugTask: TaskProvider = - GenerateDistributionPropertiesTask.register( - project, - extension, - null, - project.layout.buildDirectory.dir("dummy/debug/"), - "debug", - "Debug", - ) - - val releaseTask: TaskProvider = - GenerateDistributionPropertiesTask.register( - project, - extension, - null, - project.layout.buildDirectory.dir("dummy/release/"), - "release", - "Release", - ) - - debugTask.get().generateProperties() - releaseTask.get().generateProperties() - - val debugFile = File(project.buildDir, "dummy/debug/sentry-distribution.properties") - val releaseFile = File(project.buildDir, "dummy/release/sentry-distribution.properties") - - assertTrue(debugFile.exists()) - assertTrue(releaseFile.exists()) - - val debugProps = PropertiesUtil.load(debugFile) - val releaseProps = PropertiesUtil.load(releaseFile) - - assertEquals("debug", debugProps.getProperty(BUILD_CONFIGURATION_PROPERTY)) - assertEquals("release", releaseProps.getProperty(BUILD_CONFIGURATION_PROPERTY)) - } - private fun createProject(): Project { with(ProjectBuilder.builder().build()) { plugins.apply("io.sentry.android.gradle") From fc82fd673fa773a13ad4c12913d7c4dd1ab6e45b Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 6 Oct 2025 16:55:48 +0200 Subject: [PATCH 3/6] Apply spotless formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../gradle/tasks/GenerateDistributionPropertiesTaskTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt b/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt index 472325b5e..074cb5e38 100644 --- a/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt +++ b/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt @@ -8,7 +8,6 @@ import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Compani import io.sentry.android.gradle.util.PropertiesUtil import java.io.File import kotlin.test.assertEquals -import kotlin.test.assertNull import kotlin.test.assertTrue import org.gradle.api.Project import org.gradle.api.tasks.TaskProvider From 516991f0033ecdb3868861b376a57d3f2fd6a101 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 6 Oct 2025 17:00:21 +0200 Subject: [PATCH 4/6] Add comments --- .../android/gradle/tasks/GenerateDistributionPropertiesTask.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt b/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt index 124137ca7..ef4d247da 100644 --- a/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt +++ b/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt @@ -64,8 +64,10 @@ abstract class GenerateDistributionPropertiesTask : PropertiesFileOutputTask() { ) { task -> task.output.set(output) task.withSentryTelemetry(extension, sentryTelemetryProvider) + // TODO we should check if the org and project are available in sentry.properties task.orgSlug.set(extension.org) task.projectSlug.set(extension.projectName) + // TODO we should have a separate authToken for Build Distribution task.orgAuthToken.set(extension.authToken) task.buildConfiguration.set(buildConfiguration) } From b4a1c0c6bb99385d28ec29d6a23aea34de6fcebc Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 6 Oct 2025 17:10:18 +0200 Subject: [PATCH 5/6] Fix GenerateDistributionPropertiesTaskTest --- .../gradle/tasks/GenerateDistributionPropertiesTaskTest.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt b/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt index 074cb5e38..c6eae3dff 100644 --- a/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt +++ b/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt @@ -30,10 +30,13 @@ class GenerateDistributionPropertiesTaskTest { extension, null, project.layout.buildDirectory.dir("dummy/folder/"), - "debug", "test", + "debug", ) + val outputDir = File(project.buildDir, "dummy/folder/") + outputDir.mkdirs() + task.get().generateProperties() val expectedFile = File(project.buildDir, "dummy/folder/sentry-distribution.properties") From 8dad52dccb6e4790258f3624454a8c21f9f31c29 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Tue, 7 Oct 2025 17:23:33 +0200 Subject: [PATCH 6/6] Rename ORG_AUTH_TOKEN_PROPERTY to DISTRIBUTION_AUTH_TOKEN_PROPERTY --- .../gradle/tasks/GenerateDistributionPropertiesTask.kt | 4 ++-- .../gradle/tasks/GenerateDistributionPropertiesTaskTest.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt b/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt index ef4d247da..652a31ac1 100644 --- a/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt +++ b/plugin-build/src/main/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTask.kt @@ -38,7 +38,7 @@ abstract class GenerateDistributionPropertiesTask : PropertiesFileOutputTask() { outputFile.get().asFile.writer().use { writer -> orgSlug.orNull?.let { writer.appendLine("$ORG_SLUG_PROPERTY=$it") } projectSlug.orNull?.let { writer.appendLine("$PROJECT_SLUG_PROPERTY=$it") } - orgAuthToken.orNull?.let { writer.appendLine("$ORG_AUTH_TOKEN_PROPERTY=$it") } + orgAuthToken.orNull?.let { writer.appendLine("$DISTRIBUTION_AUTH_TOKEN_PROPERTY=$it") } writer.appendLine("$BUILD_CONFIGURATION_PROPERTY=${buildConfiguration.get()}") } } @@ -47,7 +47,7 @@ abstract class GenerateDistributionPropertiesTask : PropertiesFileOutputTask() { internal const val SENTRY_DISTRIBUTION_OUTPUT = "sentry-distribution.properties" const val ORG_SLUG_PROPERTY = "io.sentry.distribution.org-slug" const val PROJECT_SLUG_PROPERTY = "io.sentry.distribution.project-slug" - const val ORG_AUTH_TOKEN_PROPERTY = "io.sentry.distribution.org-auth-token" + const val DISTRIBUTION_AUTH_TOKEN_PROPERTY = "io.sentry.distribution.auth-token" const val BUILD_CONFIGURATION_PROPERTY = "io.sentry.distribution.build-configuration" fun register( diff --git a/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt b/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt index c6eae3dff..303409bbd 100644 --- a/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt +++ b/plugin-build/src/test/kotlin/io/sentry/android/gradle/tasks/GenerateDistributionPropertiesTaskTest.kt @@ -2,7 +2,7 @@ package io.sentry.android.gradle.tasks import io.sentry.android.gradle.extensions.SentryPluginExtension import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.BUILD_CONFIGURATION_PROPERTY -import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.ORG_AUTH_TOKEN_PROPERTY +import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.DISTRIBUTION_AUTH_TOKEN_PROPERTY import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.ORG_SLUG_PROPERTY import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.PROJECT_SLUG_PROPERTY import io.sentry.android.gradle.util.PropertiesUtil @@ -45,7 +45,7 @@ class GenerateDistributionPropertiesTaskTest { val props = PropertiesUtil.load(expectedFile) assertEquals("test-org", props.getProperty(ORG_SLUG_PROPERTY)) assertEquals("test-project", props.getProperty(PROJECT_SLUG_PROPERTY)) - assertEquals("test-token", props.getProperty(ORG_AUTH_TOKEN_PROPERTY)) + assertEquals("test-token", props.getProperty(DISTRIBUTION_AUTH_TOKEN_PROPERTY)) assertEquals("debug", props.getProperty(BUILD_CONFIGURATION_PROPERTY)) }