From 89a16e4644b7b3f880b303ebb02e854598760337 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Tue, 27 Oct 2026 11:59:36 +0100 Subject: [PATCH 01/21] build(samples): Prepare the samples to build outside the SDK build The samples and Android integration tests are about to become their own builds, which include the SDK build. Several things tie them to the SDK build today: - They call buildSrc's Config, which other builds cannot see. They now name the coordinates directly, the way a customer's build would. - Five samples' shadowJar tasks use buildSrc's MergeSpringMetadataAction, which only the samples use. It moves to build-logic, which the new builds can include. - They pick the Kotlin stdlib version with KotlinCompilerVersion, a compiler-internal class that came from buildSrc's classpath. They now use KGP's getKotlinPluginVersion(), which returns the same version. - AGP came from Config.AGP on the root buildscript classpath. A composite build must use a single AGP version, so it now comes from the version catalog, and each build's settings applies the AGP matrix job's VERSION_AGP override. - The javac -Xlint:all -Werror flags came from the root allprojects block. They move to the io.sentry.jdk-target convention, which every subproject already applies and the new builds can apply too. Co-Authored-By: Claude Opus 5.5 --- .../io/sentry/gradle/JdkTargetConvention.kt | 14 ++++++++++++++ .../sentry/gradle}/MergeSpringMetadataAction.kt | 2 ++ build.gradle.kts | 6 +----- buildSrc/src/main/java/Config.kt | 5 ----- gradle/libs.versions.toml | 6 +++--- .../build.gradle.kts | 7 +++---- .../sentry-uitest-android/build.gradle.kts | 5 ++--- .../test-app-size/build.gradle.kts | 2 +- .../sentry-samples-android/build.gradle.kts | 7 +++---- .../sentry-samples-netflix-dgs/build.gradle.kts | 7 ++++--- .../sentry-samples-spring-7/build.gradle.kts | 16 ++++++++-------- .../build.gradle.kts | 8 ++++---- .../build.gradle.kts | 8 ++++---- .../build.gradle.kts | 8 ++++---- .../build.gradle.kts | 8 ++++---- .../build.gradle.kts | 6 +++--- .../build.gradle.kts | 8 ++++---- .../build.gradle.kts | 8 ++++---- .../build.gradle.kts | 8 ++++---- .../build.gradle.kts | 8 ++++---- .../build.gradle.kts | 8 ++++---- .../build.gradle.kts | 9 +++++---- .../build.gradle.kts | 9 +++++---- .../build.gradle.kts | 6 +++--- .../build.gradle.kts | 7 ++++--- .../sentry-samples-spring-boot/build.gradle.kts | 9 +++++---- .../build.gradle.kts | 14 +++++++------- .../sentry-samples-spring/build.gradle.kts | 14 +++++++------- settings.gradle.kts | 12 ++++++++++++ 29 files changed, 128 insertions(+), 107 deletions(-) rename {buildSrc/src/main/java => build-logic/src/main/kotlin/io/sentry/gradle}/MergeSpringMetadataAction.kt (99%) diff --git a/build-logic/src/main/kotlin/io/sentry/gradle/JdkTargetConvention.kt b/build-logic/src/main/kotlin/io/sentry/gradle/JdkTargetConvention.kt index 73202bbb3f3..0b4c54ce906 100644 --- a/build-logic/src/main/kotlin/io/sentry/gradle/JdkTargetConvention.kt +++ b/build-logic/src/main/kotlin/io/sentry/gradle/JdkTargetConvention.kt @@ -33,9 +33,23 @@ private val PUBLISHED_JAVA_VERSION = JavaVersion.VERSION_1_8 * archives are checked for it * - published Android modules main code targets Java 1.8 * - minSdk is set for Android libraries + * - javac warnings fail the build */ class JdkTargetConvention : Plugin { override fun apply(project: Project) { + project.tasks.withType(JavaCompile::class.java).configureEach { + options.compilerArgs.addAll( + listOf( + "-Xlint:all", + "-Werror", + "-Xlint:-classfile", + "-Xlint:-processing", + "-Xlint:-try", + "-Xlint:-options", + ) + ) + } + project.plugins.withType(JavaBasePlugin::class.java) { project.extensions.getByType(JavaPluginExtension::class.java).toolchain { languageVersion.set(BUILD_JDK) diff --git a/buildSrc/src/main/java/MergeSpringMetadataAction.kt b/build-logic/src/main/kotlin/io/sentry/gradle/MergeSpringMetadataAction.kt similarity index 99% rename from buildSrc/src/main/java/MergeSpringMetadataAction.kt rename to build-logic/src/main/kotlin/io/sentry/gradle/MergeSpringMetadataAction.kt index 2df744924cb..ac73e21f588 100644 --- a/buildSrc/src/main/java/MergeSpringMetadataAction.kt +++ b/build-logic/src/main/kotlin/io/sentry/gradle/MergeSpringMetadataAction.kt @@ -1,3 +1,5 @@ +package io.sentry.gradle + import java.net.URI import java.nio.file.FileSystems import java.nio.file.Files diff --git a/build.gradle.kts b/build.gradle.kts index f4f59786f45..db37baa5207 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -20,6 +20,7 @@ plugins { alias(libs.plugins.spring.dependency.management) apply false id("io.sentry.javadoc.aggregate") alias(libs.plugins.sentry) apply false + alias(libs.plugins.android.application) apply false } buildscript { @@ -27,8 +28,6 @@ buildscript { google() } dependencies { - classpath(Config.BuildPlugins.androidGradle) - // add classpath of sentry android gradle plugin // classpath("io.sentry:sentry-android-gradle-plugin:{version}") @@ -50,9 +49,6 @@ allprojects { TestLogEvent.FAILED ) } - withType().configureEach { - options.compilerArgs.addAll(arrayOf("-Xlint:all", "-Werror", "-Xlint:-classfile", "-Xlint:-processing", "-Xlint:-try", "-Xlint:-options")) - } } } diff --git a/buildSrc/src/main/java/Config.kt b/buildSrc/src/main/java/Config.kt index 140805224a4..6a233274530 100644 --- a/buildSrc/src/main/java/Config.kt +++ b/buildSrc/src/main/java/Config.kt @@ -1,14 +1,9 @@ object Config { - val AGP = System.getenv("VERSION_AGP") ?: "9.4.0" val kotlinStdLib = "stdlib-jdk8" val kotlinStdLibVersionAndroid = "1.9.24" val kotlinTestJunit = "test-junit" - object BuildPlugins { - val androidGradle = "com.android.tools.build:gradle:$AGP" - } - object Android { val abiFilters = listOf("x86", "armeabi-v7a", "x86_64", "arm64-v8a") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 25681bf9137..15125fd7e65 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,8 +40,7 @@ retrofit = "2.9.0" room2 = "2.8.4" room3 = "3.0.0-rc01" sagp = "6.13.0" -# Compile-time only, for the AGP types the build-logic convention plugins use. The AGP that -# actually runs the build comes from the root buildscript (Config.AGP, overridable via VERSION_AGP). +# The AGP matrix job overrides this with the VERSION_AGP env var, through each build's settings. agp = "9.4.0" sqlite = "2.6.2" sqliteRc = "2.7.0-rc01" # Required by Room3 3.0.0-rc* @@ -62,7 +61,8 @@ compileSdkMinor = "2" minSdk = "21" [plugins] -kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +android-application = { id = "com.android.application", version.ref = "agp" } +kotlin-android ={ id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } diff --git a/sentry-android-integration-tests/sentry-uitest-android-critical/build.gradle.kts b/sentry-android-integration-tests/sentry-uitest-android-critical/build.gradle.kts index dedce1bfa53..c530245c213 100644 --- a/sentry-android-integration-tests/sentry-uitest-android-critical/build.gradle.kts +++ b/sentry-android-integration-tests/sentry-uitest-android-critical/build.gradle.kts @@ -1,4 +1,5 @@ import io.gitlab.arturbosch.detekt.Detekt +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion plugins { id("com.android.application") @@ -37,14 +38,12 @@ android { buildFeatures { compose = true } composeOptions { kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get() } androidComponents.beforeVariants { - it.enable = !Config.Android.shouldSkipDebugVariant(it.buildType) + it.enable = it.buildType != "debug" } } dependencies { - implementation( - kotlin(Config.kotlinStdLib, org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION) - ) + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(libs.androidx.activity.compose) implementation(libs.androidx.compose.foundation) implementation(libs.androidx.compose.material3) diff --git a/sentry-android-integration-tests/sentry-uitest-android/build.gradle.kts b/sentry-android-integration-tests/sentry-uitest-android/build.gradle.kts index 0af3e1bbb0d..a633acbae2e 100644 --- a/sentry-android-integration-tests/sentry-uitest-android/build.gradle.kts +++ b/sentry-android-integration-tests/sentry-uitest-android/build.gradle.kts @@ -1,5 +1,6 @@ import io.gitlab.arturbosch.detekt.Detekt import net.ltgt.gradle.errorprone.errorprone +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion plugins { id("com.android.application") @@ -86,9 +87,7 @@ if (applySentryIntegrations) { } dependencies { - implementation( - kotlin(Config.kotlinStdLib, org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION) - ) + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) if (applySentryIntegrations) { implementation(projects.sentryAndroid) diff --git a/sentry-android-integration-tests/test-app-size/build.gradle.kts b/sentry-android-integration-tests/test-app-size/build.gradle.kts index 499e468cb09..c8de6cbfbe3 100644 --- a/sentry-android-integration-tests/test-app-size/build.gradle.kts +++ b/sentry-android-integration-tests/test-app-size/build.gradle.kts @@ -33,7 +33,7 @@ android { targetCompatibility = JavaVersion.VERSION_17 } androidComponents.beforeVariants { - it.enable = !Config.Android.shouldSkipDebugVariant(it.buildType) + it.enable = it.buildType != "debug" } } diff --git a/sentry-samples/sentry-samples-android/build.gradle.kts b/sentry-samples/sentry-samples-android/build.gradle.kts index 6cb5b3d6d6d..1c70c5b69ae 100644 --- a/sentry-samples/sentry-samples-android/build.gradle.kts +++ b/sentry-samples/sentry-samples-android/build.gradle.kts @@ -5,6 +5,7 @@ import io.sentry.android.gradle.extensions.InstrumentationFeature import io.sentry.android.gradle.extensions.SentryPluginExtension import org.apache.tools.ant.taskdefs.condition.Os import org.gradle.internal.extensions.stdlib.capitalized +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion plugins { id("com.android.application") @@ -66,7 +67,7 @@ android { } } - ndk { abiFilters.addAll(Config.Android.abiFilters) } + ndk { abiFilters.addAll(listOf("x86", "armeabi-v7a", "x86_64", "arm64-v8a")) } } lint { @@ -174,9 +175,7 @@ sqldelight { } dependencies { - implementation( - kotlin(Config.kotlinStdLib, org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION) - ) + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentryAndroid) implementation(projects.sentryAndroidFragment) diff --git a/sentry-samples/sentry-samples-netflix-dgs/build.gradle.kts b/sentry-samples/sentry-samples-netflix-dgs/build.gradle.kts index f4cce527834..f64c52f2d00 100644 --- a/sentry-samples/sentry-samples-netflix-dgs/build.gradle.kts +++ b/sentry-samples/sentry-samples-netflix-dgs/build.gradle.kts @@ -1,4 +1,5 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import io.sentry.gradle.MergeSpringMetadataAction +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -24,8 +25,8 @@ java.targetCompatibility = JavaVersion.VERSION_1_8 dependencies { implementation(platform(libs.springboot2.bom)) implementation(libs.springboot.starter.web) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBootStarter) implementation(projects.sentryGraphql) implementation(platform("com.netflix.graphql.dgs:graphql-dgs-platform-dependencies:4.9.2")) diff --git a/sentry-samples/sentry-samples-spring-7/build.gradle.kts b/sentry-samples/sentry-samples-spring-7/build.gradle.kts index 744cb76b1c5..c9825bda212 100644 --- a/sentry-samples/sentry-samples-spring-7/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-7/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.springframework.boot.gradle.plugin.SpringBootPlugin @@ -31,13 +31,13 @@ dependencyManagement { } dependencies { - implementation(Config.Libs.springWeb) - implementation(Config.Libs.springAop) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.springSecurityWeb) - implementation(Config.Libs.springSecurityConfig) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.springframework:spring-webmvc") + implementation("org.springframework:spring-aop") + implementation("org.aspectj:aspectjweaver") + implementation("org.springframework.security:spring-security-web") + implementation("org.springframework.security:spring-security-config") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpring7) implementation(projects.sentryLogback) implementation(projects.sentryAsyncProfiler) diff --git a/sentry-samples/sentry-samples-spring-boot-4-log4j2/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-4-log4j2/build.gradle.kts index af5446277a2..eab14e55247 100644 --- a/sentry-samples/sentry-samples-spring-boot-4-log4j2/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-4-log4j2/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -38,9 +38,9 @@ dependencies { implementation(libs.springboot4.starter.websocket) implementation(libs.springboot4.starter.restclient) implementation(libs.springboot4.starter.webclient) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.aspectj:aspectjweaver") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBoot4Starter) implementation(projects.sentryGraphql22) implementation(projects.sentryQuartz) diff --git a/sentry-samples/sentry-samples-spring-boot-4-opentelemetry-noagent/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-4-opentelemetry-noagent/build.gradle.kts index e6f088e7ff3..0f3479ee6b1 100644 --- a/sentry-samples/sentry-samples-spring-boot-4-opentelemetry-noagent/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-4-opentelemetry-noagent/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -38,9 +38,9 @@ dependencies { implementation(libs.springboot4.starter.websocket) implementation(libs.springboot4.starter.webclient) implementation(libs.springboot4.starter.restclient) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.aspectj:aspectjweaver") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBoot4Starter) implementation(projects.sentryLogback) implementation(projects.sentryGraphql22) diff --git a/sentry-samples/sentry-samples-spring-boot-4-opentelemetry/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-4-opentelemetry/build.gradle.kts index f878d37b51a..7b92e24a462 100644 --- a/sentry-samples/sentry-samples-spring-boot-4-opentelemetry/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-4-opentelemetry/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.springframework.boot.gradle.tasks.run.BootRun @@ -39,9 +39,9 @@ dependencies { implementation(libs.springboot4.starter.websocket) implementation(libs.springboot4.starter.webclient) implementation(libs.springboot4.starter.restclient) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.aspectj:aspectjweaver") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBoot4Starter) implementation(projects.sentryLogback) implementation(projects.sentryGraphql22) diff --git a/sentry-samples/sentry-samples-spring-boot-4-otlp/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-4-otlp/build.gradle.kts index 4d16f23e893..88f82666c5d 100644 --- a/sentry-samples/sentry-samples-spring-boot-4-otlp/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-4-otlp/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -38,9 +38,9 @@ dependencies { implementation(libs.springboot4.starter.websocket) implementation(libs.springboot4.starter.restclient) implementation(libs.springboot4.starter.webclient) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.aspectj:aspectjweaver") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBoot4Starter) implementation(projects.sentryLogback) implementation(projects.sentryGraphql22) diff --git a/sentry-samples/sentry-samples-spring-boot-4-webflux/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-4-webflux/build.gradle.kts index 39f8b0487a2..942b70d491d 100644 --- a/sentry-samples/sentry-samples-spring-boot-4-webflux/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-4-webflux/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -15,8 +15,8 @@ group = "io.sentry.sample.spring-boot-4-webflux" version = "0.0.1-SNAPSHOT" dependencies { - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBoot4Starter) implementation(projects.sentryLogback) implementation(projects.sentryJdbc) diff --git a/sentry-samples/sentry-samples-spring-boot-4/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-4/build.gradle.kts index ac2f15e32fa..2059633409f 100644 --- a/sentry-samples/sentry-samples-spring-boot-4/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-4/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -38,9 +38,9 @@ dependencies { implementation(libs.springboot4.starter.websocket) implementation(libs.springboot4.starter.restclient) implementation(libs.springboot4.starter.webclient) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.aspectj:aspectjweaver") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBoot4Starter) implementation(projects.sentryLogback) implementation(projects.sentryGraphql22) diff --git a/sentry-samples/sentry-samples-spring-boot-jakarta-log4j2/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-jakarta-log4j2/build.gradle.kts index dd8e2fcaa83..0c57e1259f1 100644 --- a/sentry-samples/sentry-samples-spring-boot-jakarta-log4j2/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-jakarta-log4j2/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -40,9 +40,9 @@ dependencies { implementation(libs.springboot3.starter.web) implementation(libs.springboot3.starter.webflux) implementation(libs.springboot3.starter.websocket) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.aspectj:aspectjweaver") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBootStarterJakarta) implementation(projects.sentryLog4j2) implementation("org.springframework.boot:spring-boot-starter-log4j2") diff --git a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/build.gradle.kts index d442c49dae6..757bbda8fb1 100644 --- a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -41,9 +41,9 @@ dependencies { implementation(libs.springboot3.starter.web) implementation(libs.springboot3.starter.webflux) implementation(libs.springboot3.starter.websocket) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.aspectj:aspectjweaver") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBootStarterJakarta) implementation(projects.sentryLogback) implementation(projects.sentryGraphql22) diff --git a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry/build.gradle.kts index 847ae9ef888..9e6201fd6a1 100644 --- a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.springframework.boot.gradle.tasks.run.BootRun @@ -41,9 +41,9 @@ dependencies { implementation(libs.springboot3.starter.web) implementation(libs.springboot3.starter.webflux) implementation(libs.springboot3.starter.websocket) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.aspectj:aspectjweaver") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBootStarterJakarta) implementation(projects.sentryLogback) implementation(projects.sentryGraphql22) diff --git a/sentry-samples/sentry-samples-spring-boot-jakarta/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-jakarta/build.gradle.kts index de238c334c9..63f9b1799b8 100644 --- a/sentry-samples/sentry-samples-spring-boot-jakarta/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-jakarta/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -40,9 +40,9 @@ dependencies { implementation(libs.springboot3.starter.web) implementation(libs.springboot3.starter.webflux) implementation(libs.springboot3.starter.websocket) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.aspectj:aspectjweaver") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBootStarterJakarta) implementation(projects.sentryLogback) implementation(projects.sentryGraphql22) diff --git a/sentry-samples/sentry-samples-spring-boot-opentelemetry-noagent/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-opentelemetry-noagent/build.gradle.kts index e3b3440404b..fafda035855 100644 --- a/sentry-samples/sentry-samples-spring-boot-opentelemetry-noagent/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-opentelemetry-noagent/build.gradle.kts @@ -1,4 +1,5 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import io.sentry.gradle.MergeSpringMetadataAction +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -46,9 +47,9 @@ dependencies { implementation(libs.springboot.starter.web) implementation(libs.springboot.starter.webflux) implementation(libs.springboot.starter.websocket) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.aspectj:aspectjweaver") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBootStarter) implementation(projects.sentryLogback) implementation(projects.sentryGraphql) diff --git a/sentry-samples/sentry-samples-spring-boot-opentelemetry/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-opentelemetry/build.gradle.kts index cd31246dd2c..5e5ceb5eafd 100644 --- a/sentry-samples/sentry-samples-spring-boot-opentelemetry/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-opentelemetry/build.gradle.kts @@ -1,4 +1,5 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import io.sentry.gradle.MergeSpringMetadataAction +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -45,9 +46,9 @@ dependencies { implementation(libs.springboot.starter.web) implementation(libs.springboot.starter.webflux) implementation(libs.springboot.starter.websocket) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.aspectj:aspectjweaver") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBootStarter) implementation(projects.sentryLogback) implementation(projects.sentryGraphql) diff --git a/sentry-samples/sentry-samples-spring-boot-webflux-jakarta/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-webflux-jakarta/build.gradle.kts index cbf037a36a1..eba13d006fd 100644 --- a/sentry-samples/sentry-samples-spring-boot-webflux-jakarta/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-webflux-jakarta/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -24,8 +24,8 @@ dependencyManagement { extra["kotlin-coroutines.version"] = "1.9.0" dependencies { - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBootStarterJakarta) implementation(projects.sentryLogback) implementation(projects.sentryJdbc) diff --git a/sentry-samples/sentry-samples-spring-boot-webflux/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-webflux/build.gradle.kts index 34cb09077f7..2726fdb076c 100644 --- a/sentry-samples/sentry-samples-spring-boot-webflux/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-webflux/build.gradle.kts @@ -1,4 +1,5 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import io.sentry.gradle.MergeSpringMetadataAction +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -32,8 +33,8 @@ dependencies { implementation(libs.springboot.starter.actuator) implementation(libs.springboot.starter.graphql) implementation(libs.springboot.starter.webflux) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBootStarter) implementation(projects.sentryLogback) implementation(projects.sentryGraphql) diff --git a/sentry-samples/sentry-samples-spring-boot/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot/build.gradle.kts index 4737e6b8874..f1c71766f57 100644 --- a/sentry-samples/sentry-samples-spring-boot/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot/build.gradle.kts @@ -1,4 +1,5 @@ -import org.jetbrains.kotlin.config.KotlinCompilerVersion +import io.sentry.gradle.MergeSpringMetadataAction +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -50,9 +51,9 @@ dependencies { implementation(libs.spring.kafka2) implementation(projects.sentryKafka) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) + implementation("org.aspectj:aspectjweaver") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) implementation(projects.sentrySpringBootStarter) implementation(projects.sentryLogback) implementation(projects.sentryGraphql) diff --git a/sentry-samples/sentry-samples-spring-jakarta/build.gradle.kts b/sentry-samples/sentry-samples-spring-jakarta/build.gradle.kts index ccb1b24f3f8..d189bec4c84 100644 --- a/sentry-samples/sentry-samples-spring-jakarta/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-jakarta/build.gradle.kts @@ -29,13 +29,13 @@ dependencyManagement { } dependencies { - implementation(Config.Libs.springWeb) - implementation(Config.Libs.springAop) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.springSecurityWeb) - implementation(Config.Libs.springSecurityConfig) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib)) + implementation("org.springframework:spring-webmvc") + implementation("org.springframework:spring-aop") + implementation("org.aspectj:aspectjweaver") + implementation("org.springframework.security:spring-security-web") + implementation("org.springframework.security:spring-security-config") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8")) implementation(projects.sentrySpringJakarta) implementation(projects.sentryLogback) implementation(projects.sentryAsyncProfiler) diff --git a/sentry-samples/sentry-samples-spring/build.gradle.kts b/sentry-samples/sentry-samples-spring/build.gradle.kts index 7666a81cfab..4ef973725e9 100644 --- a/sentry-samples/sentry-samples-spring/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring/build.gradle.kts @@ -40,13 +40,13 @@ dependencyManagement { } dependencies { - implementation(Config.Libs.springWeb) - implementation(Config.Libs.springAop) - implementation(Config.Libs.aspectj) - implementation(Config.Libs.springSecurityWeb) - implementation(Config.Libs.springSecurityConfig) - implementation(Config.Libs.kotlinReflect) - implementation(kotlin(Config.kotlinStdLib)) + implementation("org.springframework:spring-webmvc") + implementation("org.springframework:spring-aop") + implementation("org.aspectj:aspectjweaver") + implementation("org.springframework.security:spring-security-web") + implementation("org.springframework.security:spring-security-config") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("stdlib-jdk8")) implementation(projects.sentrySpring) implementation(projects.sentryLogback) implementation(projects.sentryAsyncProfiler) diff --git a/settings.gradle.kts b/settings.gradle.kts index ec94cc6ccdf..2849794723f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -15,6 +15,18 @@ pluginManagement { gradlePluginPortal() google() } + + // Every build in a composite must use the same AGP, so each build's settings applies the AGP + // matrix job's override. + System.getenv("VERSION_AGP")?.let { agpVersion -> + resolutionStrategy { + eachPlugin { + if (requested.id.id.startsWith("com.android")) { + useVersion(agpVersion) + } + } + } + } } plugins { From a9e0668f0f614dc9d7906f5b4f8e82978bbf5bb6 Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Thu, 29 Oct 2026 17:17:56 +0100 Subject: [PATCH 02/21] Apply suggestion from @romtsn --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 15125fd7e65..cc0d16d8ecc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -62,7 +62,7 @@ minSdk = "21" [plugins] android-application = { id = "com.android.application", version.ref = "agp" } -kotlin-android ={ id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } From 59b6acb8c7b9abe543826067f8fb25876ce7474d Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Tue, 27 Oct 2026 12:12:03 +0100 Subject: [PATCH 03/21] build(samples): Move the Android sample to its own build The Android sample is now a standalone Gradle build that includes the SDK build. It depends on io.sentry:* coordinates, which Gradle substitutes with the SDK's projects, so there is nothing to publish first. The SDK build doesn't include it back, so the sample's plugins (KSP, SQLDelight, Room, CameraX) no longer load in the SDK build. The macrobenchmark moves into the sample's build, because AGP requires a benchmark and the app it targets to be in the same build. Root check and spotlessApply no longer reach the sample, so preMerge runs the sample build's check, and the format workflow runs its spotlessApply. That check covers what the root check ran for it: lint, unit tests, SQLDelight migrations and spotless. Run it with ./gradlew -p sentry-samples/sentry-samples-android . Co-Authored-By: Claude Opus 5.5 --- .github/workflows/format-code.yml | 4 +- .../integration-tests-macrobenchmark.yml | 4 +- .../sentry-uitest-android-macrobenchmark.yml | 2 +- AGENTS.md | 5 +- Makefile | 9 ++- .../sentry-samples-android/README.md | 13 ++-- .../sentry-samples-android/build.gradle.kts | 42 +++++----- .../sentry-samples-android/gradle.properties | 24 ++++++ .../macrobenchmark}/README.md | 4 +- .../macrobenchmark}/build.gradle.kts | 5 +- .../src/main/AndroidManifest.xml | 0 .../macrobenchmark/SentryStartupBenchmark.kt | 0 .../settings.gradle.kts | 77 +++++++++++++++++++ settings.gradle.kts | 2 - 14 files changed, 153 insertions(+), 38 deletions(-) create mode 100644 sentry-samples/sentry-samples-android/gradle.properties rename {sentry-android-integration-tests/sentry-uitest-android-macrobenchmark => sentry-samples/sentry-samples-android/macrobenchmark}/README.md (97%) rename {sentry-android-integration-tests/sentry-uitest-android-macrobenchmark => sentry-samples/sentry-samples-android/macrobenchmark}/build.gradle.kts (94%) rename {sentry-android-integration-tests/sentry-uitest-android-macrobenchmark => sentry-samples/sentry-samples-android/macrobenchmark}/src/main/AndroidManifest.xml (100%) rename {sentry-android-integration-tests/sentry-uitest-android-macrobenchmark => sentry-samples/sentry-samples-android/macrobenchmark}/src/main/java/io/sentry/uitest/android/macrobenchmark/SentryStartupBenchmark.kt (100%) create mode 100644 sentry-samples/sentry-samples-android/settings.gradle.kts diff --git a/.github/workflows/format-code.yml b/.github/workflows/format-code.yml index fb1a1da7102..522baa31cda 100644 --- a/.github/workflows/format-code.yml +++ b/.github/workflows/format-code.yml @@ -20,7 +20,9 @@ jobs: uses: gradle/actions/setup-gradle@8da46b539cd8fe6ab27ca75128919a18d757604c # v6.4.1 - name: Format with spotlessApply - run: ./gradlew spotlessApply + run: | + ./gradlew spotlessApply + ./gradlew -p sentry-samples/sentry-samples-android spotlessApply # actions/checkout fetches only a single commit in a detached HEAD state. Therefore # we need to pass the current branch, otherwise we can't commit the changes. diff --git a/.github/workflows/integration-tests-macrobenchmark.yml b/.github/workflows/integration-tests-macrobenchmark.yml index 654e8c17f76..eb1778adcd8 100644 --- a/.github/workflows/integration-tests-macrobenchmark.yml +++ b/.github/workflows/integration-tests-macrobenchmark.yml @@ -1,5 +1,5 @@ name: 'Integration Tests - Macrobenchmark' -# Runs the sentry-uitest-android-macrobenchmark cold-start benchmark on a Sauce Labs real +# Runs the sentry-samples-android macrobenchmark cold-start benchmark on a Sauce Labs real # device and recovers timeToInitialDisplay from the device log. # on: @@ -33,7 +33,7 @@ jobs: - name: Assemble target app and Macrobenchmark apk if: env.SAUCE_USERNAME != null - run: ./gradlew :sentry-samples:sentry-samples-android:assembleRelease :sentry-android-integration-tests:sentry-uitest-android-macrobenchmark:assembleBenchmark + run: ./gradlew -p sentry-samples/sentry-samples-android :assembleRelease :macrobenchmark:assembleBenchmark - name: Run Macrobenchmark in SauceLab uses: saucelabs/saucectl-run-action@283660aa934c02723c497efa151d582a3acc5801 # pin@v3 diff --git a/.sauce/sentry-uitest-android-macrobenchmark.yml b/.sauce/sentry-uitest-android-macrobenchmark.yml index 4e3d5cfbb3d..a6ef85e7c4a 100644 --- a/.sauce/sentry-uitest-android-macrobenchmark.yml +++ b/.sauce/sentry-uitest-android-macrobenchmark.yml @@ -15,7 +15,7 @@ defaults: espresso: app: ./sentry-samples/sentry-samples-android/build/outputs/apk/release/sentry-samples-android-release.apk - testApp: ./sentry-android-integration-tests/sentry-uitest-android-macrobenchmark/build/outputs/apk/benchmark/sentry-uitest-android-macrobenchmark-benchmark.apk + testApp: ./sentry-samples/sentry-samples-android/macrobenchmark/build/outputs/apk/benchmark/macrobenchmark-benchmark.apk suites: diff --git a/AGENTS.md b/AGENTS.md index 68a7bdfb74e..848045ad742 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -64,6 +64,9 @@ resolves the per-module test task, including integration test suites, for you. # Run critical UI tests ./scripts/test-ui-critical.sh + +# Build the Android sample, a separate Gradle build that includes this one +./gradlew -p sentry-samples/sentry-samples-android assembleDebug ``` ## Development Workflow Rules @@ -110,7 +113,7 @@ The repository is organized into multiple modules: ### Utility Modules - **`sentry-test-support`** - Shared test utilities, including `MockSentryServer` and envelope matchers -- **`sentry-samples`** - Example applications +- **`sentry-samples`** - Example applications. `sentry-samples-android` is a separate Gradle build that includes this one, so root tasks such as `check` and `spotlessApply` don't reach it - **`sentry-bom`** - Bill of Materials for dependency management ### Key Architectural Patterns diff --git a/Makefile b/Makefile index c5bb6ac2313..414ccec440a 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ -.PHONY: all clean compile javadocs dryRelease update checkFormat api assembleUiTestRelease assembleUiTestCriticalRelease runUiTestCritical check preMerge publish +.PHONY: all clean compile javadocs dryRelease update checkFormat api assembleUiTestRelease assembleUiTestCriticalRelease runUiTestCritical check checkSampleAndroid preMerge publish all: stop clean javadocs compile assembleUiTests: assembleUiTestRelease -preMerge: check +preMerge: check checkSampleAndroid publish: clean dryRelease # deep clean @@ -28,6 +28,7 @@ update: # Spotless check's code checkFormat: ./gradlew spotlessJavaCheck spotlessKotlinCheck + ./gradlew -p sentry-samples/sentry-samples-android spotlessJavaCheck spotlessKotlinCheck # Binary compatibility validator api: @@ -48,3 +49,7 @@ runUiTestCritical: # Run tests and lint check: ./gradlew check + +# The Android sample is a separate build, so the root `check` doesn't reach it +checkSampleAndroid: + ./gradlew -p sentry-samples/sentry-samples-android check diff --git a/sentry-samples/sentry-samples-android/README.md b/sentry-samples/sentry-samples-android/README.md index b065b91e955..35692c7b837 100644 --- a/sentry-samples/sentry-samples-android/README.md +++ b/sentry-samples/sentry-samples-android/README.md @@ -8,18 +8,21 @@ profiling) and integrations (Compose, OkHttp, SQLite, etc.). Install the app on your device or emulator: ``` -./gradlew :sentry-samples:sentry-samples-android:installDebug +./gradlew -p sentry-samples/sentry-samples-android installDebug ``` -or simply open the project in Android Studio and run the `sentry-samples-android` configuration. +or open the `sentry-samples/sentry-samples-android` directory in Android Studio and run the `sentry-samples-android` configuration. + +The sample is a separate Gradle build that includes the SDK build, so changes to the SDK show up in the next build of the sample, with nothing to publish first. +The SDK build doesn't include the sample, so `./gradlew` from the repository root doesn't build, lint or format it. You can also apply the [Sentry Android Gradle Plugin](https://github.com/getsentry/sentry-android-gradle-plugin) (SAGP) when building (not applied by default): ``` -./gradlew :sentry-samples:sentry-samples-android:installDebug -PuseSagp +./gradlew -p sentry-samples/sentry-samples-android installDebug -PuseSagp ``` -In Android Studio, add `useSagp=` (empty value) to `gradle.properties`, or pass `-PuseSagp` as a Gradle project property. +In Android Studio, add `useSagp=` (empty value) to the sample's `gradle.properties`, or pass `-PuseSagp` as a Gradle project property. For LLM-driven verification, use `adb` to inspect and interact with the running emulator. Compose-based screens often expose stable `Modifier.testTag()` values, which can be used with the UI hierarchy dump to locate controls reliably. @@ -55,7 +58,7 @@ Re-run `publishToMavenLocal` after each SAGP change. Then build from sentry-java: ``` -./gradlew :sentry-samples:sentry-samples-android:installDebug -PuseSagp +./gradlew -p sentry-samples/sentry-samples-android installDebug -PuseSagp ``` ## Viewing SDK output diff --git a/sentry-samples/sentry-samples-android/build.gradle.kts b/sentry-samples/sentry-samples-android/build.gradle.kts index 1c70c5b69ae..8fb29bb4ecd 100644 --- a/sentry-samples/sentry-samples-android/build.gradle.kts +++ b/sentry-samples/sentry-samples-android/build.gradle.kts @@ -8,16 +8,18 @@ import org.gradle.internal.extensions.stdlib.capitalized import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion plugins { - id("com.android.application") + alias(libs.plugins.android.application) + id("io.sentry.spotless") + id("io.sentry.jdk-target") alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.compose) alias(libs.plugins.ksp) alias(libs.plugins.sentry) apply false alias(libs.plugins.sqldelight) - id("io.sentry.spotless") - id("io.sentry.jdk-target") } +val sentryVersion = libs.versions.sentry.get() + if (providers.gradleProperty("useSagp").isPresent) { apply(plugin = "io.sentry.android.gradle") } @@ -55,7 +57,7 @@ android { minSdk = 23 targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 2 - versionName = project.version.toString() + versionName = sentryVersion externalNativeBuild { cmake { @@ -106,7 +108,7 @@ android { signingConfigs { getByName("debug") { - storeFile = rootProject.file("debug.keystore") + storeFile = file("../../debug.keystore") storePassword = "android" keyAlias = "androiddebugkey" keyPassword = "android" @@ -148,7 +150,7 @@ android { val toggleNativeLoggingTask = project.tasks.register(taskName) { mergedManifest.set(variant.artifacts.get(SingleArtifact.MERGED_MANIFEST)) - rootDir.set(project.rootDir.absolutePath) + repoDir.set(layout.projectDirectory.dir("../..").asFile.canonicalPath) } project.afterEvaluate { (variant as? VariantImpl<*>)?.taskContainer?.assembleTask?.configure { @@ -177,19 +179,19 @@ sqldelight { dependencies { implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) - implementation(projects.sentryAndroid) - implementation(projects.sentryAndroidFragment) - implementation(projects.sentryAndroidNavigation) - implementation(projects.sentryAndroidNavigation3) - implementation(projects.sentryAndroidSqlite) - implementation(projects.sentryAndroidTimber) - implementation(projects.sentryCompose) - implementation(projects.sentryKotlinExtensions) - implementation(projects.sentryOkhttp) - implementation(projects.sentrySpotlight) + implementation("io.sentry:sentry-android:$sentryVersion") + implementation("io.sentry:sentry-android-fragment:$sentryVersion") + implementation("io.sentry:sentry-android-navigation:$sentryVersion") + implementation("io.sentry:sentry-android-navigation3:$sentryVersion") + implementation("io.sentry:sentry-android-sqlite:$sentryVersion") + implementation("io.sentry:sentry-android-timber:$sentryVersion") + implementation("io.sentry:sentry-compose:$sentryVersion") + implementation("io.sentry:sentry-kotlin-extensions:$sentryVersion") + implementation("io.sentry:sentry-okhttp:$sentryVersion") + implementation("io.sentry:sentry-spotlight:$sentryVersion") // how to exclude androidx if release health feature is disabled - // implementation(projects.sentryAndroid) { + // implementation("io.sentry:sentry-android:$sentryVersion") { // exclude(group = "androidx.lifecycle", module = "lifecycle-process") // exclude(group = "androidx.lifecycle", module = "lifecycle-common-java8") // exclude(group = "androidx.core", module = "core") @@ -230,7 +232,7 @@ dependencies { ksp(libs.androidx.room.compiler) ksp(libs.androidx.room3.compiler) - debugImplementation(projects.sentryAndroidDistribution) + debugImplementation("io.sentry:sentry-android-distribution:$sentryVersion") debugImplementation(libs.leakcanary) testImplementation(libs.google.truth) @@ -238,7 +240,7 @@ dependencies { } abstract class ToggleNativeLoggingTask : Exec() { - @get:Input abstract val rootDir: Property + @get:Input abstract val repoDir: Property @get:InputFile abstract val mergedManifest: RegularFileProperty @@ -256,7 +258,7 @@ abstract class ToggleNativeLoggingTask : Exec() { args.add(0, "cmd") args.add(1, "/c") } - args.add("${rootDir.get()}/scripts/toggle-codec-logs.sh") + args.add("${repoDir.get()}/scripts/toggle-codec-logs.sh") args.add(if (value) "enable" else "disable") commandLine(args) super.exec() diff --git a/sentry-samples/sentry-samples-android/gradle.properties b/sentry-samples/sentry-samples-android/gradle.properties new file mode 100644 index 00000000000..8751888c1a0 --- /dev/null +++ b/sentry-samples/sentry-samples-android/gradle.properties @@ -0,0 +1,24 @@ +# Gradle properties are per build, so this repeats what the sample needs from the SDK build's +# gradle.properties. settings.gradle.kts reads the SDK version from that file. + +org.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=2g -XX:+CrashOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC +org.gradle.caching=true +org.gradle.parallel=true +org.gradle.configureondemand=true +org.gradle.configuration-cache=true +org.gradle.configuration-cache.parallel=true + +android.useAndroidX=true +# AGP 9+ migration opt-outs until we remove kotlin-android plugin and adopt built-in Kotlin. +android.builtInKotlin=false +android.newDsl=false + +android.defaults.buildfeatures.renderscript=false +android.defaults.buildfeatures.shaders=false +android.defaults.buildfeatures.aidl=false +android.defaults.buildfeatures.resvalues=false +android.nonTransitiveRClass=true + +kotlin.stdlib.default.dependency=false + +systemProp.org.gradle.internal.http.socketTimeout=120000 diff --git a/sentry-android-integration-tests/sentry-uitest-android-macrobenchmark/README.md b/sentry-samples/sentry-samples-android/macrobenchmark/README.md similarity index 97% rename from sentry-android-integration-tests/sentry-uitest-android-macrobenchmark/README.md rename to sentry-samples/sentry-samples-android/macrobenchmark/README.md index 9914825584d..23c5fab6921 100644 --- a/sentry-android-integration-tests/sentry-uitest-android-macrobenchmark/README.md +++ b/sentry-samples/sentry-samples-android/macrobenchmark/README.md @@ -1,4 +1,4 @@ -# sentry-uitest-android-macrobenchmark +# macrobenchmark Jetpack Macrobenchmark for cold-start of `sentry-samples-android`, used to evaluate SDK-init performance changes on a real device in a **stable, reproducible** way. Not run in CI. @@ -28,7 +28,7 @@ unlocked-clock device after ~14 iterations, inflating the tail of longer runs. Connect a device, then: ```bash -./gradlew :sentry-android-integration-tests:sentry-uitest-android-macrobenchmark:connectedBenchmarkAndroidTest +./gradlew -p sentry-samples/sentry-samples-android :macrobenchmark:connectedBenchmarkAndroidTest ``` Results print to the console and are written to diff --git a/sentry-android-integration-tests/sentry-uitest-android-macrobenchmark/build.gradle.kts b/sentry-samples/sentry-samples-android/macrobenchmark/build.gradle.kts similarity index 94% rename from sentry-android-integration-tests/sentry-uitest-android-macrobenchmark/build.gradle.kts rename to sentry-samples/sentry-samples-android/macrobenchmark/build.gradle.kts index 12da53b7721..b819504ddcb 100644 --- a/sentry-android-integration-tests/sentry-uitest-android-macrobenchmark/build.gradle.kts +++ b/sentry-samples/sentry-samples-android/macrobenchmark/build.gradle.kts @@ -1,8 +1,8 @@ plugins { id("com.android.test") - alias(libs.plugins.kotlin.android) id("io.sentry.spotless") id("io.sentry.jdk-target") + alias(libs.plugins.kotlin.android) } android { @@ -28,7 +28,8 @@ android { } } - targetProjectPath = ":sentry-samples:sentry-samples-android" + // The sample app is the root project of this build. + targetProjectPath = ":" // Run the test in its own process so it measures the target app cold, not itself. experimentalProperties["android.experimental.self-instrumenting"] = true } diff --git a/sentry-android-integration-tests/sentry-uitest-android-macrobenchmark/src/main/AndroidManifest.xml b/sentry-samples/sentry-samples-android/macrobenchmark/src/main/AndroidManifest.xml similarity index 100% rename from sentry-android-integration-tests/sentry-uitest-android-macrobenchmark/src/main/AndroidManifest.xml rename to sentry-samples/sentry-samples-android/macrobenchmark/src/main/AndroidManifest.xml diff --git a/sentry-android-integration-tests/sentry-uitest-android-macrobenchmark/src/main/java/io/sentry/uitest/android/macrobenchmark/SentryStartupBenchmark.kt b/sentry-samples/sentry-samples-android/macrobenchmark/src/main/java/io/sentry/uitest/android/macrobenchmark/SentryStartupBenchmark.kt similarity index 100% rename from sentry-android-integration-tests/sentry-uitest-android-macrobenchmark/src/main/java/io/sentry/uitest/android/macrobenchmark/SentryStartupBenchmark.kt rename to sentry-samples/sentry-samples-android/macrobenchmark/src/main/java/io/sentry/uitest/android/macrobenchmark/SentryStartupBenchmark.kt diff --git a/sentry-samples/sentry-samples-android/settings.gradle.kts b/sentry-samples/sentry-samples-android/settings.gradle.kts new file mode 100644 index 00000000000..06d5fc1c770 --- /dev/null +++ b/sentry-samples/sentry-samples-android/settings.gradle.kts @@ -0,0 +1,77 @@ +// A standalone build that includes the SDK build, so it depends on the SDK through the same +// io.sentry:* coordinates an app would, and Gradle substitutes the SDK's projects for them. +// The SDK build doesn't include this one back, so its plugins and versions stay out of the SDK +// build. Run it with `./gradlew -p sentry-samples/sentry-samples-android `. + +pluginManagement { + repositories { + // Prefer local SAGP artifact if one exists; otherwise fall back to libs.versions.toml. + if (providers.gradleProperty("useSagp").isPresent) { + mavenLocal { + content { + includeGroup("io.sentry") + includeGroup("io.sentry.android.gradle") + } + } + } + mavenCentral() + gradlePluginPortal() + google() + } + + // Every build in a composite must use the same AGP, so each build's settings applies the AGP + // matrix job's override. + System.getenv("VERSION_AGP")?.let { agpVersion -> + resolutionStrategy { + eachPlugin { + if (requested.id.id.startsWith("com.android")) { + useVersion(agpVersion) + } + } + } + } +} + +plugins { + id("com.gradle.develocity") version "4.5.0" + id("com.gradle.common-custom-user-data-gradle-plugin") version "2.8.0" +} + +develocity { + buildScan { + termsOfUseUrl.set("https://gradle.com/help/legal-terms-of-use") + termsOfUseAgree.set("yes") + } +} + +// Gradle reads gradle.properties only for the build it belongs to, so read the SDK version from the +// SDK build's file. +val sentryVersion: String = + providers + .fileContents(layout.settingsDirectory.file("../../gradle.properties")) + .asText + .map { java.util.Properties().apply { load(it.reader()) }.getProperty("versionName") } + .get() + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + mavenLocal() + } + versionCatalogs { + create("libs") { + from(files("../../gradle/libs.versions.toml")) + version("sentry", sentryVersion) + } + } +} + +rootProject.name = "sentry-samples-android" + +includeBuild("../..") + +// For the io.sentry.spotless and io.sentry.jdk-target convention plugins. +includeBuild("../../build-logic") + +include("macrobenchmark") diff --git a/settings.gradle.kts b/settings.gradle.kts index 2849794723f..378979411f0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -112,7 +112,6 @@ include( "sentry-reactor", "sentry-async-profiler", "sentry-ktor-client", - "sentry-samples:sentry-samples-android", "sentry-samples:sentry-samples-console", "sentry-samples:sentry-samples-console-otlp", "sentry-samples:sentry-samples-console-opentelemetry-noagent", @@ -141,7 +140,6 @@ include( "sentry-samples:sentry-samples-spring-boot-4-webflux", "sentry-samples:sentry-samples-netflix-dgs", "sentry-android-integration-tests:sentry-uitest-android-critical", - "sentry-android-integration-tests:sentry-uitest-android-macrobenchmark", "sentry-android-integration-tests:sentry-uitest-android", "sentry-android-integration-tests:test-app-size", "sentry-samples:sentry-samples-openfeign" From 12236dd49ebdd8e4a195fe37ca3a4c77ad65d29f Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 2 Nov 2026 14:12:57 +0100 Subject: [PATCH 04/21] ci(samples): Run the Android sample's check in its own workflow Instead of adding it to `make preMerge`, which the SDK's Build job runs, a new Samples workflow runs the Android sample build's `check` as its own job. A broken sample then fails its own check, it runs in parallel with the SDK build, and the Build job doesn't get longer. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/samples.yml | 76 +++++++++++++++++++++++++++++++++++ Makefile | 8 +--- 2 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/samples.yml diff --git a/.github/workflows/samples.yml b/.github/workflows/samples.yml new file mode 100644 index 00000000000..b34f8fff744 --- /dev/null +++ b/.github/workflows/samples.yml @@ -0,0 +1,76 @@ +name: 'Samples' +# Runs `check` in each build the SDK build doesn't include, so a broken sample or +# integration test fails its own job instead of the SDK's Build job. +on: + push: + branches: + - main + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + check: + name: Check ${{ matrix.name }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + include: + - name: sentry-samples-android + path: sentry-samples/sentry-samples-android + + env: + GRADLE_ENCRYPTION_KEY: ${{ secrets.GRADLE_ENCRYPTION_KEY }} + + steps: + - name: Checkout Repo + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} + submodules: 'recursive' + + - name: Setup Java Version + uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0 + with: + distribution: 'temurin' + java-version: '21' + + # Workaround for https://github.com/gradle/actions/issues/21 to use config cache + - name: Cache buildSrc + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: buildSrc/build + key: build-logic-${{ hashFiles('buildSrc/src/**', 'buildSrc/build.gradle.kts','buildSrc/settings.gradle.kts') }} + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0 + with: + cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} + + - name: Run Tests and Lint + run: ./gradlew -p ${{ matrix.path }} check + + - name: Upload test results + if: always() + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 + with: + name: test-results-${{ matrix.name }} + path: | + **/build/reports/* + + - name: Test Report + uses: phoenix-actions/test-reporting@7317eea6e13c47348dd0bb318669485157c518d6 # pin@v16 + if: always() + with: + name: JUnit ${{ matrix.name }} + list-suites: 'failed' + list-tests: 'failed' + path: | + **/build/test-results/**/*.xml + reporter: java-junit + output-to: step-summary + fail-on-error: false diff --git a/Makefile b/Makefile index 414ccec440a..45c6ed2a7a0 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ -.PHONY: all clean compile javadocs dryRelease update checkFormat api assembleUiTestRelease assembleUiTestCriticalRelease runUiTestCritical check checkSampleAndroid preMerge publish +.PHONY: all clean compile javadocs dryRelease update checkFormat api assembleUiTestRelease assembleUiTestCriticalRelease runUiTestCritical check preMerge publish all: stop clean javadocs compile assembleUiTests: assembleUiTestRelease -preMerge: check checkSampleAndroid +preMerge: check publish: clean dryRelease # deep clean @@ -49,7 +49,3 @@ runUiTestCritical: # Run tests and lint check: ./gradlew check - -# The Android sample is a separate build, so the root `check` doesn't reach it -checkSampleAndroid: - ./gradlew -p sentry-samples/sentry-samples-android check From 6feed075b1a0857c1d8e009ee61d08cb5247cfc7 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 2 Nov 2026 15:41:37 +0100 Subject: [PATCH 05/21] ci(samples): Drop the Gradle encryption key and buildSrc cache from the Samples workflow Co-Authored-By: Claude Opus 5.5 --- .github/workflows/samples.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/samples.yml b/.github/workflows/samples.yml index b34f8fff744..839dae6025f 100644 --- a/.github/workflows/samples.yml +++ b/.github/workflows/samples.yml @@ -23,9 +23,6 @@ jobs: - name: sentry-samples-android path: sentry-samples/sentry-samples-android - env: - GRADLE_ENCRYPTION_KEY: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - steps: - name: Checkout Repo uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -39,17 +36,8 @@ jobs: distribution: 'temurin' java-version: '21' - # Workaround for https://github.com/gradle/actions/issues/21 to use config cache - - name: Cache buildSrc - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: buildSrc/build - key: build-logic-${{ hashFiles('buildSrc/src/**', 'buildSrc/build.gradle.kts','buildSrc/settings.gradle.kts') }} - - name: Setup Gradle uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0 - with: - cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - name: Run Tests and Lint run: ./gradlew -p ${{ matrix.path }} check From 25b7d711f06a83e5a36218ff45e31cce8b5cb8b5 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 2 Nov 2026 15:52:28 +0100 Subject: [PATCH 06/21] ci(samples): Check out the default ref without submodules in the Samples workflow The head-SHA ref only matters for build.yml's snapshot upload, and the repository has had no submodules since #3189. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/samples.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/samples.yml b/.github/workflows/samples.yml index 839dae6025f..238f4f3debd 100644 --- a/.github/workflows/samples.yml +++ b/.github/workflows/samples.yml @@ -26,9 +26,6 @@ jobs: steps: - name: Checkout Repo uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - ref: ${{ github.event.pull_request.head.sha || github.sha }} - submodules: 'recursive' - name: Setup Java Version uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0 From 8a10160f7ba7d111fe63b627b76304918488a3f7 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 15:29:50 +0100 Subject: [PATCH 07/21] build(samples): Link the Android sample's Gradle files to the SDK build's gradle.properties, gradlew, gradle/wrapper and gradle/gradle-daemon-jvm.properties are now symlinks to the SDK build's files. Both builds pick the same daemon JDK and JVM arguments, so they can share a daemon, and the sample reads the SDK version from the versionName property instead of parsing the root file. The copied gradle.properties had drifted from the root one (-Xmx6g and CrashOnOutOfMemoryError instead of -Xmx8g and HeapDumpOnOutOfMemoryError). Dependabot also scans the sample build, so the Develocity plugins in its settings stay current. Co-Authored-By: Claude Opus 5.5 --- .github/dependabot.yml | 5 +++- .../sentry-samples-android/README.md | 3 ++- .../sentry-samples-android/build.gradle.kts | 3 ++- .../sentry-samples-android/gradle.properties | 25 +------------------ .../gradle/gradle-daemon-jvm.properties | 1 + .../sentry-samples-android/gradle/wrapper | 1 + sentry-samples/sentry-samples-android/gradlew | 1 + .../settings.gradle.kts | 16 +----------- 8 files changed, 13 insertions(+), 42 deletions(-) mode change 100644 => 120000 sentry-samples/sentry-samples-android/gradle.properties create mode 120000 sentry-samples/sentry-samples-android/gradle/gradle-daemon-jvm.properties create mode 120000 sentry-samples/sentry-samples-android/gradle/wrapper create mode 120000 sentry-samples/sentry-samples-android/gradlew diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2824699563c..fb278498bcf 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,7 +7,10 @@ registries: password: dummy # Required by dependabot updates: - package-ecosystem: "gradle" - directory: "/" + # The Android sample is a separate build that the root build doesn't include. + directories: + - "/" + - "/sentry-samples/sentry-samples-android" registries: - gradle-plugin-portal schedule: diff --git a/sentry-samples/sentry-samples-android/README.md b/sentry-samples/sentry-samples-android/README.md index 35692c7b837..2c2b328e43e 100644 --- a/sentry-samples/sentry-samples-android/README.md +++ b/sentry-samples/sentry-samples-android/README.md @@ -15,6 +15,7 @@ or open the `sentry-samples/sentry-samples-android` directory in Android Studio The sample is a separate Gradle build that includes the SDK build, so changes to the SDK show up in the next build of the sample, with nothing to publish first. The SDK build doesn't include the sample, so `./gradlew` from the repository root doesn't build, lint or format it. +`gradle.properties`, `gradlew`, `gradle/wrapper` and `gradle/gradle-daemon-jvm.properties` are symlinks to the SDK build's, so both builds use the same Gradle, JDK and settings. You can also apply the [Sentry Android Gradle Plugin](https://github.com/getsentry/sentry-android-gradle-plugin) (SAGP) when building (not applied by default): @@ -22,7 +23,7 @@ You can also apply the [Sentry Android Gradle Plugin](https://github.com/getsent ./gradlew -p sentry-samples/sentry-samples-android installDebug -PuseSagp ``` -In Android Studio, add `useSagp=` (empty value) to the sample's `gradle.properties`, or pass `-PuseSagp` as a Gradle project property. +In Android Studio, add `useSagp=` (empty value) to `gradle.properties`, or pass `-PuseSagp` as a Gradle project property. For LLM-driven verification, use `adb` to inspect and interact with the running emulator. Compose-based screens often expose stable `Modifier.testTag()` values, which can be used with the UI hierarchy dump to locate controls reliably. diff --git a/sentry-samples/sentry-samples-android/build.gradle.kts b/sentry-samples/sentry-samples-android/build.gradle.kts index 8fb29bb4ecd..30e05043d8f 100644 --- a/sentry-samples/sentry-samples-android/build.gradle.kts +++ b/sentry-samples/sentry-samples-android/build.gradle.kts @@ -18,7 +18,8 @@ plugins { alias(libs.plugins.sqldelight) } -val sentryVersion = libs.versions.sentry.get() +// gradle.properties links to the SDK build's, so this is the SDK version. +val sentryVersion = providers.gradleProperty("versionName").get() if (providers.gradleProperty("useSagp").isPresent) { apply(plugin = "io.sentry.android.gradle") diff --git a/sentry-samples/sentry-samples-android/gradle.properties b/sentry-samples/sentry-samples-android/gradle.properties deleted file mode 100644 index 8751888c1a0..00000000000 --- a/sentry-samples/sentry-samples-android/gradle.properties +++ /dev/null @@ -1,24 +0,0 @@ -# Gradle properties are per build, so this repeats what the sample needs from the SDK build's -# gradle.properties. settings.gradle.kts reads the SDK version from that file. - -org.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=2g -XX:+CrashOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -org.gradle.caching=true -org.gradle.parallel=true -org.gradle.configureondemand=true -org.gradle.configuration-cache=true -org.gradle.configuration-cache.parallel=true - -android.useAndroidX=true -# AGP 9+ migration opt-outs until we remove kotlin-android plugin and adopt built-in Kotlin. -android.builtInKotlin=false -android.newDsl=false - -android.defaults.buildfeatures.renderscript=false -android.defaults.buildfeatures.shaders=false -android.defaults.buildfeatures.aidl=false -android.defaults.buildfeatures.resvalues=false -android.nonTransitiveRClass=true - -kotlin.stdlib.default.dependency=false - -systemProp.org.gradle.internal.http.socketTimeout=120000 diff --git a/sentry-samples/sentry-samples-android/gradle.properties b/sentry-samples/sentry-samples-android/gradle.properties new file mode 120000 index 00000000000..03ca90c515b --- /dev/null +++ b/sentry-samples/sentry-samples-android/gradle.properties @@ -0,0 +1 @@ +../../gradle.properties \ No newline at end of file diff --git a/sentry-samples/sentry-samples-android/gradle/gradle-daemon-jvm.properties b/sentry-samples/sentry-samples-android/gradle/gradle-daemon-jvm.properties new file mode 120000 index 00000000000..b6233ee4449 --- /dev/null +++ b/sentry-samples/sentry-samples-android/gradle/gradle-daemon-jvm.properties @@ -0,0 +1 @@ +../../../gradle/gradle-daemon-jvm.properties \ No newline at end of file diff --git a/sentry-samples/sentry-samples-android/gradle/wrapper b/sentry-samples/sentry-samples-android/gradle/wrapper new file mode 120000 index 00000000000..166ffc09a82 --- /dev/null +++ b/sentry-samples/sentry-samples-android/gradle/wrapper @@ -0,0 +1 @@ +../../../gradle/wrapper \ No newline at end of file diff --git a/sentry-samples/sentry-samples-android/gradlew b/sentry-samples/sentry-samples-android/gradlew new file mode 120000 index 00000000000..343e0d2caa4 --- /dev/null +++ b/sentry-samples/sentry-samples-android/gradlew @@ -0,0 +1 @@ +../../gradlew \ No newline at end of file diff --git a/sentry-samples/sentry-samples-android/settings.gradle.kts b/sentry-samples/sentry-samples-android/settings.gradle.kts index 06d5fc1c770..b8b12cc6993 100644 --- a/sentry-samples/sentry-samples-android/settings.gradle.kts +++ b/sentry-samples/sentry-samples-android/settings.gradle.kts @@ -44,27 +44,13 @@ develocity { } } -// Gradle reads gradle.properties only for the build it belongs to, so read the SDK version from the -// SDK build's file. -val sentryVersion: String = - providers - .fileContents(layout.settingsDirectory.file("../../gradle.properties")) - .asText - .map { java.util.Properties().apply { load(it.reader()) }.getProperty("versionName") } - .get() - dependencyResolutionManagement { repositories { google() mavenCentral() mavenLocal() } - versionCatalogs { - create("libs") { - from(files("../../gradle/libs.versions.toml")) - version("sentry", sentryVersion) - } - } + versionCatalogs { create("libs") { from(files("../../gradle/libs.versions.toml")) } } } rootProject.name = "sentry-samples-android" From 238755642caf2090a81bd1e34544c14b5dd55e48 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 15:34:50 +0100 Subject: [PATCH 08/21] ci(samples): Drop the JUnit report step from the Samples workflow The samples and integration test builds have no unit tests, and phoenix-actions/test-reporting fails the job when it finds no JUnit XML, even with fail-on-error set to false. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/samples.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.github/workflows/samples.yml b/.github/workflows/samples.yml index 238f4f3debd..819204d8e4b 100644 --- a/.github/workflows/samples.yml +++ b/.github/workflows/samples.yml @@ -46,16 +46,3 @@ jobs: name: test-results-${{ matrix.name }} path: | **/build/reports/* - - - name: Test Report - uses: phoenix-actions/test-reporting@7317eea6e13c47348dd0bb318669485157c518d6 # pin@v16 - if: always() - with: - name: JUnit ${{ matrix.name }} - list-suites: 'failed' - list-tests: 'failed' - path: | - **/build/test-results/**/*.xml - reporter: java-junit - output-to: step-summary - fail-on-error: false From c30bc10ac710c8ee64d787fe5768cc31a6fa260c Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 17:31:10 +0100 Subject: [PATCH 09/21] build(samples): Bring back make format for every build The root spotlessApply can't reach the Android sample, because the SDK build doesn't include it. make format runs spotlessApply in the root and in the sample build, and the format workflow, AGENTS.md, CONTRIBUTING.md and the create-java-pr skill use it. CONTRIBUTING.md already documented make format, which #4476 removed. Co-Authored-By: Claude Opus 5.5 --- .claude/skills/create-java-pr/SKILL.md | 4 ++-- .github/workflows/format-code.yml | 4 +--- AGENTS.md | 6 +++--- CONTRIBUTING.md | 6 +----- Makefile | 7 ++++++- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.claude/skills/create-java-pr/SKILL.md b/.claude/skills/create-java-pr/SKILL.md index 70bc4453a58..ef813f4b1c8 100644 --- a/.claude/skills/create-java-pr/SKILL.md +++ b/.claude/skills/create-java-pr/SKILL.md @@ -74,10 +74,10 @@ Derive the branch name from the changes being made. Use `feat/`, `fix/`, `ref/`, ## Step 2: Format Code and Regenerate API Files ```bash -./gradlew spotlessApply updateKotlinAbi +make format api ``` -This is **required** before every PR in this repo. It formats all Java/Kotlin code via Spotless and regenerates the `.api` binary compatibility files. +This is **required** before every PR in this repo. It formats all Java/Kotlin code via Spotless, including the separate builds the root `spotlessApply` doesn't reach, and regenerates the `.api` binary compatibility files. If the command fails, diagnose and fix the issue before continuing. diff --git a/.github/workflows/format-code.yml b/.github/workflows/format-code.yml index 522baa31cda..e55cddb74fd 100644 --- a/.github/workflows/format-code.yml +++ b/.github/workflows/format-code.yml @@ -20,9 +20,7 @@ jobs: uses: gradle/actions/setup-gradle@8da46b539cd8fe6ab27ca75128919a18d757604c # v6.4.1 - name: Format with spotlessApply - run: | - ./gradlew spotlessApply - ./gradlew -p sentry-samples/sentry-samples-android spotlessApply + run: make format # actions/checkout fetches only a single commit in a detached HEAD state. Therefore # we need to pass the current branch, otherwise we can't commit the changes. diff --git a/AGENTS.md b/AGENTS.md index 848045ad742..378168cb49c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -41,8 +41,8 @@ The project uses **Gradle** with Kotlin DSL. Key build files: ## Essential Commands ```bash -# Format code and regenerate .api files (REQUIRED before committing) -./gradlew spotlessApply updateKotlinAbi +# Format code in every build and regenerate .api files (REQUIRED before committing) +make format api # Run all tests and linter ./gradlew check @@ -77,7 +77,7 @@ resolves the per-module test task, including integration test suites, for you. 3. **Use todo tracking**: Work through todo items, marking them as complete as you go 4. **High-level communication**: Give high-level explanations of changes made, not step-by-step descriptions 5. **Simplicity first**: Make every task and code change as simple as possible. Avoid massive or complex changes. Impact as little code as possible. -6. **Format and regenerate**: Once done, format code and regenerate .api files: `./gradlew spotlessApply updateKotlinAbi` +6. **Format and regenerate**: Once done, format code and regenerate .api files: `make format api` 7. **Propose commit**: As final step, git stage relevant files and propose (but not execute) a single git commit command. This applies to implementation work; when the task is to open a PR, the `create-java-pr` skill takes over from here and does commit, push, and open it. ## Repository Skills diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 77714917518..d0642308ff8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -73,11 +73,7 @@ To format the changed code and make CI happy you can run: make format ``` -or - -```shell -./gradlew spotlessApply -``` +`./gradlew spotlessApply` alone formats only the SDK build, not the separate builds it doesn't include, such as the Android sample. # Binary compatibility validation diff --git a/Makefile b/Makefile index 45c6ed2a7a0..14f1ce9326c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all clean compile javadocs dryRelease update checkFormat api assembleUiTestRelease assembleUiTestCriticalRelease runUiTestCritical check preMerge publish +.PHONY: all clean compile javadocs dryRelease update format checkFormat api assembleUiTestRelease assembleUiTestCriticalRelease runUiTestCritical check preMerge publish all: stop clean javadocs compile assembleUiTests: assembleUiTestRelease @@ -25,6 +25,11 @@ dryRelease: update: ./gradlew dependencyUpdates -Drevision=release +# Spotless formats the code. The root spotlessApply doesn't reach the separate builds. +format: + ./gradlew spotlessApply + ./gradlew -p sentry-samples/sentry-samples-android spotlessApply + # Spotless check's code checkFormat: ./gradlew spotlessJavaCheck spotlessKotlinCheck From f37c574728923cfbd345b5f4df27a04560a978af Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 18:15:32 +0100 Subject: [PATCH 10/21] build(samples): Read the sample's SDK version through the catalog The sample's settings now add versionName to the catalog as libs.versions.sentry, as the other separate builds do, and use the root build's Develocity plugin version. Co-Authored-By: Claude Opus 5.5 --- sentry-samples/sentry-samples-android/build.gradle.kts | 3 +-- .../sentry-samples-android/settings.gradle.kts | 10 ++++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/sentry-samples/sentry-samples-android/build.gradle.kts b/sentry-samples/sentry-samples-android/build.gradle.kts index 30e05043d8f..8fb29bb4ecd 100644 --- a/sentry-samples/sentry-samples-android/build.gradle.kts +++ b/sentry-samples/sentry-samples-android/build.gradle.kts @@ -18,8 +18,7 @@ plugins { alias(libs.plugins.sqldelight) } -// gradle.properties links to the SDK build's, so this is the SDK version. -val sentryVersion = providers.gradleProperty("versionName").get() +val sentryVersion = libs.versions.sentry.get() if (providers.gradleProperty("useSagp").isPresent) { apply(plugin = "io.sentry.android.gradle") diff --git a/sentry-samples/sentry-samples-android/settings.gradle.kts b/sentry-samples/sentry-samples-android/settings.gradle.kts index b8b12cc6993..d36c09c1554 100644 --- a/sentry-samples/sentry-samples-android/settings.gradle.kts +++ b/sentry-samples/sentry-samples-android/settings.gradle.kts @@ -33,7 +33,7 @@ pluginManagement { } plugins { - id("com.gradle.develocity") version "4.5.0" + id("com.gradle.develocity") version "4.6.1" id("com.gradle.common-custom-user-data-gradle-plugin") version "2.8.0" } @@ -50,7 +50,13 @@ dependencyResolutionManagement { mavenCentral() mavenLocal() } - versionCatalogs { create("libs") { from(files("../../gradle/libs.versions.toml")) } } + versionCatalogs { + create("libs") { + from(files("../../gradle/libs.versions.toml")) + // gradle.properties links to the SDK build's, so versionName is the SDK version. + version("sentry", providers.gradleProperty("versionName").get()) + } + } } rootProject.name = "sentry-samples-android" From 07cd03b42b664d0779c96ad6426222c3801831bd Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 18:15:32 +0100 Subject: [PATCH 11/21] ci(samples): Use the setup-gradle version of the other workflows Co-Authored-By: Claude Opus 5.5 --- .github/dependabot.yml | 2 +- .github/workflows/samples.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index fb278498bcf..8015fe0a0d8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,7 +7,7 @@ registries: password: dummy # Required by dependabot updates: - package-ecosystem: "gradle" - # The Android sample is a separate build that the root build doesn't include. + # The root build doesn't include the separate sample and test builds. directories: - "/" - "/sentry-samples/sentry-samples-android" diff --git a/.github/workflows/samples.yml b/.github/workflows/samples.yml index 819204d8e4b..70e42119c49 100644 --- a/.github/workflows/samples.yml +++ b/.github/workflows/samples.yml @@ -34,7 +34,7 @@ jobs: java-version: '21' - name: Setup Gradle - uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0 + uses: gradle/actions/setup-gradle@8da46b539cd8fe6ab27ca75128919a18d757604c # v6.4.1 - name: Run Tests and Lint run: ./gradlew -p ${{ matrix.path }} check From 0eb159e4eafaa23d371a7b6c5a76ed4c81978b90 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 18:31:21 +0100 Subject: [PATCH 12/21] build(samples): Drop the comment on the macrobenchmark's target project Co-Authored-By: Claude Opus 5.5 --- .../sentry-samples-android/macrobenchmark/build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/sentry-samples/sentry-samples-android/macrobenchmark/build.gradle.kts b/sentry-samples/sentry-samples-android/macrobenchmark/build.gradle.kts index b819504ddcb..a26fe088cd7 100644 --- a/sentry-samples/sentry-samples-android/macrobenchmark/build.gradle.kts +++ b/sentry-samples/sentry-samples-android/macrobenchmark/build.gradle.kts @@ -28,7 +28,6 @@ android { } } - // The sample app is the root project of this build. targetProjectPath = ":" // Run the test in its own process so it measures the target app cold, not itself. experimentalProperties["android.experimental.self-instrumenting"] = true From 6a678c67f8a5b890ec908099974aafcd79b19d21 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 18:34:09 +0100 Subject: [PATCH 13/21] build(samples): Drop the header comment from the Android sample's settings Co-Authored-By: Claude Opus 5.5 --- sentry-samples/sentry-samples-android/settings.gradle.kts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sentry-samples/sentry-samples-android/settings.gradle.kts b/sentry-samples/sentry-samples-android/settings.gradle.kts index d36c09c1554..9d024bf958a 100644 --- a/sentry-samples/sentry-samples-android/settings.gradle.kts +++ b/sentry-samples/sentry-samples-android/settings.gradle.kts @@ -1,8 +1,3 @@ -// A standalone build that includes the SDK build, so it depends on the SDK through the same -// io.sentry:* coordinates an app would, and Gradle substitutes the SDK's projects for them. -// The SDK build doesn't include this one back, so its plugins and versions stay out of the SDK -// build. Run it with `./gradlew -p sentry-samples/sentry-samples-android `. - pluginManagement { repositories { // Prefer local SAGP artifact if one exists; otherwise fall back to libs.versions.toml. From 070f5c9f980383031a36614b49749e09cf32f276 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Tue, 27 Oct 2026 13:03:54 +0100 Subject: [PATCH 14/21] build(samples): Move the Android integration tests to their own build sentry-uitest-android, sentry-uitest-android-critical and test-app-size are now a standalone Gradle build that includes the SDK build, like the Android sample. They depend on io.sentry:* coordinates, which Gradle substitutes with the SDK's projects, including the unpublished sentry-test-support. The SDK build doesn't include them back, so SAGP, errorprone's uitest checks and their AndroidX test dependencies no longer load in the SDK build. AGP stays shared: a composite build can only use one AGP version, so the AGP matrix job's VERSION_AGP still applies to both builds. Root check and spotlessApply no longer reach these apps, so preMerge runs this build's check, which covers what the root check ran for them: lint, detekt and spotless. The format workflow runs its spotlessApply, and the AGP matrix, UI test and size workflows call it with -p. APK paths don't change. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/integration-tests-size.yml | 2 +- AGENTS.md | 4 +- Makefile | 14 +++- scripts/test-ui-android.sh | 2 +- sentry-android-integration-tests/README.md | 4 + .../build.gradle.kts | 10 +++ .../gradle.properties | 24 ++++++ .../build.gradle.kts | 4 +- .../sentry-uitest-android/README.md | 2 +- .../sentry-uitest-android/build.gradle.kts | 20 +++-- .../settings.gradle.kts | 77 +++++++++++++++++++ .../test-app-size/build.gradle.kts | 16 ++-- settings.gradle.kts | 3 - 13 files changed, 156 insertions(+), 26 deletions(-) create mode 100644 sentry-android-integration-tests/build.gradle.kts create mode 100644 sentry-android-integration-tests/gradle.properties create mode 100644 sentry-android-integration-tests/settings.gradle.kts diff --git a/.github/workflows/integration-tests-size.yml b/.github/workflows/integration-tests-size.yml index 9705499f430..4254edcf4b2 100644 --- a/.github/workflows/integration-tests-size.yml +++ b/.github/workflows/integration-tests-size.yml @@ -29,6 +29,6 @@ jobs: uses: gradle/actions/setup-gradle@8da46b539cd8fe6ab27ca75128919a18d757604c # v6.4.1 - name: Size Analysis - run: ./gradlew :sentry-android-integration-tests:test-app-size:bundleRelease + run: ./gradlew -p sentry-android-integration-tests :test-app-size:bundleRelease env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} diff --git a/AGENTS.md b/AGENTS.md index 378168cb49c..8895b5fb658 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -59,8 +59,8 @@ resolves the per-module test task, including integration test suites, for you. ### Android-Specific Commands ```bash -# Assemble Android test APKs -./gradlew :sentry-android-integration-tests:sentry-uitest-android:assembleRelease :sentry-android-integration-tests:sentry-uitest-android:assembleAndroidTest +# Assemble Android test APKs, in a separate Gradle build that includes this one +./gradlew -p sentry-android-integration-tests :sentry-uitest-android:assembleRelease :sentry-uitest-android:assembleAndroidTest # Run critical UI tests ./scripts/test-ui-critical.sh diff --git a/Makefile b/Makefile index 14f1ce9326c..dca9b7bbe12 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ -.PHONY: all clean compile javadocs dryRelease update format checkFormat api assembleUiTestRelease assembleUiTestCriticalRelease runUiTestCritical check preMerge publish +.PHONY: all clean compile javadocs dryRelease update format checkFormat api assembleUiTestRelease assembleUiTestCriticalRelease runUiTestCritical check checkIntegrationTests preMerge publish all: stop clean javadocs compile assembleUiTests: assembleUiTestRelease -preMerge: check +preMerge: check checkIntegrationTests publish: clean dryRelease # deep clean @@ -29,11 +29,13 @@ update: format: ./gradlew spotlessApply ./gradlew -p sentry-samples/sentry-samples-android spotlessApply + ./gradlew -p sentry-android-integration-tests spotlessApply # Spotless check's code checkFormat: ./gradlew spotlessJavaCheck spotlessKotlinCheck ./gradlew -p sentry-samples/sentry-samples-android spotlessJavaCheck spotlessKotlinCheck + ./gradlew -p sentry-android-integration-tests spotlessJavaCheck spotlessKotlinCheck # Binary compatibility validator api: @@ -41,11 +43,11 @@ api: # Assemble release and Android test apk of the uitest-android module assembleUiTestRelease: - ./gradlew :sentry-android-integration-tests:sentry-uitest-android:assembleRelease :sentry-android-integration-tests:sentry-uitest-android:assembleAndroidTest + ./gradlew -p sentry-android-integration-tests :sentry-uitest-android:assembleRelease :sentry-uitest-android:assembleAndroidTest # Assemble release of the uitest-android-critical module assembleUiTestCriticalRelease: - ./gradlew :sentry-android-integration-tests:sentry-uitest-android-critical:assembleRelease + ./gradlew -p sentry-android-integration-tests :sentry-uitest-android-critical:assembleRelease # Run Maestro tests for the uitest-android-critical module runUiTestCritical: @@ -54,3 +56,7 @@ runUiTestCritical: # Run tests and lint check: ./gradlew check + +# The Android integration tests are a separate build, so the root `check` doesn't reach them +checkIntegrationTests: + ./gradlew -p sentry-android-integration-tests check diff --git a/scripts/test-ui-android.sh b/scripts/test-ui-android.sh index 4567f96afc4..d81c683aff3 100755 --- a/scripts/test-ui-android.sh +++ b/scripts/test-ui-android.sh @@ -9,7 +9,7 @@ out_dir=$1 device_dir=/sdcard/Download/sentry_replay_snapshots test_status=0 -./gradlew sentry-android-integration-tests:sentry-uitest-android:connectedReleaseAndroidTest || test_status=$? +./gradlew -p sentry-android-integration-tests :sentry-uitest-android:connectedReleaseAndroidTest || test_status=$? mkdir -p "$out_dir" if adb shell test -d "$device_dir"; then diff --git a/sentry-android-integration-tests/README.md b/sentry-android-integration-tests/README.md index 4b3c495a978..581d2df5439 100644 --- a/sentry-android-integration-tests/README.md +++ b/sentry-android-integration-tests/README.md @@ -1,4 +1,8 @@ # Android performance-impact and integration tests +This directory is a separate Gradle build that includes the SDK build, so run its tasks with +`./gradlew -p sentry-android-integration-tests `. The SDK build doesn't include it, so +`./gradlew` from the repository root doesn't build, lint or format these apps. + * [Espresso-based UI tests](./sentry-uitest-android) - run within SauceLabs (see /.sauce/*.yml) * Also used for compatibility test matrix against new AGP versions diff --git a/sentry-android-integration-tests/build.gradle.kts b/sentry-android-integration-tests/build.gradle.kts new file mode 100644 index 00000000000..be90495faf9 --- /dev/null +++ b/sentry-android-integration-tests/build.gradle.kts @@ -0,0 +1,10 @@ +// Loads the plugins once for every subproject, so they all share one classpath. +plugins { + alias(libs.plugins.android.application) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.compose) apply false + alias(libs.plugins.errorprone) apply false + alias(libs.plugins.detekt) apply false + alias(libs.plugins.gradle.versions) apply false + alias(libs.plugins.sentry) apply false +} diff --git a/sentry-android-integration-tests/gradle.properties b/sentry-android-integration-tests/gradle.properties new file mode 100644 index 00000000000..e83338c383b --- /dev/null +++ b/sentry-android-integration-tests/gradle.properties @@ -0,0 +1,24 @@ +# Gradle properties are per build, so this repeats what these apps need from the SDK build's +# gradle.properties. settings.gradle.kts reads the SDK version from that file. + +org.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=2g -XX:+CrashOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC +org.gradle.caching=true +org.gradle.parallel=true +org.gradle.configureondemand=true +org.gradle.configuration-cache=true +org.gradle.configuration-cache.parallel=true + +android.useAndroidX=true +# AGP 9+ migration opt-outs until we remove kotlin-android plugin and adopt built-in Kotlin. +android.builtInKotlin=false +android.newDsl=false + +android.defaults.buildfeatures.renderscript=false +android.defaults.buildfeatures.shaders=false +android.defaults.buildfeatures.aidl=false +android.defaults.buildfeatures.resvalues=false +android.nonTransitiveRClass=true + +kotlin.stdlib.default.dependency=false + +systemProp.org.gradle.internal.http.socketTimeout=120000 diff --git a/sentry-android-integration-tests/sentry-uitest-android-critical/build.gradle.kts b/sentry-android-integration-tests/sentry-uitest-android-critical/build.gradle.kts index c530245c213..fc43a6ad062 100644 --- a/sentry-android-integration-tests/sentry-uitest-android-critical/build.gradle.kts +++ b/sentry-android-integration-tests/sentry-uitest-android-critical/build.gradle.kts @@ -9,6 +9,8 @@ plugins { id("io.sentry.jdk-target") } +val sentryVersion = libs.versions.sentry.get() + android { compileSdk = libs.versions.compileSdk.get().toInt() compileSdkMinor = libs.versions.compileSdkMinor.get().toInt() @@ -49,7 +51,7 @@ dependencies { implementation(libs.androidx.compose.material3) implementation(libs.androidx.constraintlayout) implementation(libs.androidx.core) - implementation(projects.sentryAndroidCore) + implementation("io.sentry:sentry-android-core:$sentryVersion") } tasks.withType().configureEach { diff --git a/sentry-android-integration-tests/sentry-uitest-android/README.md b/sentry-android-integration-tests/sentry-uitest-android/README.md index 145df22485c..5150de4764a 100644 --- a/sentry-android-integration-tests/sentry-uitest-android/README.md +++ b/sentry-android-integration-tests/sentry-uitest-android/README.md @@ -5,7 +5,7 @@ By default the envelopes sent to relay are caught by a mock server which allows # How to use -Simply run `./gradlew connectedCheck` to run all ui tests of all modules (requires a connected device, either physical or an emulator). +Simply run `./gradlew -p sentry-android-integration-tests connectedCheck` to run all ui tests of all modules (requires a connected device, either physical or an emulator). # CI CI runs these tests on a GitHub Actions emulator in the AGP matrix workflow (`.github/workflows/agp-matrix.yml`). diff --git a/sentry-android-integration-tests/sentry-uitest-android/build.gradle.kts b/sentry-android-integration-tests/sentry-uitest-android/build.gradle.kts index a633acbae2e..382d3c15fdd 100644 --- a/sentry-android-integration-tests/sentry-uitest-android/build.gradle.kts +++ b/sentry-android-integration-tests/sentry-uitest-android/build.gradle.kts @@ -8,11 +8,13 @@ plugins { alias(libs.plugins.kotlin.compose) alias(libs.plugins.errorprone) alias(libs.plugins.gradle.versions) - id("io.sentry.detekt") + alias(libs.plugins.detekt) id("io.sentry.spotless") id("io.sentry.jdk-target") } +val sentryVersion = libs.versions.sentry.get() + android { compileSdk = libs.versions.compileSdk.get().toInt() compileSdkMinor = libs.versions.compileSdkMinor.get().toInt() @@ -46,7 +48,7 @@ android { signingConfigs { getByName("debug") { - storeFile = rootProject.file("debug.keystore") + storeFile = file("../../debug.keystore") storePassword = "android" keyAlias = "androiddebugkey" keyPassword = "android" @@ -90,10 +92,10 @@ dependencies { implementation(kotlin("stdlib-jdk8", getKotlinPluginVersion())) if (applySentryIntegrations) { - implementation(projects.sentryAndroid) - implementation(projects.sentryCompose) + implementation("io.sentry:sentry-android:$sentryVersion") + implementation("io.sentry:sentry-compose:$sentryVersion") } else { - implementation(projects.sentryAndroidCore) + implementation("io.sentry:sentry-android-core:$sentryVersion") } implementation(libs.androidx.appcompat) implementation(libs.androidx.activity.compose) @@ -112,7 +114,7 @@ dependencies { errorprone(libs.nullaway) androidTestUtil(libs.androidx.test.orchestrator) - androidTestImplementation(projects.sentryTestSupport) + androidTestImplementation("io.sentry:sentry-test-support:$sentryVersion") androidTestImplementation(libs.androidx.test.core.ktx) androidTestImplementation(libs.androidx.test.espresso.core) androidTestImplementation(libs.androidx.test.ext.junit) @@ -132,6 +134,12 @@ tasks.withType().configureEach { } } +detekt { + buildUponDefaultConfig = true + allRules = true + config.setFrom(file("../../detekt.yml")) +} + tasks.withType().configureEach { // Target version of the generated JVM bytecode. It is used for type resolution. jvmTarget = JavaVersion.VERSION_1_8.toString() diff --git a/sentry-android-integration-tests/settings.gradle.kts b/sentry-android-integration-tests/settings.gradle.kts new file mode 100644 index 00000000000..f4cbdf257fa --- /dev/null +++ b/sentry-android-integration-tests/settings.gradle.kts @@ -0,0 +1,77 @@ +// A standalone build that includes the SDK build, so it depends on the SDK through the same +// io.sentry:* coordinates an app would, and Gradle substitutes the SDK's projects for them. +// The SDK build doesn't include this one back, so its plugins and versions stay out of the SDK +// build. Run it with `./gradlew -p sentry-android-integration-tests `. + +pluginManagement { + repositories { + // Prefer local SAGP artifact if one exists; otherwise fall back to libs.versions.toml. + if (providers.gradleProperty("useSagp").isPresent) { + mavenLocal { + content { + includeGroup("io.sentry") + includeGroup("io.sentry.android.gradle") + } + } + } + mavenCentral() + gradlePluginPortal() + google() + } + + // Every build in a composite must use the same AGP, so each build's settings applies the AGP + // matrix job's override. + System.getenv("VERSION_AGP")?.let { agpVersion -> + resolutionStrategy { + eachPlugin { + if (requested.id.id.startsWith("com.android")) { + useVersion(agpVersion) + } + } + } + } +} + +plugins { + id("com.gradle.develocity") version "4.5.0" + id("com.gradle.common-custom-user-data-gradle-plugin") version "2.8.0" +} + +develocity { + buildScan { + termsOfUseUrl.set("https://gradle.com/help/legal-terms-of-use") + termsOfUseAgree.set("yes") + } +} + +// Gradle reads gradle.properties only for the build it belongs to, so read the SDK version from the +// SDK build's file. +val sentryVersion: String = + providers + .fileContents(layout.settingsDirectory.file("../gradle.properties")) + .asText + .map { java.util.Properties().apply { load(it.reader()) }.getProperty("versionName") } + .get() + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + mavenLocal() + } + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + version("sentry", sentryVersion) + } + } +} + +rootProject.name = "sentry-android-integration-tests" + +includeBuild("..") + +// For the io.sentry.spotless and io.sentry.jdk-target convention plugins. +includeBuild("../build-logic") + +include("sentry-uitest-android", "sentry-uitest-android-critical", "test-app-size") diff --git a/sentry-android-integration-tests/test-app-size/build.gradle.kts b/sentry-android-integration-tests/test-app-size/build.gradle.kts index c8de6cbfbe3..678ae4103e0 100644 --- a/sentry-android-integration-tests/test-app-size/build.gradle.kts +++ b/sentry-android-integration-tests/test-app-size/build.gradle.kts @@ -5,6 +5,8 @@ plugins { id("io.sentry.jdk-target") } +val sentryVersion = libs.versions.sentry.get() + android { namespace = "io.sentry.tests.size" compileSdk = libs.versions.compileSdk.get().toInt() @@ -15,7 +17,7 @@ android { minSdk = libs.versions.minSdk.get().toInt() targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 1 - versionName = project.version.toString() + versionName = sentryVersion } buildTypes { @@ -44,12 +46,12 @@ configurations.configureEach { } dependencies { - implementation(projects.sentryAndroid) - implementation(projects.sentryAndroidTimber) - implementation(projects.sentryAndroidSqlite) - implementation(projects.sentryOkhttp) - implementation(projects.sentryCompose) - implementation(projects.sentryAndroidFragment) + implementation("io.sentry:sentry-android:$sentryVersion") + implementation("io.sentry:sentry-android-timber:$sentryVersion") + implementation("io.sentry:sentry-android-sqlite:$sentryVersion") + implementation("io.sentry:sentry-okhttp:$sentryVersion") + implementation("io.sentry:sentry-compose:$sentryVersion") + implementation("io.sentry:sentry-android-fragment:$sentryVersion") } sentry { diff --git a/settings.gradle.kts b/settings.gradle.kts index 378979411f0..bd377c7a03b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -139,8 +139,5 @@ include( "sentry-samples:sentry-samples-spring-boot-4-otlp", "sentry-samples:sentry-samples-spring-boot-4-webflux", "sentry-samples:sentry-samples-netflix-dgs", - "sentry-android-integration-tests:sentry-uitest-android-critical", - "sentry-android-integration-tests:sentry-uitest-android", - "sentry-android-integration-tests:test-app-size", "sentry-samples:sentry-samples-openfeign" ) From da5cf0652351438e06e7fe85a7db1d6f123637d1 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 2 Nov 2026 14:13:24 +0100 Subject: [PATCH 15/21] ci(samples): Run the Android integration tests' check in the Samples workflow Adds the integration tests build to the Samples workflow's matrix instead of a `make preMerge` target. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/samples.yml | 2 ++ Makefile | 8 ++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/samples.yml b/.github/workflows/samples.yml index 70e42119c49..c0376a85328 100644 --- a/.github/workflows/samples.yml +++ b/.github/workflows/samples.yml @@ -22,6 +22,8 @@ jobs: include: - name: sentry-samples-android path: sentry-samples/sentry-samples-android + - name: sentry-android-integration-tests + path: sentry-android-integration-tests steps: - name: Checkout Repo diff --git a/Makefile b/Makefile index dca9b7bbe12..d88f81d09ab 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ -.PHONY: all clean compile javadocs dryRelease update format checkFormat api assembleUiTestRelease assembleUiTestCriticalRelease runUiTestCritical check checkIntegrationTests preMerge publish +.PHONY: all clean compile javadocs dryRelease update format checkFormat api assembleUiTestRelease assembleUiTestCriticalRelease runUiTestCritical check preMerge publish all: stop clean javadocs compile assembleUiTests: assembleUiTestRelease -preMerge: check checkIntegrationTests +preMerge: check publish: clean dryRelease # deep clean @@ -56,7 +56,3 @@ runUiTestCritical: # Run tests and lint check: ./gradlew check - -# The Android integration tests are a separate build, so the root `check` doesn't reach them -checkIntegrationTests: - ./gradlew -p sentry-android-integration-tests check From c42a2e7e7dd8cda850865a8412278a3f496661a4 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 16:56:36 +0100 Subject: [PATCH 16/21] build: Drop the root's SAGP declaration and local SAGP repository With the Android sample and integration tests in their own builds, no project in the SDK build applies the Sentry Android Gradle Plugin. The root no longer declares it or looks it up in mavenLocal when useSagp is set; those builds declare it and handle useSagp themselves. The root keeps the AGP declaration: the SDK's Android modules apply com.android.library without a version and get AGP from it. Co-Authored-By: Claude Opus 5.5 --- build.gradle.kts | 4 ---- settings.gradle.kts | 9 --------- 2 files changed, 13 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index db37baa5207..fff33104ae9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,7 +19,6 @@ plugins { alias(libs.plugins.gradle.versions) apply false alias(libs.plugins.spring.dependency.management) apply false id("io.sentry.javadoc.aggregate") - alias(libs.plugins.sentry) apply false alias(libs.plugins.android.application) apply false } @@ -28,9 +27,6 @@ buildscript { google() } dependencies { - // add classpath of sentry android gradle plugin - // classpath("io.sentry:sentry-android-gradle-plugin:{version}") - classpath(libs.commons.compress) } } diff --git a/settings.gradle.kts b/settings.gradle.kts index bd377c7a03b..aae18edb922 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,15 +2,6 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { repositories { - // Prefer local SAGP artifact if one exists; otherwise fall back to libs.versions.toml. - if (providers.gradleProperty("useSagp").isPresent) { - mavenLocal { - content { - includeGroup("io.sentry") - includeGroup("io.sentry.android.gradle") - } - } - } mavenCentral() gradlePluginPortal() google() From 2d4595f1b6bb90560aab1dc7e779e5bb4cbf2440 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 17:25:18 +0100 Subject: [PATCH 17/21] build(samples): Link the integration tests' Gradle files to the SDK build's gradle.properties, gradlew, gradle/wrapper and gradle/gradle-daemon-jvm.properties are now symlinks to the SDK build's files, as in the Android sample. The copied gradle.properties had drifted from the root one (-Xmx6g and CrashOnOutOfMemoryError), and the build had no wrapper or daemon JDK pin. The SDK version now comes from the shared versionName property instead of parsing the root file. The root drops android.experimental.lint.version. It equals the lint bundled with AGP 9.4.0, so it changes nothing for the SDK build, and sentry-uitest-android's warningsAsErrors fails on it once the integration tests share the root gradle.properties. Co-Authored-By: Claude Opus 5.5 --- gradle.properties | 1 - sentry-android-integration-tests/README.md | 2 ++ .../gradle.properties | 25 +------------------ .../gradle/gradle-daemon-jvm.properties | 1 + .../gradle/wrapper | 1 + sentry-android-integration-tests/gradlew | 1 + .../settings.gradle.kts | 12 ++------- 7 files changed, 8 insertions(+), 35 deletions(-) mode change 100644 => 120000 sentry-android-integration-tests/gradle.properties create mode 120000 sentry-android-integration-tests/gradle/gradle-daemon-jvm.properties create mode 120000 sentry-android-integration-tests/gradle/wrapper create mode 120000 sentry-android-integration-tests/gradlew diff --git a/gradle.properties b/gradle.properties index eeefd38c92d..417334e771c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,6 @@ android.useAndroidX=true # AGP 9+ migration opt-outs until we remove kotlin-android plugin and adopt built-in Kotlin. android.builtInKotlin=false android.newDsl=false -android.experimental.lint.version=9.4.0 android.disableAgpUpgradePrompt=true diff --git a/sentry-android-integration-tests/README.md b/sentry-android-integration-tests/README.md index 581d2df5439..2e84e1cbd06 100644 --- a/sentry-android-integration-tests/README.md +++ b/sentry-android-integration-tests/README.md @@ -3,6 +3,8 @@ This directory is a separate Gradle build that includes the SDK build, so run its tasks with `./gradlew -p sentry-android-integration-tests `. The SDK build doesn't include it, so `./gradlew` from the repository root doesn't build, lint or format these apps. +`gradle.properties`, `gradlew`, `gradle/wrapper` and `gradle/gradle-daemon-jvm.properties` are +symlinks to the SDK build's, so both builds use the same Gradle, JDK and settings. * [Espresso-based UI tests](./sentry-uitest-android) - run within SauceLabs (see /.sauce/*.yml) * Also used for compatibility test matrix against new AGP versions diff --git a/sentry-android-integration-tests/gradle.properties b/sentry-android-integration-tests/gradle.properties deleted file mode 100644 index e83338c383b..00000000000 --- a/sentry-android-integration-tests/gradle.properties +++ /dev/null @@ -1,24 +0,0 @@ -# Gradle properties are per build, so this repeats what these apps need from the SDK build's -# gradle.properties. settings.gradle.kts reads the SDK version from that file. - -org.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=2g -XX:+CrashOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -org.gradle.caching=true -org.gradle.parallel=true -org.gradle.configureondemand=true -org.gradle.configuration-cache=true -org.gradle.configuration-cache.parallel=true - -android.useAndroidX=true -# AGP 9+ migration opt-outs until we remove kotlin-android plugin and adopt built-in Kotlin. -android.builtInKotlin=false -android.newDsl=false - -android.defaults.buildfeatures.renderscript=false -android.defaults.buildfeatures.shaders=false -android.defaults.buildfeatures.aidl=false -android.defaults.buildfeatures.resvalues=false -android.nonTransitiveRClass=true - -kotlin.stdlib.default.dependency=false - -systemProp.org.gradle.internal.http.socketTimeout=120000 diff --git a/sentry-android-integration-tests/gradle.properties b/sentry-android-integration-tests/gradle.properties new file mode 120000 index 00000000000..7677fb73be8 --- /dev/null +++ b/sentry-android-integration-tests/gradle.properties @@ -0,0 +1 @@ +../gradle.properties \ No newline at end of file diff --git a/sentry-android-integration-tests/gradle/gradle-daemon-jvm.properties b/sentry-android-integration-tests/gradle/gradle-daemon-jvm.properties new file mode 120000 index 00000000000..284e270637d --- /dev/null +++ b/sentry-android-integration-tests/gradle/gradle-daemon-jvm.properties @@ -0,0 +1 @@ +../../gradle/gradle-daemon-jvm.properties \ No newline at end of file diff --git a/sentry-android-integration-tests/gradle/wrapper b/sentry-android-integration-tests/gradle/wrapper new file mode 120000 index 00000000000..3232fe4e272 --- /dev/null +++ b/sentry-android-integration-tests/gradle/wrapper @@ -0,0 +1 @@ +../../gradle/wrapper \ No newline at end of file diff --git a/sentry-android-integration-tests/gradlew b/sentry-android-integration-tests/gradlew new file mode 120000 index 00000000000..502f5a2d3ec --- /dev/null +++ b/sentry-android-integration-tests/gradlew @@ -0,0 +1 @@ +../gradlew \ No newline at end of file diff --git a/sentry-android-integration-tests/settings.gradle.kts b/sentry-android-integration-tests/settings.gradle.kts index f4cbdf257fa..3eba475aec0 100644 --- a/sentry-android-integration-tests/settings.gradle.kts +++ b/sentry-android-integration-tests/settings.gradle.kts @@ -44,15 +44,6 @@ develocity { } } -// Gradle reads gradle.properties only for the build it belongs to, so read the SDK version from the -// SDK build's file. -val sentryVersion: String = - providers - .fileContents(layout.settingsDirectory.file("../gradle.properties")) - .asText - .map { java.util.Properties().apply { load(it.reader()) }.getProperty("versionName") } - .get() - dependencyResolutionManagement { repositories { google() @@ -62,7 +53,8 @@ dependencyResolutionManagement { versionCatalogs { create("libs") { from(files("../gradle/libs.versions.toml")) - version("sentry", sentryVersion) + // gradle.properties links to the SDK build's, so versionName is the SDK version. + version("sentry", providers.gradleProperty("versionName").get()) } } } From 0868820e63ab54ab0c833f1bbd5d64879eb16d04 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 17:49:38 +0100 Subject: [PATCH 18/21] build(samples): Include each integration test project on its own line Adding or removing a project then changes only its own line. Co-Authored-By: Claude Opus 5.5 --- sentry-android-integration-tests/settings.gradle.kts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sentry-android-integration-tests/settings.gradle.kts b/sentry-android-integration-tests/settings.gradle.kts index 3eba475aec0..8fd56bf5535 100644 --- a/sentry-android-integration-tests/settings.gradle.kts +++ b/sentry-android-integration-tests/settings.gradle.kts @@ -66,4 +66,6 @@ includeBuild("..") // For the io.sentry.spotless and io.sentry.jdk-target convention plugins. includeBuild("../build-logic") -include("sentry-uitest-android", "sentry-uitest-android-critical", "test-app-size") +include("sentry-uitest-android") +include("sentry-uitest-android-critical") +include("test-app-size") From 800282d432a254b03099c6aaf645ebee19fb6d76 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 18:16:01 +0100 Subject: [PATCH 19/21] build(samples): Keep the integration tests' Develocity and dependency versions current The integration tests' settings use the root build's Develocity plugin version, and Dependabot also scans their build, as it does the Android sample's. Co-Authored-By: Claude Opus 5.5 --- .github/dependabot.yml | 1 + sentry-android-integration-tests/settings.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8015fe0a0d8..8e712646a1e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -11,6 +11,7 @@ updates: directories: - "/" - "/sentry-samples/sentry-samples-android" + - "/sentry-android-integration-tests" registries: - gradle-plugin-portal schedule: diff --git a/sentry-android-integration-tests/settings.gradle.kts b/sentry-android-integration-tests/settings.gradle.kts index 8fd56bf5535..4eacc2ddab4 100644 --- a/sentry-android-integration-tests/settings.gradle.kts +++ b/sentry-android-integration-tests/settings.gradle.kts @@ -33,7 +33,7 @@ pluginManagement { } plugins { - id("com.gradle.develocity") version "4.5.0" + id("com.gradle.develocity") version "4.6.1" id("com.gradle.common-custom-user-data-gradle-plugin") version "2.8.0" } From 03cda835ff4f513e9aa4f01661ea633846a98542 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 18:31:30 +0100 Subject: [PATCH 20/21] build(samples): Drop the comment on the integration tests' root plugins Co-Authored-By: Claude Opus 5.5 --- sentry-android-integration-tests/build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/sentry-android-integration-tests/build.gradle.kts b/sentry-android-integration-tests/build.gradle.kts index be90495faf9..53972e7fdb1 100644 --- a/sentry-android-integration-tests/build.gradle.kts +++ b/sentry-android-integration-tests/build.gradle.kts @@ -1,4 +1,3 @@ -// Loads the plugins once for every subproject, so they all share one classpath. plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.kotlin.android) apply false From 0825f7003bdcb6ae58621f30ea5e262235f2b030 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 18:34:23 +0100 Subject: [PATCH 21/21] build(samples): Drop the header comment from the integration tests' settings Co-Authored-By: Claude Opus 5.5 --- sentry-android-integration-tests/settings.gradle.kts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sentry-android-integration-tests/settings.gradle.kts b/sentry-android-integration-tests/settings.gradle.kts index 4eacc2ddab4..5a0d060f7d7 100644 --- a/sentry-android-integration-tests/settings.gradle.kts +++ b/sentry-android-integration-tests/settings.gradle.kts @@ -1,8 +1,3 @@ -// A standalone build that includes the SDK build, so it depends on the SDK through the same -// io.sentry:* coordinates an app would, and Gradle substitutes the SDK's projects for them. -// The SDK build doesn't include this one back, so its plugins and versions stay out of the SDK -// build. Run it with `./gradlew -p sentry-android-integration-tests `. - pluginManagement { repositories { // Prefer local SAGP artifact if one exists; otherwise fall back to libs.versions.toml.