Skip to content
Open
11 changes: 8 additions & 3 deletions .github/workflows/spring-boot-2-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
strategy:
fail-fast: false
matrix:
springboot-version: [ '2.1.0', '2.2.5', '2.4.13', '2.5.15', '2.6.15', '2.7.0', '2.7.18' ]
springboot-version: [ '2.4.13', '2.5.15', '2.6.15', '2.7.0', '2.7.18' ]

name: Spring Boot ${{ matrix.springboot-version }}
env:
Expand Down Expand Up @@ -62,8 +62,13 @@ jobs:

- name: Update Spring Boot 2.x version
run: |
sed -i 's/^springboot2=.*/springboot2=${{ matrix.springboot-version }}/' gradle/libs.versions.toml
echo "Updated Spring Boot 2.x version to ${{ matrix.springboot-version }}"
springboot_version="${{ matrix.springboot-version }}"
if [[ ! "$springboot_version" =~ ^2\.7\. ]]; then
echo "ORG_GRADLE_PROJECT_excludeGraphql=true" >> "$GITHUB_ENV"
echo "ORG_GRADLE_PROJECT_excludeKafka=true" >> "$GITHUB_ENV"
fi
sed -i 's/^\(springboot2[[:space:]]*=[[:space:]]*\)".*"/\1"'"$springboot_version"'"/' gradle/libs.versions.toml
Copy link
Copy Markdown
Contributor

@runningcode runningcode May 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this PR is about fixing the fact that this sed wasn't replacing versions correctly, how do we prevent changes or refactoring of libs.versions.toml file from breaking this? Can we make this fail if no replacement is found?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we should

echo "Updated Spring Boot 2.x version to $springboot_version"

- name: Exclude android modules from build
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/spring-boot-3-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
strategy:
fail-fast: false
matrix:
springboot-version: [ '3.0.0', '3.2.12', '3.3.13', '3.4.13', '3.5.13' ]
springboot-version: [ '3.2.12', '3.3.13', '3.4.13', '3.5.13' ]

name: Spring Boot ${{ matrix.springboot-version }}
env:
Expand Down Expand Up @@ -62,7 +62,7 @@ jobs:

- name: Update Spring Boot 3.x version
run: |
sed -i 's/^springboot3=.*/springboot3=${{ matrix.springboot-version }}/' gradle/libs.versions.toml
sed -i 's/^\(springboot3[[:space:]]*=[[:space:]]*\)".*"/\1"${{ matrix.springboot-version }}"/' gradle/libs.versions.toml
echo "Updated Spring Boot 3.x version to ${{ matrix.springboot-version }}"
- name: Exclude android modules from build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/spring-boot-4-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:

- name: Update Spring Boot 4.x version
run: |
sed -i 's/^springboot4=.*/springboot4=${{ matrix.springboot-version }}/' gradle/libs.versions.toml
sed -i 's/^\(springboot4[[:space:]]*=[[:space:]]*\)".*"/\1"${{ matrix.springboot-version }}"/' gradle/libs.versions.toml
echo "Updated Spring Boot 4.x version to ${{ matrix.springboot-version }}"
- name: Exclude android modules from build
Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ slf4j2-api = { module = "org.slf4j:slf4j-api", version = "2.0.5" }
spotlessLib = { module = "com.diffplug.spotless:com.diffplug.spotless.gradle.plugin", version.ref = "spotless"}
springboot2-bom = { module = "org.springframework.boot:spring-boot-dependencies", version.ref = "springboot2" }
springboot-starter = { module = "org.springframework.boot:spring-boot-starter", version.ref = "springboot2" }
spring-graphql = { module = "org.springframework.graphql:spring-graphql", version = "1.0.6" }
springboot-starter-graphql = { module = "org.springframework.boot:spring-boot-starter-graphql", version.ref = "springboot2" }
springboot-starter-quartz = { module = "org.springframework.boot:spring-boot-starter-quartz", version.ref = "springboot2" }
springboot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test", version.ref = "springboot2" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ java.targetCompatibility = JavaVersion.VERSION_17

repositories { mavenCentral() }

dependencyManagement {
imports {
mavenBom("org.springframework.boot:spring-boot-dependencies:${libs.versions.springboot3.get()}")
mavenBom(libs.otel.instrumentation.bom.get().toString())
}
}

// Apollo 4.x requires coroutines 1.9.0+, override Spring Boot's managed version
extra["kotlin-coroutines.version"] = "1.9.0"

Expand Down Expand Up @@ -79,8 +86,6 @@ dependencies {
testImplementation("ch.qos.logback:logback-core:1.5.16")
}

dependencyManagement { imports { mavenBom(libs.otel.instrumentation.bom.get().toString()) } }

configure<SourceSetContainer> { test { java.srcDir("src/test/java") } }

tasks.register<Test>("systemTest").configure {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ java.targetCompatibility = JavaVersion.VERSION_17

repositories { mavenCentral() }

dependencyManagement {
imports {
mavenBom("org.springframework.boot:spring-boot-dependencies:${libs.versions.springboot3.get()}")
}
}

// Apollo 4.x requires coroutines 1.9.0+, override Spring Boot's managed version
extra["kotlin-coroutines.version"] = "1.9.0"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ java.targetCompatibility = JavaVersion.VERSION_17

repositories { mavenCentral() }

dependencyManagement {
imports {
mavenBom("org.springframework.boot:spring-boot-dependencies:${libs.versions.springboot3.get()}")
}
}

// Apollo 4.x requires coroutines 1.9.0+, override Spring Boot's managed version
extra["kotlin-coroutines.version"] = "1.9.0"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,37 @@ group = "io.sentry.sample.spring-boot"

version = "0.0.1-SNAPSHOT"

java.sourceCompatibility = JavaVersion.VERSION_17
java.sourceCompatibility = JavaVersion.VERSION_11

java.targetCompatibility = JavaVersion.VERSION_17
java.targetCompatibility = JavaVersion.VERSION_11

repositories { mavenCentral() }

fun springBoot2SupportsOptionalIntegrations(): Boolean {
val version = libs.versions.springboot2.get().removeSuffix(".RELEASE")
val parts = version.split(".").map { it.toIntOrNull() ?: 0 }
val major = parts.getOrElse(0) { 0 }
val minor = parts.getOrElse(1) { 0 }
return major > 2 || (major == 2 && minor >= 7)
}

val includeGraphql =
!project.hasProperty("excludeGraphql") && springBoot2SupportsOptionalIntegrations()
val includeKafka = !project.hasProperty("excludeKafka") && springBoot2SupportsOptionalIntegrations()

configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

tasks.withType<KotlinCompile>().configureEach {
compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
}

tasks.withType<KotlinCompile>().configureEach {
kotlin {
compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict")
compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
}
}

Expand All @@ -43,7 +55,9 @@ dependencies {
implementation(libs.springboot.starter)
implementation(libs.springboot.starter.actuator)
implementation(libs.springboot.starter.aop)
implementation(libs.springboot.starter.graphql)
if (includeGraphql) {
implementation(libs.springboot.starter.graphql)
}
implementation(libs.springboot.starter.jdbc)
implementation(libs.springboot.starter.quartz)
implementation(libs.springboot.starter.security)
Expand All @@ -55,14 +69,17 @@ dependencies {
implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION))
implementation(projects.sentrySpringBootStarter)
implementation(projects.sentryLogback)
implementation(projects.sentryGraphql)
if (includeGraphql) {
implementation(projects.sentryGraphql)
}
implementation(projects.sentryQuartz)
implementation(projects.sentryOpentelemetry.sentryOpentelemetryAgentlessSpring)
implementation(projects.sentryAsyncProfiler)

// kafka
implementation(libs.spring.kafka2)
implementation(projects.sentryKafka)
if (includeKafka) {
implementation(libs.spring.kafka2)
implementation(projects.sentryKafka)
}

// database query tracing
implementation(projects.sentryJdbc)
Expand Down Expand Up @@ -103,7 +120,19 @@ tasks.jar {

tasks.startScripts { dependsOn(tasks.shadowJar) }

configure<SourceSetContainer> { test { java.srcDir("src/test/java") } }
configure<SourceSetContainer> {
main {
if (!includeGraphql) {
Copy link
Copy Markdown
Contributor

@runningcode runningcode May 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the best gradle caching it would be best to make these 3 separate source sets.
This way they can each get their own cache entry and be compiled separately.
This depends however on what their dependencies look like but I imagine that if they are easily excluded like this that the sources are independent.

EDIT: after scrolling further down and seeing that they also have different imports maybe I need to understand better why we need this. could you explain it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since older versions of Spring Boot 2 don't have GraphQL support, we're excluding it from the sample in the matrix build.

java.exclude("**/graphql/**")
resources.exclude("graphql/**")
}
if (!includeKafka) {
java.exclude("**/queues/kafka/**")
resources.exclude("application-kafka.properties")
}
}
test { java.srcDir("src/test/java") }
Copy link
Copy Markdown
Contributor

@runningcode runningcode May 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if this is the implicit default, why do we need this?
Does spring boot or something else change it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably redundant, can try to remove

}

tasks.register<Test>("systemTest").configure {
group = "verification"
Expand All @@ -121,7 +150,15 @@ tasks.register<Test>("systemTest").configure {
minHeapSize = "128m"
maxHeapSize = "1g"

filter { includeTestsMatching("io.sentry.systemtest*") }
filter {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, if we use 3 separate test source sets/tasks we can compile and execute/cache them independently.

includeTestsMatching("io.sentry.systemtest*")
if (!includeGraphql) {
excludeTestsMatching("io.sentry.systemtest.Graphql*")
}
if (!includeKafka) {
excludeTestsMatching("io.sentry.systemtest.Kafka*")
}
}
}

tasks.named("test").configure {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,34 @@ group = "io.sentry.sample.spring-boot"

version = "0.0.1-SNAPSHOT"

java.sourceCompatibility = JavaVersion.VERSION_17
java.sourceCompatibility = JavaVersion.VERSION_11

java.targetCompatibility = JavaVersion.VERSION_17
java.targetCompatibility = JavaVersion.VERSION_11

repositories { mavenCentral() }

fun springBoot2SupportsOptionalIntegrations(): Boolean {
val version = libs.versions.springboot2.get().removeSuffix(".RELEASE")
val parts = version.split(".").map { it.toIntOrNull() ?: 0 }
val major = parts.getOrElse(0) { 0 }
val minor = parts.getOrElse(1) { 0 }
return major > 2 || (major == 2 && minor >= 7)
}

val includeGraphql =
!project.hasProperty("excludeGraphql") && springBoot2SupportsOptionalIntegrations()
val includeKafka = !project.hasProperty("excludeKafka") && springBoot2SupportsOptionalIntegrations()

configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

tasks.withType<KotlinCompile>().configureEach {
compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should we import this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

kotlin {
compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict")
compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
}
}

Expand All @@ -39,7 +51,9 @@ dependencies {
implementation(libs.springboot.starter)
implementation(libs.springboot.starter.actuator)
implementation(libs.springboot.starter.aop)
implementation(libs.springboot.starter.graphql)
if (includeGraphql) {
implementation(libs.springboot.starter.graphql)
}
implementation(libs.springboot.starter.jdbc)
implementation(libs.springboot.starter.quartz)
implementation(libs.springboot.starter.security)
Expand All @@ -51,14 +65,17 @@ dependencies {
implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION))
implementation(projects.sentrySpringBootStarter)
implementation(projects.sentryLogback)
implementation(projects.sentryGraphql)
if (includeGraphql) {
implementation(projects.sentryGraphql)
}
implementation(projects.sentryQuartz)
implementation(projects.sentryAsyncProfiler)
implementation(libs.otel)

// kafka
implementation(libs.spring.kafka2)
implementation(projects.sentryKafka)
if (includeKafka) {
implementation(libs.spring.kafka2)
implementation(projects.sentryKafka)
}

// database query tracing
implementation(projects.sentryJdbc)
Expand Down Expand Up @@ -99,7 +116,19 @@ tasks.jar {

tasks.startScripts { dependsOn(tasks.shadowJar) }

configure<SourceSetContainer> { test { java.srcDir("src/test/java") } }
configure<SourceSetContainer> {
main {
if (!includeGraphql) {
java.exclude("**/graphql/**")
resources.exclude("graphql/**")
}
if (!includeKafka) {
java.exclude("**/queues/kafka/**")
resources.exclude("application-kafka.properties")
}
}
test { java.srcDir("src/test/java") }
}

tasks.register<JavaExec>("bootRunWithAgent").configure {
group = "application"
Expand Down Expand Up @@ -141,7 +170,15 @@ tasks.register<Test>("systemTest").configure {
minHeapSize = "128m"
maxHeapSize = "1g"

filter { includeTestsMatching("io.sentry.systemtest*") }
filter {
includeTestsMatching("io.sentry.systemtest*")
if (!includeGraphql) {
excludeTestsMatching("io.sentry.systemtest.Graphql*")
}
if (!includeKafka) {
excludeTestsMatching("io.sentry.systemtest.Kafka*")
}
}
}

tasks.named("test").configure {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ java.targetCompatibility = JavaVersion.VERSION_17

repositories { mavenCentral() }

dependencyManagement {
imports {
mavenBom("org.springframework.boot:spring-boot-dependencies:${libs.versions.springboot3.get()}")
}
}

// Apollo 4.x requires coroutines 1.9.0+, override Spring Boot's managed version
extra["kotlin-coroutines.version"] = "1.9.0"

Expand Down
Loading
Loading