diff --git a/.github/workflows/check-api.yml b/.github/workflows/check-api.yml index 444e56ed8d..a981a0f7eb 100644 --- a/.github/workflows/check-api.yml +++ b/.github/workflows/check-api.yml @@ -14,9 +14,10 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - run: ./gradlew apiCheck --stacktrace diff --git a/.github/workflows/examples-build.yml b/.github/workflows/examples-build.yml index 4648a61a75..ebb7b5adaf 100644 --- a/.github/workflows/examples-build.yml +++ b/.github/workflows/examples-build.yml @@ -33,10 +33,11 @@ jobs: - '${{ matrix.projects }}/**' - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - run: ./gradlew build --no-daemon --stacktrace working-directory: ${{ matrix.projects }} @@ -63,10 +64,11 @@ jobs: - '${{ matrix.projects }}/**' - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - run: ./gradlew dokkaHtml --no-daemon --stacktrace working-directory: ${{ matrix.projects }} @@ -87,10 +89,11 @@ jobs: - 'examples/gradle/dokka-library-publishing-example/**' - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - run: ./gradlew ${{ matrix.tasks }} --no-daemon --stacktrace working-directory: examples/gradle/dokka-library-publishing-example @@ -113,10 +116,11 @@ jobs: - '${{ matrix.dir }}/**' - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - run: ./gradlew ${{ matrix.task }} --no-daemon --stacktrace working-directory: ${{ matrix.dir }} @@ -135,9 +139,8 @@ jobs: working-directory: examples/maven - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 - cache: 'maven' + distribution: "temurin" + java-version: 21 - run: mvn compile dokka:dokka working-directory: examples/maven if: steps.filter.outputs.examples_changed == 'true' diff --git a/.github/workflows/gh-pages-deploy-dev-docs.yml b/.github/workflows/gh-pages-deploy-dev-docs.yml index e1474e5f62..39962d5f9e 100644 --- a/.github/workflows/gh-pages-deploy-dev-docs.yml +++ b/.github/workflows/gh-pages-deploy-dev-docs.yml @@ -20,10 +20,11 @@ jobs: path: dokka - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Get current Dokka version run: echo "DOKKA_VERSION=`./gradlew :properties | grep '^version:.*' | cut -d ' ' -f 2`" >> $GITHUB_ENV diff --git a/.github/workflows/gh-pages-deploy-examples.yml b/.github/workflows/gh-pages-deploy-examples.yml index 1e2a1a5556..4abe3cd815 100644 --- a/.github/workflows/gh-pages-deploy-examples.yml +++ b/.github/workflows/gh-pages-deploy-examples.yml @@ -30,10 +30,11 @@ jobs: - 'examples/gradle/${{ matrix.projects }}/**' - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Build html run: ./gradlew dokkaHtml --no-daemon --stacktrace @@ -65,11 +66,11 @@ jobs: - 'examples/gradle/${{ matrix.projects }}/**' - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 - cache: 'maven' + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Build html run: ./gradlew dokkaHtmlMultiModule --no-daemon --stacktrace diff --git a/.github/workflows/preview-publish-ga.yml b/.github/workflows/preview-publish-ga.yml index 0ea176f310..554186eb1f 100644 --- a/.github/workflows/preview-publish-ga.yml +++ b/.github/workflows/preview-publish-ga.yml @@ -18,10 +18,11 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Document coroutines run: ./gradlew :dokka-integration-tests:gradle:testExternalProjectKotlinxCoroutines --stacktrace "-Dorg.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=500m" @@ -44,10 +45,11 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Document serialization run: ./gradlew :dokka-integration-tests:gradle:testExternalProjectKotlinxSerialization --stacktrace "-Dorg.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=500m" @@ -70,10 +72,11 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Document biojava-core run: ./gradlew :dokka-integration-tests:maven:testExternalProjectBioJava --stacktrace diff --git a/.github/workflows/preview-publish-web-s3.yml b/.github/workflows/preview-publish-web-s3.yml index c0aedf6a7f..e06bcc86a4 100644 --- a/.github/workflows/preview-publish-web-s3.yml +++ b/.github/workflows/preview-publish-web-s3.yml @@ -15,10 +15,11 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Document coroutines run: ./gradlew :dokka-integration-tests:gradle:testExternalProjectKotlinxCoroutines --stacktrace "-Dorg.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=500m" @@ -43,10 +44,11 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Document serialization run: ./gradlew :dokka-integration-tests:gradle:testExternalProjectKotlinxSerialization --stacktrace "-Dorg.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=500m" @@ -71,10 +73,11 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Generate ui-showcase documentation run: ./gradlew :dokka-integration-tests:gradle:testUiShowcaseProject @@ -99,11 +102,11 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 - cache: 'maven' + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Document biojava-core run: ./gradlew :dokka-integration-tests:maven:testExternalProjectBioJava --stacktrace diff --git a/.github/workflows/tests-smoke.yml b/.github/workflows/tests-smoke.yml index 9e1279fa5f..d74dbb1b13 100644 --- a/.github/workflows/tests-smoke.yml +++ b/.github/workflows/tests-smoke.yml @@ -25,10 +25,11 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Run tests run: > diff --git a/.github/workflows/tests-thorough.yml b/.github/workflows/tests-thorough.yml index c5586f73d6..0a66f594ce 100644 --- a/.github/workflows/tests-thorough.yml +++ b/.github/workflows/tests-thorough.yml @@ -23,10 +23,11 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - uses: gradle/actions/setup-gradle@v4 with: + cache-cleanup: always develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - name: Run tests run: > diff --git a/.gitignore b/.gitignore index f252364f0e..262a92b2a5 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,9 @@ hs_err_pid* .gradle build/ +# FIXME Remove when Gradle Daemon JVM can be auto-provisioned. See build-logic/src/main/kotlin/dokkabuild/utils/GradleDaemonJvm.kt +gradle/gradle-daemon-jvm.properties + # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index 619e61d74b..fdfcd0a25e 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -3,13 +3,19 @@ */ import org.gradle.kotlin.dsl.support.expectedKotlinDslPluginsVersion +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile +import kotlin.jvm.optionals.getOrElse plugins { `kotlin-dsl` } kotlin { - jvmToolchain(11) + jvmToolchain { + languageVersion = libs.versions.gradleDaemonJvm.map(String::toInt).map(JavaLanguageVersion::of) + } } dependencies { diff --git a/build-logic/src/main/kotlin/dokkabuild/utils/GradleDaemonJvm.kt b/build-logic/src/main/kotlin/dokkabuild/utils/GradleDaemonJvm.kt new file mode 100644 index 0000000000..bac647aa77 --- /dev/null +++ b/build-logic/src/main/kotlin/dokkabuild/utils/GradleDaemonJvm.kt @@ -0,0 +1,88 @@ +/* + * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +package dokkabuild.utils + +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.gradle.api.logging.Logging +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.TaskProvider +import org.gradle.buildconfiguration.tasks.UpdateDaemonJvm +import org.gradle.jvm.toolchain.JavaLanguageVersion +import org.gradle.jvm.toolchain.JavaToolchainService +import org.gradle.kotlin.dsl.assign +import org.gradle.kotlin.dsl.invoke +import org.gradle.kotlin.dsl.support.serviceOf + +/** + * Lazily configure the version of Java Gradle uses to run the daemon. + * + * To maximise Build Cache hits the same JDK version should be used to run Gradle on all machines. + * + * Gradle has an incubating feature to set the Daemon JVM + * https://docs.gradle.org/current/userguide/gradle_daemon.html#sec:daemon_jvm_criteria, + * but it doesn't auto-download the required JVM. This is annoying, because Gradle will just fail + * until the user manually installs the required JVM. + * + * Instead, this function configures Gradle so it will only set the Daemon JVM if the + * required JDK is installed. + * + * This custom logic can be removed when Gradle supports auto-provisioning of the Daemon JVM + * https://github.com/gradle/gradle/pull/29166 + */ +@Suppress("UnstableApiUsage") +fun configureGradleDaemonJvm( + project: Project, + updateDaemonJvm: TaskProvider, + gradleDaemonJvmVersion: Provider, +) { + require(project.rootProject == project) { + "Gradle Daemon must be configured in the root project, but was configured in ${project.displayName}." + } + + @Suppress("UnstableApiUsage") + updateDaemonJvm { + jvmVersion = gradleDaemonJvmVersion.map(JavaVersion::toVersion) + + val javaToolchains = project.serviceOf() + val isGradleDaemonJvmVersionInstalled = gradleDaemonJvmVersion.isInstalled(javaToolchains) + inputs.property("isGradleDaemonJvmVersionInstalled", isGradleDaemonJvmVersionInstalled) + onlyIf("Valid JVM is installed") { isGradleDaemonJvmVersionInstalled.get() } + } + + // Depend on some common tasks, so the Daemon JVM properties file will be generated automatically. + project.defaultTasks(updateDaemonJvm.name) + project.tasks + .matching { it.name in setOf("prepareKotlinIdeaImport", "prepareKotlinBuildScriptModel", "assemble") } + .configureEach { + dependsOn(updateDaemonJvm) + } +} + +/** + * Determine if the [JavaToolchainService] can detect, or automatically install, + * a toolchain for this [JavaVersion]. + */ +private fun Provider.isInstalled( + javaToolchains: JavaToolchainService +): Provider { + // Must catch exceptions because Toolchains don't properly support the Provider API. + // See https://github.com/gradle/gradle/issues/29758 + return map { version -> + val launcher = try { + javaToolchains + .launcherFor { languageVersion = JavaLanguageVersion.of(version.majorVersion) } + .orNull + } catch (ex: Exception) { + null + } + if (launcher == null) { + logger.lifecycle("i: Could not find JDK $version to run Gradle Daemon. Build performance may be impacted.") + } + launcher == null + } +} + +private val logger = Logging.getLogger("dokkabuild.GradleDaemonJvm") diff --git a/build-settings-logic/build.gradle.kts b/build-settings-logic/build.gradle.kts index 78114e59b1..c682db1792 100644 --- a/build-settings-logic/build.gradle.kts +++ b/build-settings-logic/build.gradle.kts @@ -9,7 +9,9 @@ plugins { description = "Conventions for use in settings.gradle.kts scripts" kotlin { - jvmToolchain(11) + jvmToolchain { + languageVersion = libs.versions.gradleDaemonJvm.map(String::toInt).map(JavaLanguageVersion::of) + } } dependencies { diff --git a/build.gradle.kts b/build.gradle.kts index e4c294a282..c67bbfd6dd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,7 @@ /* * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ +import dokkabuild.utils.configureGradleDaemonJvm plugins { id("dokkabuild.base") @@ -123,3 +124,9 @@ idea { ) } } + +configureGradleDaemonJvm( + project = project, + updateDaemonJvm = tasks.updateDaemonJvm, + gradleDaemonJvmVersion = libs.versions.gradleDaemonJvm.map(JavaVersion::toVersion), +) diff --git a/gradle/daemon-jvm.properties b/gradle/daemon-jvm.properties new file mode 100644 index 0000000000..63e5bbdf48 --- /dev/null +++ b/gradle/daemon-jvm.properties @@ -0,0 +1,2 @@ +#This file is generated by updateDaemonJvm +toolchainVersion=21 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b5608a6b88..22382844b4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -63,6 +63,9 @@ junit = "5.9.3" kotest = "5.6.2" eclipse-jgit = "5.13.3.202401111512-r" # jgit 6.X requires Java 11 to run +# JDK used to run Gradle Daemon. (Should be the same as jvmCompiler, but could be higher or lower.) +gradleDaemonJvm = "21" + [libraries] #### Kotlin Libs #### diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3..2c3521197d 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ