From 29943005496ecd4c45b3b25946febb8c78f11fd4 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 10 Jun 2026 21:01:35 +0200 Subject: [PATCH 1/2] chore(samples-android): Add optional SAGP build mode Adds an optional useSagp flag to Android sample app builds that, when true, applies the Sentry Android Gradle Plugin. (Defaults to false, which matches existing build behavior.) ``` ./gradlew :sentry-samples:sentry-samples-android:installDebug -PuseSagp=true ``` See the Android sample app README for more details. --- .../sentry-samples-android/README.md | 57 +++++++++++++++++++ .../sentry-samples-android/build.gradle.kts | 32 +++++++++++ 2 files changed, 89 insertions(+) create mode 100644 sentry-samples/sentry-samples-android/README.md diff --git a/sentry-samples/sentry-samples-android/README.md b/sentry-samples/sentry-samples-android/README.md new file mode 100644 index 0000000000..c7c7ad0d89 --- /dev/null +++ b/sentry-samples/sentry-samples-android/README.md @@ -0,0 +1,57 @@ +# Sentry Sample Android App + +Sample application demonstrating how to use the Sentry Android SDK, including core functionality (error reporting, tracing, session replay, +profiling) and integrations (Compose, OkHttp, etc.). + +## How to run it? + +Install the app on your device or emulator: + +``` +./gradlew :sentry-samples:sentry-samples-android:installDebug +``` + +or simply open the project in Android Studio and run the `sentry-samples-android` configuration. + +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=true +``` + +In Android Studio, add `useSagp=true` to `gradle.properties` or pass it as a Gradle project property. + +## Build modes + +### With or without SAGP + +The sample app can be built with or without the SAGP. + +| Gradle Property | Required | Purpose | +|-----------------|--------------------------|----------------------------------------------------------------------------------------------------------------| +| `useSagp` | No (defaults to `false`) | When `true`, apply SAGP when building the sample app. When false or absent, build the sample app without SAGP. | + +You can configure SAGP properties via the lambda passed to `extensions.configure("sentry")` in the sample app's +`build.gradle.kts` file. + +### Builds against your local sentry-java branch + +Regardless of `useSagp`, the sample always depends on sentry-java modules from this monorepo (e.g., `projects.sentryAndroid`). SAGP's SDK +auto-installation is disabled, so the sample never pulls a separate SDK version from Maven. Local SDK changes in your branch are picked up +directly. + +## Viewing SDK output + +### Locally + +Debug builds enable SDK debug logging, so captured envelopes are printed to logcat (tag `Sentry`): + +``` +adb logcat -s Sentry +``` + +### On Sentry UI + +By default, SDK output produced by the sample app appears under the [sentry-sdk test project](https://sentry-sdks.sentry.io/issues/?project=5428559). +To redirect them to your own project, replace the test DSN (i.e., the `io.sentry.dsn` `meta-data` value in `src/main/AndroidManifest.xml` +with your own. diff --git a/sentry-samples/sentry-samples-android/build.gradle.kts b/sentry-samples/sentry-samples-android/build.gradle.kts index ed8cea2566..44d930975e 100644 --- a/sentry-samples/sentry-samples-android/build.gradle.kts +++ b/sentry-samples/sentry-samples-android/build.gradle.kts @@ -1,5 +1,7 @@ import com.android.build.api.artifact.SingleArtifact import com.android.build.api.variant.impl.VariantImpl +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 @@ -7,6 +9,36 @@ plugins { id("com.android.application") alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.compose) + alias(libs.plugins.sentry) apply false +} + +val useSagp = + providers.gradleProperty("useSagp").map { it.equals("true", ignoreCase = true) }.orElse(false) + +if (useSagp.get()) { + apply(plugin = "io.sentry.android.gradle") +} + +plugins.withId("io.sentry.android.gradle") { + // Extension configs match non-SAGP builds. Update locally to test your feature. + extensions.configure("sentry") { + autoInstallation.enabled.set(false) + includeProguardMapping.set(false) + includeDependenciesReport.set(false) + telemetry.set(false) + tracingInstrumentation { + features.set( + setOf( + InstrumentationFeature.COMPOSE, + InstrumentationFeature.DATABASE, + InstrumentationFeature.FILE_IO, + InstrumentationFeature.OKHTTP, + ) + ) + logcat.enabled.set(false) + appStart.enabled.set(false) + } + } } android { From f521ffd781baf513fbad21e0978c85130caddc99 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 12 Jun 2026 10:52:23 +0200 Subject: [PATCH 2/2] chore(samples-android): Support mavenLocal for builds that apply the SAGP Adds wiring that lets us prefer mavenLocal SAGP artifacts, when present, for Android sample app builds that set -PuseSagp=true. If no local artifact is found, we fall back to libs.versions.toml. --- gradle/libs.versions.toml | 3 +- .../sentry-samples-android/README.md | 20 ++++++++ .../sentry-samples-android/build.gradle.kts | 47 +++++++++++++++++++ settings.gradle.kts | 9 ++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e653069e2b..fb4c53d0c0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,6 +29,7 @@ otelInstrumentationAlpha = "2.26.0-alpha" otelSemanticConventions = "1.40.0" otelSemanticConventionsAlpha = "1.40.0-alpha" retrofit = "2.9.0" +sagp = "6.6.0" slf4j = "1.7.30" springboot2 = "2.7.18" springboot3 = "3.5.0" @@ -66,7 +67,7 @@ springboot4 = { id = "org.springframework.boot", version.ref = "springboot4" } spring-dependency-management = { id = "io.spring.dependency-management", version = "1.1.7" } gretty = { id = "org.gretty", version = "4.0.0" } animalsniffer = { id = "ru.vyarus.animalsniffer", version = "2.0.1" } -sentry = { id = "io.sentry.android.gradle", version = "6.6.0"} +sentry = { id = "io.sentry.android.gradle", version.ref = "sagp"} shadow = { id = "com.gradleup.shadow", version = "9.4.1" } [libraries] diff --git a/sentry-samples/sentry-samples-android/README.md b/sentry-samples/sentry-samples-android/README.md index c7c7ad0d89..5ce0a3ccbd 100644 --- a/sentry-samples/sentry-samples-android/README.md +++ b/sentry-samples/sentry-samples-android/README.md @@ -40,6 +40,26 @@ Regardless of `useSagp`, the sample always depends on sentry-java modules from t auto-installation is disabled, so the sample never pulls a separate SDK version from Maven. Local SDK changes in your branch are picked up directly. +### Testing an unpublished SAGP build + +#### I. Publish to Maven Local: + +`-PuseSagp=true` builds check `mavenLocal()` first when resolving SAGP, so you can test a local SAGP branch by publishing it to your local +Maven repository: + +``` +# In your sentry-android-gradle-plugin checkout: +./gradlew publishToMavenLocal +``` + +Re-run `publishToMavenLocal` after each SAGP change; a previously published artifact stays in `~/.m2` and keeps winning until you republish +or remove it. + +#### II. Update `sagp` version in `libs.versions.toml` if needed + +The sample requests the SAGP version pinned in `gradle/libs.versions.toml` (`[versions].sagp`), so either publish your branch at that +version, or temporarily bump the pin to your branch's version (e.g., a `-SNAPSHOT`) without committing the change. + ## Viewing SDK output ### Locally diff --git a/sentry-samples/sentry-samples-android/build.gradle.kts b/sentry-samples/sentry-samples-android/build.gradle.kts index 44d930975e..069cfaf8d7 100644 --- a/sentry-samples/sentry-samples-android/build.gradle.kts +++ b/sentry-samples/sentry-samples-android/build.gradle.kts @@ -2,6 +2,8 @@ import com.android.build.api.artifact.SingleArtifact import com.android.build.api.variant.impl.VariantImpl import io.sentry.android.gradle.extensions.InstrumentationFeature import io.sentry.android.gradle.extensions.SentryPluginExtension +import java.io.File +import java.time.Instant import org.apache.tools.ant.taskdefs.condition.Os import org.gradle.internal.extensions.stdlib.capitalized @@ -20,6 +22,8 @@ if (useSagp.get()) { } plugins.withId("io.sentry.android.gradle") { + logSagpOrigin() + // Extension configs match non-SAGP builds. Update locally to test your feature. extensions.configure("sentry") { autoInstallation.enabled.set(false) @@ -230,3 +234,46 @@ abstract class ToggleNativeLoggingTask : Exec() { ) } } + +fun Project.logSagpOrigin() { + // A locally published SAGP in ~/.m2 silently shadows the released artifact (see README, + // "Testing an unpublished SAGP build"); we log so developers don't wonder what's going on. + val sagpVersion = + SentryPluginExtension::class + .java + .protectionDomain + .codeSource + ?.location + ?.toURI() + ?.let { File(it).name } + ?.removePrefix("sentry-android-gradle-plugin-") + ?.removeSuffix(".jar") + + val sagpLocalJar = + sagpVersion?.let { + File( + System.getProperty("user.home"), + ".m2/repository/io/sentry/sentry-android-gradle-plugin/$it/sentry-android-gradle-plugin-$it.jar", + ) + } + + val sagpOrigin = + when { + sagpVersion == null -> "unknown origin" + sagpLocalJar?.isFile == true -> + "mavenLocal (published ${Instant.ofEpochMilli(sagpLocalJar.lastModified())})" + else -> "remote repository" + } + + val colorize = + gradle.startParameter.consoleOutput != org.gradle.api.logging.configuration.ConsoleOutput.Plain + val (magenta, reset) = if (colorize) "\u001B[35m" to "\u001B[0m" else "" to "" + + logger.lifecycle( + "\n{}🧩 Applied Sentry Android Gradle Plugin {} from {}{}", + magenta, + sagpVersion ?: "", + sagpOrigin, + reset, + ) +} diff --git a/settings.gradle.kts b/settings.gradle.kts index c435c382b7..28bead1218 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,6 +2,15 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { repositories { + // Prefer local SAGP artifact if one exists; otherwise fall back to libs.versions.toml. + if (providers.gradleProperty("useSagp").orNull.equals("true", ignoreCase = true)) { + mavenLocal { + content { + includeGroup("io.sentry") + includeGroup("io.sentry.android.gradle") + } + } + } mavenCentral() gradlePluginPortal() }