Skip to content

Commit 3695529

Browse files
runningcodeclaude
andauthored
Add GenerateDistributionPropertiesTask for distribution options (#999)
* Add GenerateDistributionPropertiesTask for distribution options 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.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 <noreply@anthropic.com> * Refine GenerateDistributionPropertiesTask - 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 <noreply@anthropic.com> * Apply spotless formatting 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add comments * Fix GenerateDistributionPropertiesTaskTest * Rename ORG_AUTH_TOKEN_PROPERTY to DISTRIBUTION_AUTH_TOKEN_PROPERTY --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 0499e13 commit 3695529

File tree

4 files changed

+165
-0
lines changed

4 files changed

+165
-0
lines changed

plugin-build/src/main/kotlin/io/sentry/android/gradle/AndroidComponentsConfig.kt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import io.sentry.android.gradle.instrumentation.SpanAddingClassVisitorFactory
2222
import io.sentry.android.gradle.services.SentryModulesService
2323
import io.sentry.android.gradle.sourcecontext.OutputPaths
2424
import io.sentry.android.gradle.sourcecontext.SourceContext
25+
import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask
2526
import io.sentry.android.gradle.tasks.InjectSentryMetaPropertiesIntoAssetsTask
2627
import io.sentry.android.gradle.tasks.PropertiesFileOutputTask
2728
import io.sentry.android.gradle.tasks.SentryGenerateIntegrationListTask
@@ -103,6 +104,15 @@ fun ApplicationAndroidComponentsExtension.configure(
103104
)
104105
generateProguardUuidTask?.let { tasksGeneratingProperties.add(it) }
105106

107+
val generateDistributionPropertiesTask =
108+
variant.configureDistributionPropertiesTask(
109+
project,
110+
extension,
111+
sentryTelemetryProvider,
112+
paths,
113+
)
114+
generateDistributionPropertiesTask?.let { tasksGeneratingProperties.add(it) }
115+
106116
sentryVariant.configureNativeSymbolsTask(
107117
project,
108118
extension,
@@ -372,6 +382,26 @@ private fun ApplicationVariant.configureProguardMappingsTasks(
372382
}
373383
}
374384

385+
private fun ApplicationVariant.configureDistributionPropertiesTask(
386+
project: Project,
387+
extension: SentryPluginExtension,
388+
sentryTelemetryProvider: Provider<SentryTelemetryService>,
389+
paths: OutputPaths,
390+
): TaskProvider<GenerateDistributionPropertiesTask>? {
391+
val variantName = name
392+
if (extension.distribution.enabledVariants.get().contains(variantName)) {
393+
return GenerateDistributionPropertiesTask.register(
394+
project = project,
395+
extension = extension,
396+
sentryTelemetryProvider = sentryTelemetryProvider,
397+
output = paths.distributionPropertiesDir,
398+
taskSuffix = name.capitalized,
399+
buildConfiguration = name,
400+
)
401+
}
402+
return null
403+
}
404+
375405
/**
376406
* Configure the upload AAB and APK tasks and set them up as finalizers on the respective producer
377407
* tasks

plugin-build/src/main/kotlin/io/sentry/android/gradle/sourcecontext/OutputPaths.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ class OutputPaths(private val project: Project, variantName: String) {
1515
val bundleIdDir = dir("$variantDirectory/bundle-id")
1616
val sourceDir = dir("$variantDirectory/source-to-bundle")
1717
val bundleDir = dir("$variantDirectory/source-bundle")
18+
val distributionPropertiesDir = dir("$variantDirectory/distribution-properties")
1819
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package io.sentry.android.gradle.tasks
2+
3+
import io.sentry.android.gradle.extensions.SentryPluginExtension
4+
import io.sentry.android.gradle.telemetry.SentryTelemetryService
5+
import io.sentry.android.gradle.telemetry.withSentryTelemetry
6+
import org.gradle.api.Project
7+
import org.gradle.api.file.Directory
8+
import org.gradle.api.file.RegularFile
9+
import org.gradle.api.provider.Property
10+
import org.gradle.api.provider.Provider
11+
import org.gradle.api.tasks.CacheableTask
12+
import org.gradle.api.tasks.Input
13+
import org.gradle.api.tasks.OutputFile
14+
import org.gradle.api.tasks.TaskAction
15+
import org.gradle.api.tasks.TaskProvider
16+
17+
@CacheableTask
18+
abstract class GenerateDistributionPropertiesTask : PropertiesFileOutputTask() {
19+
20+
init {
21+
description = "Writes properties used to check for Build Distribution updates"
22+
}
23+
24+
@get:OutputFile
25+
override val outputFile: Provider<RegularFile>
26+
get() = output.file(SENTRY_DISTRIBUTION_OUTPUT)
27+
28+
@get:Input abstract val orgSlug: Property<String>
29+
30+
@get:Input abstract val projectSlug: Property<String>
31+
32+
@get:Input abstract val orgAuthToken: Property<String>
33+
34+
@get:Input abstract val buildConfiguration: Property<String>
35+
36+
@TaskAction
37+
fun generateProperties() {
38+
outputFile.get().asFile.writer().use { writer ->
39+
orgSlug.orNull?.let { writer.appendLine("$ORG_SLUG_PROPERTY=$it") }
40+
projectSlug.orNull?.let { writer.appendLine("$PROJECT_SLUG_PROPERTY=$it") }
41+
orgAuthToken.orNull?.let { writer.appendLine("$DISTRIBUTION_AUTH_TOKEN_PROPERTY=$it") }
42+
writer.appendLine("$BUILD_CONFIGURATION_PROPERTY=${buildConfiguration.get()}")
43+
}
44+
}
45+
46+
companion object {
47+
internal const val SENTRY_DISTRIBUTION_OUTPUT = "sentry-distribution.properties"
48+
const val ORG_SLUG_PROPERTY = "io.sentry.distribution.org-slug"
49+
const val PROJECT_SLUG_PROPERTY = "io.sentry.distribution.project-slug"
50+
const val DISTRIBUTION_AUTH_TOKEN_PROPERTY = "io.sentry.distribution.auth-token"
51+
const val BUILD_CONFIGURATION_PROPERTY = "io.sentry.distribution.build-configuration"
52+
53+
fun register(
54+
project: Project,
55+
extension: SentryPluginExtension,
56+
sentryTelemetryProvider: Provider<SentryTelemetryService>? = null,
57+
output: Provider<Directory>,
58+
taskSuffix: String,
59+
buildConfiguration: String,
60+
): TaskProvider<GenerateDistributionPropertiesTask> {
61+
return project.tasks.register(
62+
"generateSentryDistributionProperties$taskSuffix",
63+
GenerateDistributionPropertiesTask::class.java,
64+
) { task ->
65+
task.output.set(output)
66+
task.withSentryTelemetry(extension, sentryTelemetryProvider)
67+
// TODO we should check if the org and project are available in sentry.properties
68+
task.orgSlug.set(extension.org)
69+
task.projectSlug.set(extension.projectName)
70+
// TODO we should have a separate authToken for Build Distribution
71+
task.orgAuthToken.set(extension.authToken)
72+
task.buildConfiguration.set(buildConfiguration)
73+
}
74+
}
75+
}
76+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package io.sentry.android.gradle.tasks
2+
3+
import io.sentry.android.gradle.extensions.SentryPluginExtension
4+
import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.BUILD_CONFIGURATION_PROPERTY
5+
import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.DISTRIBUTION_AUTH_TOKEN_PROPERTY
6+
import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.ORG_SLUG_PROPERTY
7+
import io.sentry.android.gradle.tasks.GenerateDistributionPropertiesTask.Companion.PROJECT_SLUG_PROPERTY
8+
import io.sentry.android.gradle.util.PropertiesUtil
9+
import java.io.File
10+
import kotlin.test.assertEquals
11+
import kotlin.test.assertTrue
12+
import org.gradle.api.Project
13+
import org.gradle.api.tasks.TaskProvider
14+
import org.gradle.testfixtures.ProjectBuilder
15+
import org.junit.Test
16+
17+
class GenerateDistributionPropertiesTaskTest {
18+
19+
@Test
20+
fun `generate distribution properties with all fields`() {
21+
val project = createProject()
22+
val extension = project.extensions.findByName("sentry") as SentryPluginExtension
23+
extension.org.set("test-org")
24+
extension.projectName.set("test-project")
25+
extension.authToken.set("test-token")
26+
27+
val task: TaskProvider<GenerateDistributionPropertiesTask> =
28+
GenerateDistributionPropertiesTask.register(
29+
project,
30+
extension,
31+
null,
32+
project.layout.buildDirectory.dir("dummy/folder/"),
33+
"test",
34+
"debug",
35+
)
36+
37+
val outputDir = File(project.buildDir, "dummy/folder/")
38+
outputDir.mkdirs()
39+
40+
task.get().generateProperties()
41+
42+
val expectedFile = File(project.buildDir, "dummy/folder/sentry-distribution.properties")
43+
assertTrue(expectedFile.exists())
44+
45+
val props = PropertiesUtil.load(expectedFile)
46+
assertEquals("test-org", props.getProperty(ORG_SLUG_PROPERTY))
47+
assertEquals("test-project", props.getProperty(PROJECT_SLUG_PROPERTY))
48+
assertEquals("test-token", props.getProperty(DISTRIBUTION_AUTH_TOKEN_PROPERTY))
49+
assertEquals("debug", props.getProperty(BUILD_CONFIGURATION_PROPERTY))
50+
}
51+
52+
private fun createProject(): Project {
53+
with(ProjectBuilder.builder().build()) {
54+
plugins.apply("io.sentry.android.gradle")
55+
return this
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)