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
2 changes: 1 addition & 1 deletion .github/workflows/test-matrix-agp-gradle.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ concurrency:

jobs:
publish-dry-run:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Fixes

- Kotlin Compiler Plugin: Fix API incompatibility with Kotlin 2.1.20 ([#857](https://github.com/getsentry/sentry-android-gradle-plugin/pull/857))
- Make `SentryGenerateIntegrationListTask` configuration-cache compatible ([#866](https://github.com/getsentry/sentry-android-gradle-plugin/pull/866))

### Internal

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import io.sentry.android.gradle.tasks.SentryUploadProguardMappingsTask
import io.sentry.android.gradle.tasks.configureNativeSymbolsTask
import io.sentry.android.gradle.tasks.dependencies.SentryExternalDependenciesReportTaskFactory
import io.sentry.android.gradle.telemetry.SentryTelemetryService
import io.sentry.android.gradle.telemetry.withSentryTelemetry
import io.sentry.android.gradle.transforms.MetaInfStripTransform
import io.sentry.android.gradle.util.AgpVersions
import io.sentry.android.gradle.util.AgpVersions.isAGP74
Expand Down Expand Up @@ -204,18 +203,13 @@ fun AndroidComponentsExtension<*, *, *>.configure(
}

val manifestUpdater =
project.tasks.register(
"${variant.name}SentryGenerateIntegrationListTask",
SentryGenerateIntegrationListTask::class.java,
) {
it.integrations.set(
sentryModulesService.map { service ->
service.retrieveEnabledInstrumentationFeatures()
}
)
it.usesService(sentryModulesService)
it.withSentryTelemetry(extension, sentryTelemetryProvider)
}
SentryGenerateIntegrationListTask.register(
project,
extension,
sentryTelemetryProvider,
sentryModulesService,
variant.name,
)

variant.artifacts
.use(manifestUpdater)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ abstract class SentryModulesService :
@set:Synchronized
var externalModules: Map<ModuleIdentifier, SemVer> = emptyMap()

fun retrieveEnabledInstrumentationFeatures(): Set<String> {
fun retrieveEnabledInstrumentationFeatures(project: Project): Provider<Set<String>> {
val features =
parameters.features
.get()
Expand All @@ -52,7 +52,7 @@ abstract class SentryModulesService :
features.add("DexGuard")
}

return features
return project.provider { features }
}

private fun isInstrumentationEnabled(feature: InstrumentationFeature): Boolean {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package io.sentry.android.gradle.tasks

import io.sentry.android.gradle.ManifestWriter
import io.sentry.android.gradle.extensions.SentryPluginExtension
import io.sentry.android.gradle.services.SentryModulesService
import io.sentry.android.gradle.telemetry.SentryTelemetryService
import io.sentry.android.gradle.telemetry.withSentryTelemetry
import io.sentry.android.gradle.util.info
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Provider
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
Expand All @@ -14,14 +20,11 @@ import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity.NONE
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskProvider

@CacheableTask
abstract class SentryGenerateIntegrationListTask : DefaultTask() {

companion object {
const val ATTR_INTEGRATIONS = "io.sentry.gradle-plugin-integrations"
}

init {
description = "Writes enabled integrations to AndroidManifest.xml"
}
Expand Down Expand Up @@ -58,4 +61,29 @@ abstract class SentryGenerateIntegrationListTask : DefaultTask() {
)
}
}

companion object {
const val ATTR_INTEGRATIONS = "io.sentry.gradle-plugin-integrations"

fun register(
project: Project,
extension: SentryPluginExtension,
sentryTelemetryProvider: Provider<SentryTelemetryService>?,
sentryModulesService: Provider<SentryModulesService>,
variantName: String,
): TaskProvider<SentryGenerateIntegrationListTask> {
return project.tasks.register(
"${variantName}SentryGenerateIntegrationListTask",
SentryGenerateIntegrationListTask::class.java,
) {
it.integrations.set(
sentryModulesService.flatMap { service ->
service.retrieveEnabledInstrumentationFeatures(project)
}
)
it.usesService(sentryModulesService)
it.withSentryTelemetry(extension, sentryTelemetryProvider)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import io.sentry.android.gradle.util.AgpVersions
import io.sentry.android.gradle.util.GradleVersions
import io.sentry.android.gradle.util.SemVer
import io.sentry.android.gradle.verifyDependenciesReportAndroid
import io.sentry.android.gradle.verifyIntegrationList
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
import org.gradle.testkit.runner.TaskOutcome
import org.gradle.util.GradleVersion
import org.hamcrest.CoreMatchers.`is`
import org.jetbrains.kotlin.gradle.report.TaskExecutionState.UP_TO_DATE
import org.junit.Assume.assumeThat
import org.junit.Test

Expand Down Expand Up @@ -306,4 +309,61 @@ class SentryPluginConfigurationCacheTest :
val outputWithConfigCache = runner.build().output
assertTrue { "Configuration cache entry reused." in outputWithConfigCache }
}

@Test
fun `generate integration list task respects configuration cache`() {
assumeThat(
"SentryGenerateIntegrationListTask only supports " +
"configuration cache from Gradle 7.5 onwards",
GradleVersions.CURRENT >= GradleVersions.VERSION_7_5,
`is`(true),
)
appBuildFile.writeText(
// language=Groovy
"""
plugins {
id "com.android.application"
id "io.sentry.android.gradle"
}

android {
namespace 'com.example'
}

sentry {
includeNativeSources = false
uploadNativeSymbols = false
includeProguardMapping = false
autoUploadProguardMapping = false
tracingInstrumentation.features = []
telemetry = false
}
"""
.trimIndent()
)
runner.appendArguments(":app:assembleDebug").appendArguments("--configuration-cache")

val firstBuild = runner.build().output
assertTrue { "Configuration cache entry stored." in firstBuild }

val integrationsFirst = verifyIntegrationList(testProjectDir.root, "debug", signed = false)
assertEquals(
listOf("AppStartInstrumentation", "LogcatInstrumentation"),
integrationsFirst.sorted(),
)

// second build should reuse config cache and tasks should be up-to-date as nothing changed
val secondBuild = runner.build()
assertEquals(
TaskOutcome.UP_TO_DATE,
secondBuild.task(":app:debugSentryGenerateIntegrationListTask")?.outcome,
)
assertTrue { "Configuration cache entry reused." in secondBuild.output }

val integrationsSecond = verifyIntegrationList(testProjectDir.root, "debug", signed = false)
assertEquals(
listOf("AppStartInstrumentation", "LogcatInstrumentation"),
integrationsSecond.sorted(),
)
}
}
Loading