Skip to content

build(samples): Move the Android sample to its own composite build - #6047

Draft
runningcode wants to merge 1 commit into
mainfrom
no/samples-android-composite-build
Draft

build(samples): Move the Android sample to its own composite build#6047
runningcode wants to merge 1 commit into
mainfrom
no/samples-android-composite-build

Conversation

@runningcode

Copy link
Copy Markdown
Contributor

📜 Description

sentry-samples/sentry-samples-android becomes a standalone Gradle build that includes the SDK build, instead of being a subproject of it.

The sample's nine projects.sentryX accessors become plain io.sentry:* coordinates, which Gradle substitutes back to the SDK's projects — so nothing needs to be published first:

io.sentry:sentry-android:8.54.0  -> project ':sentry-android'
io.sentry:sentry-compose:8.54.0  -> project ':sentry-compose'
... all 9, plus sentry-android-distribution on debugImplementation

Run it with ./gradlew -p sentry-samples/sentry-samples-android <task>, or open that directory in Android Studio.

Notable details:

  • sentry-uitest-android-macrobenchmark moves into the sample build as sentry-samples-android/macrobenchmark, because AGP requires a benchmark's target app to live in the same build. The app is that build's root project and targetProjectPath = ":" works, so the app's own files did not have to move. Its APK path changes (Sauce config updated); the sample's own APK path is unchanged.
  • The AGP version moves to gradle/libs.versions.toml (agp = "9.2.1"), shared by both builds, replacing Config.AGP and the root buildscript classpath. VERSION_AGP still overrides it, through a pluginManagement resolution strategy in each settings file.
  • The SDK version stays single-source: the sample reads versionName out of the root build's gradle.properties rather than duplicating it, so an APK still records which SDK it was built against.
  • The SDK build includes the sample build back, purely so a single ./gradlew spotlessApply still formats the whole repository — no CI or contributor-facing formatting changes were needed. The sample build's root spotlessApply fans out to its own subprojects, so the root build does not enumerate the sample's modules.
  • make preMerge gains checkSampleAndroid (assembleDebug lintDebug in the sample build), since root check no longer reaches the sample. Folding it into root check instead would put an Android app build back into the SDK build's gate.

Two things worth a second opinion:

  1. With a cold configuration cache, root tasks that need the full task graph now configure the sample's two projects so Gradle can discover substitutions — a little of the coupling this PR removes. Measured at ~7.5s vs ~7.4s for build --dry-run --no-configuration-cache, i.e. inside run-to-run noise, and no sample tasks execute. Not zero coupling, but not measurable either.
  2. The sample's 7 .java files lose the root build's -Xlint:all -Werror javac flags, which came from the root allprojects block. I did not replicate them for a sample app.

💡 Motivation and Context

While the sample was a subproject of the SDK build, every root Gradle invocation (check, apiDump, spotlessApply) configured it, dragging AGP, Compose, KSP, SQLDelight, Room and CameraX into the SDK build's graph. The sample also consumed the SDK through project accessors, so it never exercised it the way a real consumer does, and it could not be built or opened independently of the whole SDK build.

💚 How did you test it?

  • dependencies --configuration debugRuntimeClasspath in the sample build, confirming every io.sentry:* dependency resolves to a project of the included build (including the KMP sentry-compose).
  • assembleDebug, assembleRelease (exercises R8 and proguard-rules.pro), :macrobenchmark:assembleBenchmark, and make checkSampleAndroid in the sample build.
  • Root build unaffected: apiDump (no .api drift), spotlessApply (no changes), and make assembleUiTests, the command the AGP matrix job runs.
  • VERSION_AGP: 9.2.1 by default and 9.0.0 under the env var, in both builds.
  • Spotless delegation, tested by breaking it on purpose: added trailing whitespace to MyApplication.java (app) and SentryStartupBenchmark.kt (macrobenchmark), then confirmed root ./gradlew spotlessApply fixed both.

Not verified locally: -PuseSagp (the catalog pins SAGP 6.13.0, which needs a local SAGP build) and installing on a device. On the first of those, the build root is now the sample directory, which has no sentry.properties; that should not matter because the sample sets includeProguardMapping=false and telemetry=false, but that is reasoning rather than a test.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes. — n/a, build configuration only
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed. — sample and macrobenchmark READMEs, AGENTS.md
  • I updated the wizard if needed. — n/a
  • Review from the native team if needed. — n/a
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec. — no public API changes, apiDump is clean

🔮 Next steps

If the cold-configuration coupling in point 1 above is unwelcome, the alternative is to drop includeBuild("sentry-samples/sentry-samples-android") from the root settings and give the root build its own spotless targets covering the sample's paths, at the cost of duplicating the format rules.

make checkFormat runs spotlessJavaCheck spotlessKotlinCheck, which are per-project task names and so do not reach included builds. Left alone here rather than change which formats that target checks; a root-level spotlessCheck could delegate the same way spotlessApply now does, if wanted.

#skip-changelog

The Android sample was a subproject of the SDK build, so every root Gradle
invocation configured AGP, Compose, KSP, SQLDelight, Room and CameraX, and the
sample consumed the SDK through project accessors rather than as a real
consumer would.

It is now a standalone build that includes the SDK build, depending on plain
io.sentry:* coordinates that Gradle substitutes with the SDK's projects. Run it
with ./gradlew -p sentry-samples/sentry-samples-android <task>.

The macrobenchmark module moves along with it, because AGP requires a
benchmark's target app to live in the same build. The AGP version moves to the
version catalog so both builds share one source of truth, still overridable via
VERSION_AGP.

The SDK build includes the sample build back, so a single ./gradlew spotlessApply
still formats the whole repository and CI needs no sample-specific step. Root
check does not reach the sample, so preMerge gains a checkSampleAndroid target.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sentry

sentry Bot commented Sep 2, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.54.0 (1) release

⚙️ sentry-android Build Distribution Settings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant