From 5ee8b2a7aad01bec3b4bad95303136b04bac4d78 Mon Sep 17 00:00:00 2001 From: Dennis Fokin Date: Fri, 20 Mar 2026 11:16:48 +0100 Subject: [PATCH 01/11] Add Gradle tasks for running tests with LTS Java versions --- .github/workflows/build.yml | 44 +++++++++---------- .../kotlin/project-convention-java.gradle.kts | 35 +++++++++++++++ webauthn-server-attestation/build.gradle.kts | 2 +- 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5c356e809..18c1aa0fe 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,53 +19,49 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [8, 11, 17, 18] + java: [8, 11, 17, 21, 25] distribution: [temurin] include: - - java: 17 + - java: 25 distribution: zulu - - java: 17 + - java: 25 distribution: microsoft outputs: - report-java: 17 + report-java: 25 report-dist: temurin steps: - name: Check out code uses: actions/checkout@v6 - - name: Set up JDK 17 - uses: actions/setup-java@v5 - with: - java-version: 17 - distribution: ${{ matrix.distribution }} - - - name: Compile libraries and tests - run: ./gradlew clean testClasses - - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@v5 with: java-version: ${{ matrix.java }} distribution: ${{ matrix.distribution }} - - name: Run tests against JDK17-compiled code - run: ./gradlew test --exclude-task compileJava - - - name: Archive HTML test report on failure - if: ${{ failure() }} - uses: actions/upload-artifact@v5 - with: - name: test-reports-java17-java${{ matrix.java }}-${{ matrix.distribution }}-html - path: "*/build/reports/**" - - name: Build and test with JDK ${{ matrix.java }} run: ./gradlew clean test - name: Build archives run: ./gradlew assemble + - name: Run test using Java 25 runtime + run: ./gradlew testJava25 + + - name: Run test using Java 21 runtime + run: ./gradlew testJava21 + + - name: Run test using Java 17 runtime + run: ./gradlew testJava17 + + - name: Run test using Java 11 runtime + run: ./gradlew testJava11 + + - name: Run test using Java 8 runtime + run: ./gradlew testJava8 + - name: Archive HTML test report if: ${{ always() }} uses: actions/upload-artifact@v5 @@ -73,7 +69,7 @@ jobs: name: test-reports-java${{ matrix.java }}-${{ matrix.distribution }}-html path: "*/build/reports/**" - - name: Archive JUnit test report + - name: Archive JUnit test reports if: ${{ always() }} uses: actions/upload-artifact@v5 with: diff --git a/buildSrc/src/main/kotlin/project-convention-java.gradle.kts b/buildSrc/src/main/kotlin/project-convention-java.gradle.kts index bf19301ad..e7ab746a9 100644 --- a/buildSrc/src/main/kotlin/project-convention-java.gradle.kts +++ b/buildSrc/src/main/kotlin/project-convention-java.gradle.kts @@ -14,3 +14,38 @@ tasks.withType(JavaCompile::class) { sourceCompatibility = "1.8" } } + +tasks.register("testJava8") { + javaLauncher.set(javaToolchains.launcherFor { + languageVersion.set(JavaLanguageVersion.of(8)) + }) + tasks["check"].dependsOn(this) +} + +tasks.register("testJava11") { + javaLauncher.set(javaToolchains.launcherFor { + languageVersion.set(JavaLanguageVersion.of(11)) + }) + tasks["check"].dependsOn(this) +} + +tasks.register("testJava17") { + javaLauncher.set(javaToolchains.launcherFor { + languageVersion.set(JavaLanguageVersion.of(17)) + }) + tasks["check"].dependsOn(this) +} + +tasks.register("testJava21") { + javaLauncher.set(javaToolchains.launcherFor { + languageVersion.set(JavaLanguageVersion.of(21)) + }) + tasks["check"].dependsOn(this) +} + +tasks.register("testJava25") { + javaLauncher.set(javaToolchains.launcherFor { + languageVersion.set(JavaLanguageVersion.of(25)) + }) + tasks["check"].dependsOn(this) +} \ No newline at end of file diff --git a/webauthn-server-attestation/build.gradle.kts b/webauthn-server-attestation/build.gradle.kts index 713cd59e5..69db25c6a 100644 --- a/webauthn-server-attestation/build.gradle.kts +++ b/webauthn-server-attestation/build.gradle.kts @@ -54,7 +54,7 @@ dependencies { testRuntimeOnly("uk.org.lidalia:slf4j-test") } -val integrationTest = task("integrationTest") { +val integrationTest = tasks.register("integrationTest") { description = "Runs integration tests." group = "verification" From 7f924dca505e95b990c911b72b8337072a14456a Mon Sep 17 00:00:00 2001 From: Dennis Fokin Date: Fri, 20 Mar 2026 14:15:15 +0100 Subject: [PATCH 02/11] Upgrade to Gradle 9 --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 4abf68a62..a9bdcf335 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ import com.yubico.gradle.GitUtils project.ext.isCiBuild = System.env.CI == 'true' wrapper { - gradleVersion = '8.14.3' + gradleVersion = '9.0.0' } dependencies { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d4081da47..2a84e188b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From c6712110317910f8096074f48bd5708dcdf94469 Mon Sep 17 00:00:00 2001 From: Dennis Fokin Date: Fri, 20 Mar 2026 14:29:06 +0100 Subject: [PATCH 03/11] Gradle fixes --- buildSrc/build.gradle.kts | 4 ++-- .../com/yubico/gradle/pitest/tasks/PitestMergeTask.groovy | 1 + buildSrc/src/main/kotlin/project-convention-pitest.gradle.kts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 53c8a5f8f..b230e80b0 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -10,13 +10,13 @@ repositories { } dependencies { - implementation("info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.15.0") + implementation("info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.19.0-rc.2") implementation("io.franzbecker:gradle-lombok:5.0.0") // Spotless dropped Java 8 support in version 2.33.0 // spotless-plugin-gradle dropped Java <17 support in version 8.0.0 if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { implementation("com.diffplug.spotless:spotless-plugin-gradle:8.2.0") - implementation("io.github.cosmicsilence:gradle-scalafix:0.2.2") + implementation("io.github.cosmicsilence:gradle-scalafix:0.2.6") } } diff --git a/buildSrc/src/main/groovy/com/yubico/gradle/pitest/tasks/PitestMergeTask.groovy b/buildSrc/src/main/groovy/com/yubico/gradle/pitest/tasks/PitestMergeTask.groovy index 720341d72..f330f7d33 100644 --- a/buildSrc/src/main/groovy/com/yubico/gradle/pitest/tasks/PitestMergeTask.groovy +++ b/buildSrc/src/main/groovy/com/yubico/gradle/pitest/tasks/PitestMergeTask.groovy @@ -1,6 +1,7 @@ package com.yubico.gradle.pitest.tasks import groovy.xml.XmlUtil +import groovy.xml.XmlParser import info.solidsoft.gradle.pitest.PitestTask import org.gradle.api.DefaultTask diff --git a/buildSrc/src/main/kotlin/project-convention-pitest.gradle.kts b/buildSrc/src/main/kotlin/project-convention-pitest.gradle.kts index 0bd7a5104..40e19a76f 100644 --- a/buildSrc/src/main/kotlin/project-convention-pitest.gradle.kts +++ b/buildSrc/src/main/kotlin/project-convention-pitest.gradle.kts @@ -4,7 +4,7 @@ plugins { } pitest { - pitestVersion.set("1.15.0") + pitestVersion.set("1.20.3") timestampedReports.set(false) outputFormats.set(listOf("XML", "HTML")) From 6b0fd8199e01f2442a5f54110559d7113290c0d1 Mon Sep 17 00:00:00 2001 From: Dennis Fokin Date: Fri, 20 Mar 2026 14:32:55 +0100 Subject: [PATCH 04/11] Use io.freefair.gradle lombok plugin --- buildSrc/build.gradle.kts | 2 +- .../groovy/project-convention-lombok.gradle | 34 +------------------ 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index b230e80b0..18cb5dd9f 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -11,7 +11,7 @@ repositories { dependencies { implementation("info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.19.0-rc.2") - implementation("io.franzbecker:gradle-lombok:5.0.0") + implementation("io.freefair.gradle:lombok-plugin:9.2.0") // Spotless dropped Java 8 support in version 2.33.0 // spotless-plugin-gradle dropped Java <17 support in version 8.0.0 diff --git a/buildSrc/src/main/groovy/project-convention-lombok.gradle b/buildSrc/src/main/groovy/project-convention-lombok.gradle index 13ce462d1..c7b35b69a 100644 --- a/buildSrc/src/main/groovy/project-convention-lombok.gradle +++ b/buildSrc/src/main/groovy/project-convention-lombok.gradle @@ -1,36 +1,4 @@ -import io.franzbecker.gradle.lombok.task.DelombokTask - plugins { id "java" - id "io.franzbecker.gradle-lombok" -} - -lombok { - version = "1.18.24" - sha256 = "d3584bc2db03f059f984fb0a9c119aac1fa0da578a448e69fc3f68b36584c749" -} - -tasks.withType(AbstractCompile.class) { - dependsOn(tasks.verifyLombok) -} - -task delombok(type: DelombokTask.class, dependsOn: tasks.classes) { - ext.outputDir = file("${buildDir}/delombok") - outputs.dir(outputDir) - project.sourceSets.main.java.srcDirs.forEach { - if (!it.exists()) { - it.mkdirs() - } - inputs.dir(it) - args(it, "-d", outputDir) - } - doFirst { - outputDir.deleteDir() - } -} - -javadoc { - dependsOn(delombok) - source = tasks.delombok.outputDir - inputs.dir(tasks.delombok.outputDir) + id "io.freefair.lombok" } From 4cb45ead355da9b8dcab0aef8465fde2a771d2cd Mon Sep 17 00:00:00 2001 From: Dennis Fokin Date: Fri, 20 Mar 2026 14:34:42 +0100 Subject: [PATCH 05/11] Comment out jmh --- webauthn-server-core/build.gradle.kts | 12 ++++++------ yubico-util/build.gradle.kts | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/webauthn-server-core/build.gradle.kts b/webauthn-server-core/build.gradle.kts index 70b9c5a98..f234de334 100644 --- a/webauthn-server-core/build.gradle.kts +++ b/webauthn-server-core/build.gradle.kts @@ -1,6 +1,6 @@ plugins { `java-library` - id("me.champeau.jmh") version "0.6.8" + // id("me.champeau.jmh") version "0.7.3" `project-convention-java` `project-convention-scala` `project-convention-lombok` @@ -42,13 +42,13 @@ dependencies { } } - jmhImplementation(platform(project(":test-platform"))) - jmhRuntimeOnly("org.slf4j:slf4j-nop") + // jmhImplementation(platform(project(":test-platform"))) + // jmhRuntimeOnly("org.slf4j:slf4j-nop") } -configurations.jmhRuntimeClasspath { - exclude(module = "slf4j-test") -} +// configurations.jmhRuntimeClasspath { +// exclude(module = "slf4j-test") +// } tasks.withType(Jar::class) { manifest { diff --git a/yubico-util/build.gradle.kts b/yubico-util/build.gradle.kts index 0012ca94a..d12ba2504 100644 --- a/yubico-util/build.gradle.kts +++ b/yubico-util/build.gradle.kts @@ -1,6 +1,6 @@ plugins { `java-library` - id("me.champeau.jmh") version "0.6.8" + // id("me.champeau.jmh") version "0.7.3" `project-convention-java` `project-convention-scala` `project-convention-lombok` @@ -30,13 +30,13 @@ dependencies { testImplementation("org.scalatestplus:junit-4-13_2.13") testImplementation("org.scalatestplus:scalacheck-1-16_2.13") - jmhImplementation(platform(project(":test-platform"))) - jmhRuntimeOnly("org.slf4j:slf4j-nop") + // jmhImplementation(platform(project(":test-platform"))) + // jmhRuntimeOnly("org.slf4j:slf4j-nop") } -configurations.jmhRuntimeClasspath { - exclude(module = "slf4j-test") -} +// configurations.jmhRuntimeClasspath { +// exclude(module = "slf4j-test") +// } tasks.jar { manifest { From e4450c277730159b7a24e12c64aa362cc9f237a5 Mon Sep 17 00:00:00 2001 From: Dennis Fokin Date: Thu, 2 Apr 2026 09:20:21 +0200 Subject: [PATCH 06/11] Bump CI Java version --- .github/workflows/build.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 18c1aa0fe..ba5dd00ac 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [8, 11, 17, 21, 25] + java: [17, 21, 25] distribution: [temurin] include: - java: 25 @@ -62,7 +62,7 @@ jobs: - name: Run test using Java 8 runtime run: ./gradlew testJava8 - - name: Archive HTML test report + - name: Archive HTML test reports if: ${{ always() }} uses: actions/upload-artifact@v5 with: @@ -77,7 +77,6 @@ jobs: path: "*/build/test-results/**/*.xml" - name: Check binary reproducibility - if: ${{ matrix.java != 8 }} # JDK 8 does not produce reproducible binaries run: | ./gradlew clean primaryPublishJar find . -name '*.jar' | grep -v buildSrc | grep -v gradle-wrapper | xargs sha256sum | tee java-webauthn-server-artifacts.sha256sum @@ -85,7 +84,6 @@ jobs: ./gradlew clean primaryPublishJar && sha256sum -c java-webauthn-server-artifacts.sha256sum - name: Archive artifact checksums - if: ${{ matrix.java != 8 }} # JDK 8 does not produce reproducible binaries uses: actions/upload-artifact@v5 with: name: artifact-checksums-java${{ matrix.java }}-${{ matrix.distribution }} From 0ce0c6b3b584555fa436407e3f5363bb06a62bc2 Mon Sep 17 00:00:00 2001 From: Dennis Fokin Date: Mon, 20 Apr 2026 14:52:26 +0200 Subject: [PATCH 07/11] Bump to gradle 9.1.0, since it supports java 25 --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index a9bdcf335..baeb81154 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ import com.yubico.gradle.GitUtils project.ext.isCiBuild = System.env.CI == 'true' wrapper { - gradleVersion = '9.0.0' + gradleVersion = '9.1.0' } dependencies { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2a84e188b..2e1113280 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From edc24bb4beb31ac8f6bebb63072fde001ce1e74b Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Tue, 21 Apr 2026 16:46:56 +0200 Subject: [PATCH 08/11] fixup! Add Gradle tasks for running tests with LTS Java versions --- .../src/main/kotlin/project-convention-java.gradle.kts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/buildSrc/src/main/kotlin/project-convention-java.gradle.kts b/buildSrc/src/main/kotlin/project-convention-java.gradle.kts index e7ab746a9..7836a5563 100644 --- a/buildSrc/src/main/kotlin/project-convention-java.gradle.kts +++ b/buildSrc/src/main/kotlin/project-convention-java.gradle.kts @@ -16,6 +16,8 @@ tasks.withType(JavaCompile::class) { } tasks.register("testJava8") { + testClassesDirs = tasks.named("test").get().testClassesDirs + classpath = tasks.named("test").get().classpath javaLauncher.set(javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(8)) }) @@ -23,6 +25,8 @@ tasks.register("testJava8") { } tasks.register("testJava11") { + testClassesDirs = tasks.named("test").get().testClassesDirs + classpath = tasks.named("test").get().classpath javaLauncher.set(javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(11)) }) @@ -30,6 +34,8 @@ tasks.register("testJava11") { } tasks.register("testJava17") { + testClassesDirs = tasks.named("test").get().testClassesDirs + classpath = tasks.named("test").get().classpath javaLauncher.set(javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(17)) }) @@ -37,6 +43,8 @@ tasks.register("testJava17") { } tasks.register("testJava21") { + testClassesDirs = tasks.named("test").get().testClassesDirs + classpath = tasks.named("test").get().classpath javaLauncher.set(javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(21)) }) @@ -44,6 +52,8 @@ tasks.register("testJava21") { } tasks.register("testJava25") { + testClassesDirs = tasks.named("test").get().testClassesDirs + classpath = tasks.named("test").get().classpath javaLauncher.set(javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(25)) }) From 0cda34ae73db91bc9883ac0b6838ef26f8abe347 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Tue, 21 Apr 2026 17:10:09 +0200 Subject: [PATCH 09/11] squash! Comment out jmh Upgrade `me.champeau.jmh` plugin --- webauthn-server-core/build.gradle.kts | 12 ++++++------ yubico-util/build.gradle.kts | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/webauthn-server-core/build.gradle.kts b/webauthn-server-core/build.gradle.kts index f234de334..1091211af 100644 --- a/webauthn-server-core/build.gradle.kts +++ b/webauthn-server-core/build.gradle.kts @@ -1,6 +1,6 @@ plugins { `java-library` - // id("me.champeau.jmh") version "0.7.3" + id("me.champeau.jmh") version "0.7.3" `project-convention-java` `project-convention-scala` `project-convention-lombok` @@ -42,13 +42,13 @@ dependencies { } } - // jmhImplementation(platform(project(":test-platform"))) - // jmhRuntimeOnly("org.slf4j:slf4j-nop") + jmhImplementation(platform(project(":test-platform"))) + jmhRuntimeOnly("org.slf4j:slf4j-nop") } -// configurations.jmhRuntimeClasspath { -// exclude(module = "slf4j-test") -// } +configurations.jmhRuntimeClasspath { + exclude(module = "slf4j-test") +} tasks.withType(Jar::class) { manifest { diff --git a/yubico-util/build.gradle.kts b/yubico-util/build.gradle.kts index d12ba2504..d387ff5d8 100644 --- a/yubico-util/build.gradle.kts +++ b/yubico-util/build.gradle.kts @@ -1,6 +1,6 @@ plugins { `java-library` - // id("me.champeau.jmh") version "0.7.3" + id("me.champeau.jmh") version "0.7.3" `project-convention-java` `project-convention-scala` `project-convention-lombok` @@ -30,13 +30,13 @@ dependencies { testImplementation("org.scalatestplus:junit-4-13_2.13") testImplementation("org.scalatestplus:scalacheck-1-16_2.13") - // jmhImplementation(platform(project(":test-platform"))) - // jmhRuntimeOnly("org.slf4j:slf4j-nop") + jmhImplementation(platform(project(":test-platform"))) + jmhRuntimeOnly("org.slf4j:slf4j-nop") } -// configurations.jmhRuntimeClasspath { -// exclude(module = "slf4j-test") -// } +configurations.jmhRuntimeClasspath { + exclude(module = "slf4j-test") +} tasks.jar { manifest { From dab59d407f81c3b631beab7b0dcb1424c0b74ff3 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Tue, 21 Apr 2026 17:21:37 +0200 Subject: [PATCH 10/11] Pin Lombok version This is necessary to ensure that historical builds continue to work, and to maintain binary reproducibility for historical builds. --- buildSrc/src/main/groovy/project-convention-lombok.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/buildSrc/src/main/groovy/project-convention-lombok.gradle b/buildSrc/src/main/groovy/project-convention-lombok.gradle index c7b35b69a..b5824b6a6 100644 --- a/buildSrc/src/main/groovy/project-convention-lombok.gradle +++ b/buildSrc/src/main/groovy/project-convention-lombok.gradle @@ -2,3 +2,7 @@ plugins { id "java" id "io.freefair.lombok" } + +lombok { + version = "1.18.44" +} From 057ab2a4583556509608bff23cf623250a14c490 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 24 Apr 2026 15:31:57 +0200 Subject: [PATCH 11/11] fixup! Pin Lombok version --- buildSrc/src/main/groovy/project-convention-lombok.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/groovy/project-convention-lombok.gradle b/buildSrc/src/main/groovy/project-convention-lombok.gradle index b5824b6a6..46d7318df 100644 --- a/buildSrc/src/main/groovy/project-convention-lombok.gradle +++ b/buildSrc/src/main/groovy/project-convention-lombok.gradle @@ -4,5 +4,5 @@ plugins { } lombok { - version = "1.18.44" + version = "1.18.24" }