From 0da673733fb326c0d99b1c6397ce6399a82b9676 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Tue, 27 Oct 2026 12:12:03 +0100 Subject: [PATCH 1/4] 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 | 40 +++++----- .../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, 154 insertions(+), 35 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 (90%) 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 0fe0c84ccf6..728ac900397 100644 --- a/.github/workflows/format-code.yml +++ b/.github/workflows/format-code.yml @@ -24,7 +24,9 @@ jobs: cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - 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 b85ed387133..007d106fe13 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 a736a15e389..843e29f966e 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 28d8748faa9..8fb29bb4ecd 100644 --- a/sentry-samples/sentry-samples-android/build.gradle.kts +++ b/sentry-samples/sentry-samples-android/build.gradle.kts @@ -8,7 +8,9 @@ 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) @@ -16,6 +18,8 @@ plugins { alias(libs.plugins.sqldelight) } +val sentryVersion = libs.versions.sentry.get() + if (providers.gradleProperty("useSagp").isPresent) { apply(plugin = "io.sentry.android.gradle") } @@ -53,7 +57,7 @@ android { minSdk = 23 targetSdk = libs.versions.targetSdk.get().toInt() versionCode = 2 - versionName = project.version.toString() + versionName = sentryVersion externalNativeBuild { cmake { @@ -104,7 +108,7 @@ android { signingConfigs { getByName("debug") { - storeFile = rootProject.file("debug.keystore") + storeFile = file("../../debug.keystore") storePassword = "android" keyAlias = "androiddebugkey" keyPassword = "android" @@ -146,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 { @@ -175,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") @@ -228,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) @@ -236,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 @@ -254,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 90% 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 cab7c28f934..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,5 +1,7 @@ plugins { id("com.android.test") + id("io.sentry.spotless") + id("io.sentry.jdk-target") alias(libs.plugins.kotlin.android) } @@ -26,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 99d9f516e4c..8921993193b 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 6667fe946ca9d305e8b08ebb5125a9c65cc0ecb3 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 2 Nov 2026 14:12:57 +0100 Subject: [PATCH 2/4] 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 dcdde3aeaf400a8dc7b67f7fbf18e8071b80cbd9 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 2 Nov 2026 15:41:37 +0100 Subject: [PATCH 3/4] 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 d3549ca64def7725d748216a5ccc1ac3b69394b9 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 2 Nov 2026 15:52:28 +0100 Subject: [PATCH 4/4] 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