diff --git a/.cursor/rules/e2e_tests.mdc b/.cursor/rules/e2e_tests.mdc index 1785e61b5c..fd52adb14d 100644 --- a/.cursor/rules/e2e_tests.mdc +++ b/.cursor/rules/e2e_tests.mdc @@ -64,9 +64,16 @@ it. Gradle runs the two in parallel. ## Running them -- The `spring-boot-{2,3,4}-matrix.yml` workflows run the suites against each supported Spring Boot - version, by setting the version in `gradle/libs.versions.toml`. The suites aren't part of - `check`, so a new suite only runs on CI once it's added to its matrix. +- The `springBootMatrix` block in each Spring module's build file runs its suites on every Spring + Boot version in `SpringBootVersions` (build-logic), with a task per suite and version, e.g. + `integrationTestWebfluxBoot3_2_12`. The suites and the SDK compile once, against the catalog's + version; only the runtime classpath changes. `allIntegrationTestsBoot3_2_12` runs one version's + suites, `allIntegrationTestsBoot3` every version's. +- The `spring-boot-{2,3,4}-matrix.yml` workflows run `./gradlew allIntegrationTestsBoot`, + which picks up every module of the line. The suites aren't part of `check`, so a new suite only + runs on CI once it's added to its module's `springBootMatrix` block. +- Suite code may only use APIs that exist in the oldest version of its line. Compiled against a + newer one, a missing API fails at runtime with `NoSuchMethodError` or `NoClassDefFoundError`. ## Gotchas diff --git a/.github/workflows/spring-boot-2-matrix.yml b/.github/workflows/spring-boot-2-matrix.yml index 3ee4553cf2..e537ca96b9 100644 --- a/.github/workflows/spring-boot-2-matrix.yml +++ b/.github/workflows/spring-boot-2-matrix.yml @@ -18,12 +18,7 @@ jobs: spring-boot-2-matrix: timeout-minutes: 45 runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - springboot-version: [ '2.7.0', '2.7.18' ] - - name: Spring Boot ${{ matrix.springboot-version }} + name: Spring Boot 2.x env: GRADLE_ENCRYPTION_KEY: ${{ secrets.GRADLE_ENCRYPTION_KEY }} @@ -51,27 +46,15 @@ jobs: with: cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - - name: Update Spring Boot 2.x version - run: | - springboot_version="${{ matrix.springboot-version }}" - perl -0pi -e 'BEGIN { $v = shift } s/^springboot2[[:space:]]*=[[:space:]]*"\K[^"]*/$v/m or die "::error::springboot2 version entry not found in gradle/libs.versions.toml\n"' "$springboot_version" gradle/libs.versions.toml - echo "Updated Spring Boot 2.x version to $springboot_version" - - name: Test integration suites - run: | - ./gradlew \ - :sentry-spring:integrationTest \ - :sentry-spring-boot:integrationTest \ - :sentry-spring-boot:integrationTestWebflux \ - :sentry-spring-boot:integrationTestOtelNoAgent \ - :sentry-spring-boot:integrationTestOtelAgent \ - :sentry-spring-boot:integrationTestOtelAgentWithoutAutoInit + # Runs every version even after one fails, as separate jobs per version would. + run: ./gradlew allIntegrationTestsBoot2 --continue - name: Upload test results if: always() uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: - name: test-results-springboot-2-${{ matrix.springboot-version }} + name: test-results-springboot-2 path: | **/build/reports/* **/build/test-results/**/*.xml @@ -80,7 +63,7 @@ jobs: uses: phoenix-actions/test-reporting@7317eea6e13c47348dd0bb318669485157c518d6 # pin@v16 if: always() with: - name: JUnit Spring Boot 2.x ${{ matrix.springboot-version }} + name: JUnit Spring Boot 2.x path: | **/build/test-results/**/*.xml reporter: java-junit diff --git a/.github/workflows/spring-boot-3-matrix.yml b/.github/workflows/spring-boot-3-matrix.yml index f698683cdc..9140a0f1fc 100644 --- a/.github/workflows/spring-boot-3-matrix.yml +++ b/.github/workflows/spring-boot-3-matrix.yml @@ -18,12 +18,7 @@ jobs: spring-boot-3-matrix: timeout-minutes: 45 runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - springboot-version: [ '3.2.12', '3.3.13', '3.4.13', '3.5.13' ] - - name: Spring Boot ${{ matrix.springboot-version }} + name: Spring Boot 3.x env: GRADLE_ENCRYPTION_KEY: ${{ secrets.GRADLE_ENCRYPTION_KEY }} @@ -51,28 +46,15 @@ jobs: with: cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - - name: Update Spring Boot 3.x version - run: | - springboot_version="${{ matrix.springboot-version }}" - perl -0pi -e 'BEGIN { $v = shift } s/^springboot3[[:space:]]*=[[:space:]]*"\K[^"]*/$v/m or die "::error::springboot3 version entry not found in gradle/libs.versions.toml\n"' "$springboot_version" gradle/libs.versions.toml - echo "Updated Spring Boot 3.x version to $springboot_version" - - name: Test integration suites - run: | - ./gradlew \ - :sentry-spring-jakarta:integrationTest \ - :sentry-spring-boot-jakarta:integrationTest \ - :sentry-spring-boot-jakarta:integrationTestWebflux \ - :sentry-spring-boot-jakarta:integrationTestOtelNoAgent \ - :sentry-spring-boot-jakarta:integrationTestLog4j2 \ - :sentry-spring-boot-jakarta:integrationTestOtelAgent \ - :sentry-spring-boot-jakarta:integrationTestOtelAgentWithoutAutoInit + # Runs every version even after one fails, as separate jobs per version would. + run: ./gradlew allIntegrationTestsBoot3 --continue - name: Upload test results if: always() uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: - name: test-results-springboot-3-${{ matrix.springboot-version }} + name: test-results-springboot-3 path: | **/build/reports/* **/build/test-results/**/*.xml @@ -81,7 +63,7 @@ jobs: uses: phoenix-actions/test-reporting@7317eea6e13c47348dd0bb318669485157c518d6 # pin@v16 if: always() with: - name: JUnit Spring Boot 3.x ${{ matrix.springboot-version }} + name: JUnit Spring Boot 3.x path: | **/build/test-results/**/*.xml reporter: java-junit diff --git a/.github/workflows/spring-boot-4-matrix.yml b/.github/workflows/spring-boot-4-matrix.yml index 8f91289db9..3524a66e3c 100644 --- a/.github/workflows/spring-boot-4-matrix.yml +++ b/.github/workflows/spring-boot-4-matrix.yml @@ -18,12 +18,7 @@ jobs: spring-boot-4-matrix: timeout-minutes: 45 runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - springboot-version: [ '4.0.0', '4.0.5', '4.1.0' ] - - name: Spring Boot ${{ matrix.springboot-version }} + name: Spring Boot 4.x env: GRADLE_ENCRYPTION_KEY: ${{ secrets.GRADLE_ENCRYPTION_KEY }} @@ -51,29 +46,15 @@ jobs: with: cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - - name: Update Spring Boot 4.x version - run: | - springboot_version="${{ matrix.springboot-version }}" - perl -0pi -e 'BEGIN { $v = shift } s/^springboot4[[:space:]]*=[[:space:]]*"\K[^"]*/$v/m or die "::error::springboot4 version entry not found in gradle/libs.versions.toml\n"' "$springboot_version" gradle/libs.versions.toml - echo "Updated Spring Boot 4.x version to $springboot_version" - - name: Test integration suites - run: | - ./gradlew \ - :sentry-spring-7:integrationTest \ - :sentry-spring-boot-4:integrationTest \ - :sentry-spring-boot-4:integrationTestWebflux \ - :sentry-spring-boot-4:integrationTestOtelNoAgent \ - :sentry-spring-boot-4:integrationTestLog4j2 \ - :sentry-spring-boot-4:integrationTestOtelAgent \ - :sentry-spring-boot-4:integrationTestOtelAgentWithoutAutoInit \ - :sentry-spring-boot-4:integrationTestOtlp + # Runs every version even after one fails, as separate jobs per version would. + run: ./gradlew allIntegrationTestsBoot4 --continue - name: Upload test results if: always() uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: - name: test-results-springboot-4-${{ matrix.springboot-version }} + name: test-results-springboot-4 path: | **/build/reports/* **/build/test-results/**/*.xml @@ -82,7 +63,7 @@ jobs: uses: phoenix-actions/test-reporting@7317eea6e13c47348dd0bb318669485157c518d6 # pin@v16 if: always() with: - name: JUnit Spring Boot 4.x ${{ matrix.springboot-version }} + name: JUnit Spring Boot 4.x path: | **/build/test-results/**/*.xml reporter: java-junit diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index d02ab58488..408aef2a0a 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -23,5 +23,9 @@ gradlePlugin { id = "io.sentry.animalsniffer.android" implementationClass = "io.sentry.gradle.SentryAnimalSnifferAndroidPlugin" } + register("sentrySpringBootMatrix") { + id = "io.sentry.spring-boot-matrix" + implementationClass = "io.sentry.gradle.SpringBootMatrixPlugin" + } } } diff --git a/build-logic/src/main/kotlin/io/sentry/gradle/SpringBootMatrixPlugin.kt b/build-logic/src/main/kotlin/io/sentry/gradle/SpringBootMatrixPlugin.kt new file mode 100644 index 0000000000..77fad36af4 --- /dev/null +++ b/build-logic/src/main/kotlin/io/sentry/gradle/SpringBootMatrixPlugin.kt @@ -0,0 +1,102 @@ +package io.sentry.gradle + +import javax.inject.Inject +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.file.FileCollection +import org.gradle.api.tasks.SourceSetContainer +import org.gradle.api.tasks.testing.Test +import org.gradle.language.base.plugins.LifecycleBasePlugin + +/** + * Runs integration suites on each Spring Boot version of a line, without recompiling anything. + * + * The suites and the SDK compile once, against the version catalog's Spring Boot version. For each + * version, a suite's test task reuses its compiled classes on a runtime classpath resolved for that + * version, which is how users run our published jars on their Spring Boot version. + */ +class SpringBootMatrixPlugin : Plugin { + override fun apply(project: Project) { + project.extensions.create("springBootMatrix", SpringBootMatrixExtension::class.java) + } +} + +abstract class SpringBootMatrixExtension @Inject constructor(private val project: Project) { + private var versions = emptyList() + + /** + * Registers `allIntegrationTestsBoot` for each of [versions], and + * `allIntegrationTestsBoot` for all of them, which CI runs from the root project for every + * module of the line at once. + */ + fun versions(versions: List) { + this.versions = versions + val major = versions.map { it.substringBefore('.') }.distinct().single() + project.tasks.register("allIntegrationTestsBoot$major") { + description = "Runs the integration suites on Spring Boot ${versions.joinToString()}." + group = LifecycleBasePlugin.VERIFICATION_GROUP + dependsOn(versions.map { aggregateName(it) }) + } + versions.forEach { version -> + project.tasks.register(aggregateName(version)) { + description = "Runs the integration suites on Spring Boot $version." + group = LifecycleBasePlugin.VERIFICATION_GROUP + } + } + } + + /** + * Registers `Boot` for each version, running [suite]'s tests. [name] tells apart + * several tasks of one suite, and [configure] adds what the suite's own task has beyond its + * classes and classpath. + */ + fun test(suite: String, name: String = suite, configure: Test.(version: String) -> Unit = {}) { + check(versions.isNotEmpty()) { "Call versions() before test()" } + versions.forEach { version -> + // Created now rather than with the task, so `dependencies --configuration` finds it. + val runtimeClasspath = runtimeClasspath(suite, version) + val task = + project.tasks.register("$name${suffix(version)}", Test::class.java) { + description = "Runs $name on Spring Boot $version." + group = LifecycleBasePlugin.VERIFICATION_GROUP + testClassesDirs = sourceSet(suite).output.classesDirs + classpath = runtimeClasspath + useJUnit() + configure(version) + } + project.tasks.named(aggregateName(version)) { dependsOn(task) } + } + } + + /** [sourceSet]'s output and runtime dependencies, with Spring Boot at [version]. */ + fun runtimeClasspath(sourceSet: String, version: String): FileCollection { + val sources = sourceSet(sourceSet) + val name = "$sourceSet${suffix(version)}RuntimeClasspath" + val configurations = project.configurations + val dependencies = + configurations.findByName(name) + ?: configurations.create(name) { + isCanBeConsumed = false + extendsFrom( + configurations.getByName(sources.implementationConfigurationName), + configurations.getByName(sources.runtimeOnlyConfigurationName), + ) + attributes.addAllLater( + configurations.getByName(sources.runtimeClasspathConfigurationName).attributes + ) + // What setting the version in the catalog does: every Spring Boot artifact, the BOM + // included, is in this group. Libraries pinned to their own version still win conflicts. + resolutionStrategy.eachDependency { + if (requested.group == "org.springframework.boot") useVersion(version) + } + } + return sources.output + dependencies + } + + private fun sourceSet(name: String) = + project.extensions.getByType(SourceSetContainer::class.java).getByName(name) + + private fun aggregateName(version: String) = "allIntegrationTests${suffix(version)}" + + private fun suffix(version: String) = "Boot" + version.replace('.', '_') +} diff --git a/build-logic/src/main/kotlin/io/sentry/gradle/SpringBootVersions.kt b/build-logic/src/main/kotlin/io/sentry/gradle/SpringBootVersions.kt new file mode 100644 index 0000000000..588d50ce7c --- /dev/null +++ b/build-logic/src/main/kotlin/io/sentry/gradle/SpringBootVersions.kt @@ -0,0 +1,11 @@ +package io.sentry.gradle + +/** + * The Spring Boot versions the Spring integration suites run on, per major line. A WAR suite runs + * on the same versions as its Boot module, because the Boot BOM decides its Spring version. + */ +object SpringBootVersions { + val BOOT_2 = listOf("2.7.0", "2.7.18") + val BOOT_3 = listOf("3.2.12", "3.3.13", "3.4.13", "3.5.13") + val BOOT_4 = listOf("4.0.0", "4.0.5", "4.1.0") +} diff --git a/sentry-spring-7/build.gradle.kts b/sentry-spring-7/build.gradle.kts index b9d418abe4..2eadb3efb6 100644 --- a/sentry-spring-7/build.gradle.kts +++ b/sentry-spring-7/build.gradle.kts @@ -1,3 +1,4 @@ +import io.sentry.gradle.SpringBootVersions import net.ltgt.gradle.errorprone.errorprone import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.springframework.boot.gradle.plugin.SpringBootPlugin @@ -5,6 +6,7 @@ import org.springframework.boot.gradle.plugin.SpringBootPlugin plugins { `java-library` id("io.sentry.javadoc") + id("io.sentry.spring-boot-matrix") alias(libs.plugins.kotlin.jvm) alias(libs.plugins.errorprone) alias(libs.plugins.gradle.versions) @@ -142,3 +144,9 @@ testing { } } } + +// The suites on each Spring Boot 4 version the CI matrix tests. +springBootMatrix { + versions(SpringBootVersions.BOOT_4) + test("integrationTest") +} diff --git a/sentry-spring-boot-4/build.gradle.kts b/sentry-spring-boot-4/build.gradle.kts index 7f4428551b..0077caf712 100644 --- a/sentry-spring-boot-4/build.gradle.kts +++ b/sentry-spring-boot-4/build.gradle.kts @@ -1,4 +1,5 @@ import io.sentry.gradle.ChildJvmTestArguments +import io.sentry.gradle.SpringBootVersions import net.ltgt.gradle.errorprone.errorprone import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.springframework.boot.gradle.plugin.SpringBootPlugin @@ -6,6 +7,7 @@ import org.springframework.boot.gradle.plugin.SpringBootPlugin plugins { `java-library` id("io.sentry.javadoc") + id("io.sentry.spring-boot-matrix") alias(libs.plugins.kotlin.jvm) alias(libs.plugins.kotlin.spring) alias(libs.plugins.errorprone) @@ -387,13 +389,17 @@ testing { /** * Has the OpenTelemetry agent tests start agentFixture's app in a child JVM, with the built agent * attached. [autoInit] decides whether the agent initializes Sentry or, as with - * `SENTRY_AUTO_INIT=false`, the Spring Boot starter. + * `SENTRY_AUTO_INIT=false`, the Spring Boot starter. [appClasspath] is the app's classpath for + * another Spring Boot version. */ -fun Test.runAgentFixture(autoInit: Boolean) { +fun Test.runAgentFixture( + autoInit: Boolean, + appClasspath: FileCollection = agentFixture.runtimeClasspath, +) { jvmArgumentProviders.add( objects.newInstance().apply { agentJar.from(otelAgentJar) - appClasspath.from(agentFixture.runtimeClasspath) + this.appClasspath.from(appClasspath) } ) systemProperty("sentry.test.agentAutoInit", autoInit) @@ -423,3 +429,19 @@ listOf( .forEach { tasks.named(it) { compilerOptions.javaParameters = true } } + +// The suites on each Spring Boot 4 version the CI matrix tests. +springBootMatrix { + versions(SpringBootVersions.BOOT_4) + test("integrationTest") + test("integrationTestLog4j2") + test("integrationTestWebflux") + test("integrationTestOtelNoAgent") + test("integrationTestOtlp") + test("integrationTestOtelAgent") { version -> + runAgentFixture(autoInit = true, appClasspath = runtimeClasspath("agentFixture", version)) + } + test("integrationTestOtelAgent", name = "integrationTestOtelAgentWithoutAutoInit") { version -> + runAgentFixture(autoInit = false, appClasspath = runtimeClasspath("agentFixture", version)) + } +} diff --git a/sentry-spring-boot-jakarta/build.gradle.kts b/sentry-spring-boot-jakarta/build.gradle.kts index 9451cf9511..3b97650119 100644 --- a/sentry-spring-boot-jakarta/build.gradle.kts +++ b/sentry-spring-boot-jakarta/build.gradle.kts @@ -1,4 +1,5 @@ import io.sentry.gradle.ChildJvmTestArguments +import io.sentry.gradle.SpringBootVersions import net.ltgt.gradle.errorprone.errorprone import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.springframework.boot.gradle.plugin.SpringBootPlugin @@ -6,6 +7,7 @@ import org.springframework.boot.gradle.plugin.SpringBootPlugin plugins { `java-library` id("io.sentry.javadoc") + id("io.sentry.spring-boot-matrix") alias(libs.plugins.kotlin.jvm) alias(libs.plugins.errorprone) alias(libs.plugins.gradle.versions) @@ -327,13 +329,17 @@ testing { /** * Has the OpenTelemetry agent tests start agentFixture's app in a child JVM, with the built agent * attached. [autoInit] decides whether the agent initializes Sentry or, as with - * `SENTRY_AUTO_INIT=false`, the Spring Boot starter. + * `SENTRY_AUTO_INIT=false`, the Spring Boot starter. [appClasspath] is the app's classpath for + * another Spring Boot version. */ -fun Test.runAgentFixture(autoInit: Boolean) { +fun Test.runAgentFixture( + autoInit: Boolean, + appClasspath: FileCollection = agentFixture.runtimeClasspath, +) { jvmArgumentProviders.add( objects.newInstance().apply { agentJar.from(otelAgentJar) - appClasspath.from(agentFixture.runtimeClasspath) + this.appClasspath.from(appClasspath) } ) systemProperty("sentry.test.agentAutoInit", autoInit) @@ -362,3 +368,18 @@ listOf( .forEach { tasks.named(it) { compilerOptions.javaParameters = true } } + +// The suites on each Spring Boot 3 version the CI matrix tests. +springBootMatrix { + versions(SpringBootVersions.BOOT_3) + test("integrationTest") + test("integrationTestLog4j2") + test("integrationTestWebflux") + test("integrationTestOtelNoAgent") + test("integrationTestOtelAgent") { version -> + runAgentFixture(autoInit = true, appClasspath = runtimeClasspath("agentFixture", version)) + } + test("integrationTestOtelAgent", name = "integrationTestOtelAgentWithoutAutoInit") { version -> + runAgentFixture(autoInit = false, appClasspath = runtimeClasspath("agentFixture", version)) + } +} diff --git a/sentry-spring-boot/build.gradle.kts b/sentry-spring-boot/build.gradle.kts index 3f24e73dc9..c20bdc71e9 100644 --- a/sentry-spring-boot/build.gradle.kts +++ b/sentry-spring-boot/build.gradle.kts @@ -1,4 +1,5 @@ import io.sentry.gradle.ChildJvmTestArguments +import io.sentry.gradle.SpringBootVersions import net.ltgt.gradle.errorprone.errorprone import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile @@ -6,6 +7,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { `java-library` id("io.sentry.javadoc") + id("io.sentry.spring-boot-matrix") alias(libs.plugins.kotlin.jvm) alias(libs.plugins.errorprone) alias(libs.plugins.gradle.versions) @@ -272,13 +274,17 @@ testing { /** * Has the OpenTelemetry agent tests start agentFixture's app in a child JVM, with the built agent * attached. [autoInit] decides whether the agent initializes Sentry or, as with - * `SENTRY_AUTO_INIT=false`, the Spring Boot starter. + * `SENTRY_AUTO_INIT=false`, the Spring Boot starter. [appClasspath] is the app's classpath for + * another Spring Boot version. */ -fun Test.runAgentFixture(autoInit: Boolean) { +fun Test.runAgentFixture( + autoInit: Boolean, + appClasspath: FileCollection = agentFixture.runtimeClasspath, +) { jvmArgumentProviders.add( objects.newInstance().apply { agentJar.from(otelAgentJar) - appClasspath.from(agentFixture.runtimeClasspath) + this.appClasspath.from(appClasspath) } ) systemProperty("sentry.test.agentAutoInit", autoInit) @@ -308,3 +314,17 @@ listOf( .forEach { tasks.named(it) { compilerOptions.javaParameters = true } } + +// The suites on each Spring Boot 2 version the CI matrix tests. +springBootMatrix { + versions(SpringBootVersions.BOOT_2) + test("integrationTest") + test("integrationTestWebflux") + test("integrationTestOtelNoAgent") + test("integrationTestOtelAgent") { version -> + runAgentFixture(autoInit = true, appClasspath = runtimeClasspath("agentFixture", version)) + } + test("integrationTestOtelAgent", name = "integrationTestOtelAgentWithoutAutoInit") { version -> + runAgentFixture(autoInit = false, appClasspath = runtimeClasspath("agentFixture", version)) + } +} diff --git a/sentry-spring-jakarta/build.gradle.kts b/sentry-spring-jakarta/build.gradle.kts index 701d5a0420..a3478b383f 100644 --- a/sentry-spring-jakarta/build.gradle.kts +++ b/sentry-spring-jakarta/build.gradle.kts @@ -1,3 +1,4 @@ +import io.sentry.gradle.SpringBootVersions import net.ltgt.gradle.errorprone.errorprone import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.springframework.boot.gradle.plugin.SpringBootPlugin @@ -5,6 +6,7 @@ import org.springframework.boot.gradle.plugin.SpringBootPlugin plugins { `java-library` id("io.sentry.javadoc") + id("io.sentry.spring-boot-matrix") alias(libs.plugins.kotlin.jvm) alias(libs.plugins.errorprone) alias(libs.plugins.gradle.versions) @@ -129,3 +131,9 @@ testing { } } } + +// The suites on each Spring Boot 3 version the CI matrix tests. +springBootMatrix { + versions(SpringBootVersions.BOOT_3) + test("integrationTest") +} diff --git a/sentry-spring/build.gradle.kts b/sentry-spring/build.gradle.kts index f11087c1b0..c9e2620d56 100644 --- a/sentry-spring/build.gradle.kts +++ b/sentry-spring/build.gradle.kts @@ -1,3 +1,4 @@ +import io.sentry.gradle.SpringBootVersions import net.ltgt.gradle.errorprone.errorprone import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile @@ -5,6 +6,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { `java-library` id("io.sentry.javadoc") + id("io.sentry.spring-boot-matrix") alias(libs.plugins.kotlin.jvm) alias(libs.plugins.errorprone) alias(libs.plugins.gradle.versions) @@ -117,3 +119,9 @@ testing { } } } + +// The suites on each Spring Boot 2 version the CI matrix tests. +springBootMatrix { + versions(SpringBootVersions.BOOT_2) + test("integrationTest") +}