# Gradle Release Notes

We are excited to announce Gradle 8.13 (released 2025-02-25).

This release introduces Daemon JVM auto-provisioning, which automatically downloads the JVM required by the Gradle Daemon to run.

Gradle 8.13 also adds explicit Scala version configuration and JUnit XML timestamps with millisecond precision.

For build authors and plugin developers, this release adds improved access to the settings directory in build scripts, a new artifact transform report, custom test report generation, and the new `distribution-base` plugin.

We would like to thank the following community members for their contributions to this release of Gradle: Adam, Adam, Ahmad Al-Masry, Ahmed Ehab, Aurimas, Baptiste Decroix, Björn Kautler, Borewit, Jorge Matamoros, Lei Zhu, Madalin Valceleanu, Mohammed Thavaf, Patrick Brückner, Philip Wedemann, Roberto Perez Alcolea, Róbert Papp, Semyon Gaschenko, Shi Chen, Stefan M., Steven Schoen, tg-freigmbh, TheGoesen, Tony Robalik, Zongle Wang.

Be sure to check out the public roadmap for insight into what's planned for future releases.

## Table Of Contents

## Upgrade instructions

Switch your build to use Gradle 8.13 by updating the wrapper in your project:

    ./gradlew wrapper --gradle-version=8.13 && ./gradlew wrapper

See the Gradle 8.x upgrade guide to learn about deprecations, breaking changes, and other considerations when upgrading to Gradle 8.13.

For Java, Groovy, Kotlin, and Android compatibility, see the full compatibility notes.

## New features and usability improvements

### Toolchain support

Gradle's toolchain support allows provisioning and selection of JDK versions required for building projects (compiling code, running tests, etc) and running Gradle itself.

#### Daemon toolchain auto-provisioning

Since Gradle 8.8, users can specify a different JVM for building their project than the one used to run Gradle by configuring the Daemon JVM criteria.
Gradle first attempts to locate a compatible Java toolchain from installed versions—this process is known as Daemon JVM auto-detection.

With the introduction of Daemon JVM auto-provisioning, Gradle can now also download a matching Java toolchain when none is found locally.

Running the `updateDaemonJvm` task generates the `gradle/gradle-daemon-jvm.properties` file, which now includes download URLs for the required JDKs:

    toolchainUrl.LINUX.AARCH64=https\://server.com/jdk
    toolchainUrl.LINUX.X86_64=https\://server.com/jdk
    ...
    toolchainVendor=adoptium
    toolchainVersion=17

If no installed JDK matches the specified version or vendor, Gradle automatically downloads the required version:

IntelliJ IDEA support is available starting from version 2025.1 EAP or later and includes the configurable values in the Settings menu:

To enable auto-provisioning, the latest version of the `foojay` plugin (or a custom implementation) is required:

    plugins {
        // Apply the foojay-resolver plugin to allow automatic download of JDKs
        id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
    }

Once the plugin is applied, running the `updateDaemonJvm` task:

    ./gradlew updateDaemonJvm --jvm-version=17 --jvm-vendor=adoptium

Populates `gradle/gradle-daemon-jvm.properties` with the JDK download information:

    toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ff8d269e2495c538cfa04b4b52d22286/redirect
    toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4dfe7aab2abf71db71537e9dca36c154/redirect
    ...
    toolchainVendor=adoptium
    toolchainVersion=17

The resolved platforms and URLs are customizable. For more details, see the Daemon JVM criteria documentation.

### Explicit Scala version declaration in the `scala` extension

The Scala plugin provides support for compiling, testing, and packaging Scala projects.

Starting in this version of Gradle, when applying the `scala-base` or `scala` plugins, you can now explicitly declare the Scala version on the `scala` extension. This allows Gradle to automatically resolve the required Scala toolchain dependencies, eliminating the need for the user to declare them manually. It also removes the need to infer the Scala version from the production runtime classpath, which was error-prone.

Now, you can explicitly set the Scala version in the `scala` extension, and the `scala-library` dependency is no longer required:

    plugins {
        id("scala")
    }

    repositories {
        mavenCentral()
    }

    scala {
        scalaVersion = "2.13.12"
        // OR
        scalaVersion = "3.6.3"
    }

Previously, you had to declare a `scala-library` dependency, like this:

    plugins {
        id("scala")
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        implementation("org.scala-lang:scala-library:2.13.12")
        // OR
        implementation("org.scala-lang:scala3-library_3:3.6.3")
    }

For more details on using the Scala plugin, see the documentation.

### Additional precision in JUnit XML timestamps

Gradle provides built-in support for running JUnit tests and generating detailed reports. The JUnit XML report generated by the `test` task now includes millisecond precision in test event timestamps:

    <testsuite name="ExampleTest" tests="1" failures="0" errors="0" timestamp="2024-02-03T12:34:56.789" time="1.234">
        <testcase name="testExample" classname="com.example.ExampleTest" time="1.234">
        </testcase>
    </testsuite>

This change improves accuracy when analyzing test execution times, particularly in environments where precise timing is critical.

For more details on JUnit test reporting in Gradle, see Testing in JVM Projects.

### Build authoring improvements

Gradle provides rich APIs for plugin authors and build engineers to develop custom build logic.

#### `ProjectLayout` API improvement

The `ProjectLayout` class provides access to directories and files within a project. Starting with this version of Gradle, it can also access the settings directory (the location of the `settings.gradle(.kts)` file).

While the settings directory is not specific to any project, some use cases require resolving file paths relative to it:

    val versionFile = layout.settingsDirectory.file("version.txt")

Previously, accessing the settings directory required using `rootProject.layout.projectDirectory`. This approach involved accessing the `rootProject` object, which is discouraged, and then manually resolving paths to the settings directory:

    val versionFile = rootProject.layout.projectDirectory.file("version.text")

The new capability addresses a common scenario: resolving files shared across all projects in a build, such as linting configurations or `version.txt` files in the root folder.

Refer to `ProjectLayout.getSettingsDirectory()` for additional details.

#### New `artifactTransforms` report task

Artifact Transforms modify or transform the artifacts of dependencies during the dependency resolution process.

A new `artifactTransforms` task is available, providing information about all the registered Artifact Transforms in a project.

The report produced by the task helps build authors identify the transforms registered by build scripts and plugins in their projects. Viewing the list of registered transforms is particularly useful for debugging ambiguous transform failures.

The report includes the following details:

- The fully qualified type name of the action implementing the transform
- Whether the transform is cacheable
- The complete set of input attributes and their values used to select the transform
- The complete set of output attributes and their values produced by the transform

For more information, refer to the ArtifactTransformsReportTask DSL reference.

#### `TestEventReporting` API improvements

Gradle provides an HTML test report to help you understand and resolve test failures. This report is automatically generated when using the `test` task with supported test frameworks, such as `JUnit`.

Plugin authors and platform providers can now leverage the Test Event Reporting APIs to capture test events and generate reports for tests executed outside Gradle's built-in testing infrastructure:

    public abstract class CustomTest extends DefaultTask {

        @Inject
        protected abstract ProjectLayout getLayout();

        @Inject
        protected abstract TestEventReporterFactory getTestEventReporterFactory();

        @TaskAction
        void runTests() {
            try (TestEventReporter test = getTestEventReporterFactory().createTestEventReporter(
                    "custom-test",
                    getLayout().getBuildDirectory().dir("test-results/custom-test").get(),
                    getLayout().getBuildDirectory().dir("reports/tests/custom-test").get()
            )) {
                // Start the test
                test.started(Instant.now());

                // Execute custom test...

                // Report test outcome
                if (testFailureCount > 0) {
                    test.failed(Instant.now());
                } else {
                    test.succeeded(Instant.now());
                }
            }
        }
    }

This integration allows custom test frameworks to generate rich HTML test reports consistent with Gradle's built-in reporting format, enhancing visibility and usability.

You can find additional details and sample code in Test Reporting API.

The following sections highlight two key features of this API.

##### Metadata support

Custom tests can include metadata to provide supplementary information about test execution.

The metadata is displayed in the HTML test report for better visibility:

    test.metadata(Instant.now(),"Parent class:", String.valueOf(result.getTestIdentifier().getParentId().get()));

##### Nesting support

Hierarchical nesting is supported to logically group test suites and individual tests. This ensures detailed and structured reporting, with rich metadata scoped to each level:

    try (GroupTestEventReporter outer = root.reportTestGroup("OuterNestingSuite")) {
        outer.started(Instant.now());
            try (GroupTestEventReporter inner = root.reportTestGroup("InnerNestingSuite")) {
                inner.started(Instant.now());
                try (TestEventReporter test = inner.reportTest("nestedTest", "nestedTest()")) {
                    test.started(Instant.now());
                    test.succeeded(Instant.now());
                }
                inner.succeeded(Instant.now());
        }
        outer.succeeded(Instant.now());
    }

Nested events are reflected in the HTML test reports, providing clear traceability.

#### New `distribution-base` plugin for custom distributions

The Distribution Plugin simplifies the packaging and distribution of project binaries, scripts, and other resources. It creates a distributable archive (ZIP or TAR) containing specified project outputs and provides tasks for assembling and installing the distribution.

Gradle now includes a `distribution-base` plugin, which mirrors the functionality of the Distribution Plugin but does not add a default distribution. Instead, the existing `distribution` plugin acts as a wrapper for the `distribution-base` plugin, adding a default `main` distribution.

The `distribution-base` plugin is particularly useful for plugin developers who want the capabilities of the Distribution Plugin without a `main` distribution:

    plugins {
        id("distribution-base")
    }

    distributions {
        create("custom") {
            distributionBaseName = "customName"
            contents {
                from("src/customLocation")
            }
        }
    }

For more details, see the Distribution Plugin documentation.

## Promoted features

Promoted features are features that were incubating in previous versions of Gradle but are now supported and subject to backward compatibility. See the User Manual section on the "Feature Lifecycle" for more information.

The following are the features that have been promoted in this Gradle release.

### Promoted features in Tooling API

The Tooling API is an interface that allows external tools, such as IDEs, to interact with and control Gradle builds.

The API to asynchronously send data to the client, which includes the `BuildActionExecuter.setStreamedValueListener(StreamedValueListener)` method, the `StreamedValueListener` type, and the `BuildController.send(Object)` method has been promoted to stable.

### Strongly-typed `dependencies` block API

The strongly-typed `dependencies` block API introduced in Gradle 7.6 is now partially stable. Version catalog dependencies remain under review for potential changes.

The `Dependencies` API enables plugin authors to create custom DSL-like `dependencies` blocks, similar to the top-level `dependencies` block in a build script.

## Fixed issues

## Known issues

Known issues are problems that were discovered post-release that are directly related to changes made in this release.

## External contributions

We love getting contributions from the Gradle community. For information on contributing, please see gradle.org/contribute.

## Reporting problems

If you find a problem with this release, please file a bug on GitHub Issues adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the forum.

We hope you will build happiness with Gradle, and we look forward to your feedback via Twitter or on GitHub.