From c835065534e775677286b8fb228a1d6e26a9365d Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Tue, 27 Oct 2026 13:03:54 +0100 Subject: [PATCH 1/8] 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/agp-matrix.yml | 2 +- .github/workflows/integration-tests-size.yml | 2 +- AGENTS.md | 4 +- Makefile | 14 +++- sentry-android-integration-tests/README.md | 4 + .../build.gradle.kts | 10 +++ .../gradle.properties | 24 ++++++ .../build.gradle.kts | 6 +- .../sentry-uitest-android/README.md | 4 +- .../sentry-uitest-android/build.gradle.kts | 20 +++-- .../settings.gradle.kts | 77 +++++++++++++++++++ .../test-app-size/build.gradle.kts | 18 +++-- settings.gradle.kts | 3 - 13 files changed, 162 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/agp-matrix.yml b/.github/workflows/agp-matrix.yml index 81127cb468f..b55ee483720 100644 --- a/.github/workflows/agp-matrix.yml +++ b/.github/workflows/agp-matrix.yml @@ -85,7 +85,7 @@ jobs: disable-spellchecker: true emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none disk-size: 4096M - script: ./gradlew sentry-android-integration-tests:sentry-uitest-android:connectedReleaseAndroidTest -Denvironment=github --daemon + script: ./gradlew -p sentry-android-integration-tests :sentry-uitest-android:connectedReleaseAndroidTest -Denvironment=github --daemon - name: Upload test results if: always() 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 43347411346..ee6436f8d23 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/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 8a22b91890c..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 @@ -5,8 +5,12 @@ plugins { id("com.android.application") alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.compose) + 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() @@ -47,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 d6ccf2f1f93..9f6f57b3fc0 100644 --- a/sentry-android-integration-tests/sentry-uitest-android/README.md +++ b/sentry-android-integration-tests/sentry-uitest-android/README.md @@ -5,13 +5,13 @@ 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). # SauceLabs To run on saucelabs execute following commands (need also `SAUCE_USERNAME` and `SAUCE_ACCESS_KEY` environment variables): For End 2 End: ``` -./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 saucectl run -c .sauce/sentry-uitest-android-end2end.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 53cc88fec46..4aa91bf3735 100644 --- a/sentry-android-integration-tests/sentry-uitest-android/build.gradle.kts +++ b/sentry-android-integration-tests/sentry-uitest-android/build.gradle.kts @@ -9,8 +9,12 @@ plugins { alias(libs.plugins.errorprone) alias(libs.plugins.gradle.versions) 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 +50,7 @@ android { signingConfigs { getByName("debug") { - storeFile = rootProject.file("debug.keystore") + storeFile = file("../../debug.keystore") storePassword = "android" keyAlias = "androiddebugkey" keyPassword = "android" @@ -90,10 +94,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 +116,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 +136,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 6260c761d53..678ae4103e0 100644 --- a/sentry-android-integration-tests/test-app-size/build.gradle.kts +++ b/sentry-android-integration-tests/test-app-size/build.gradle.kts @@ -1,8 +1,12 @@ plugins { id("com.android.application") id("io.sentry.android.gradle") + id("io.sentry.spotless") + id("io.sentry.jdk-target") } +val sentryVersion = libs.versions.sentry.get() + android { namespace = "io.sentry.tests.size" compileSdk = libs.versions.compileSdk.get().toInt() @@ -13,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 { @@ -42,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 ce6fb57dc1a48588e618da47081abf26ff0cf6a7 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 2 Nov 2026 14:13:24 +0100 Subject: [PATCH 2/8] 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 d6eff98a1f4778919082741e439aea2b90faa8f3 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 16:56:36 +0100 Subject: [PATCH 3/8] 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 f880ab151b5..27a81c7a9a6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,7 +25,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 } @@ -34,9 +33,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 96f4e02cd90744d623970b2b8b2be1c4320ac290 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 17:25:18 +0100 Subject: [PATCH 4/8] 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 9b474103c4be9dacf4ad80e4a94184ac895e4c40 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 17:49:38 +0100 Subject: [PATCH 5/8] 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 8dd0deb3877b60cc257e1f00ba57dbd64f15607f Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 18:16:01 +0100 Subject: [PATCH 6/8] 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 2565610c527c26325c247267a8c54758ad84d40f Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 18:31:30 +0100 Subject: [PATCH 7/8] 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 27ec18e6831ea14cf5cbbfd0ca07952635e13f20 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 5 Nov 2026 18:34:23 +0100 Subject: [PATCH 8/8] 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.