With Develocity 2024.1, this extension has been deprecated in favor of the new Develocity Maven extension. With Develocity 2024.3, there will be no further releases of this extension. It’s recommended to upgrade to the Develocity Maven extension as soon as possible. Please refer to the Migrating to the Develocity extension section for details. |
The Gradle Enterprise Maven extension improves your development workflow and your productivity, when developing and maintaining Apache Maven™ builds. The extension enables Build Scan insights, Build Cache acceleration, Predictive Test Selection, and Test Distribution.
Getting set up
Automated setup
(Maven extension 1.19+)
Execute the init
goal to quickly set up the Develocity Maven extension on a Maven project:
mvn com.gradle:gradle-enterprise-maven-extension:1.22.2:init -Dgradle.enterprise.url=https://develocity.mycompany.com
See here for more information.
Manual setup
Apply the Develocity Maven extension to your build by adding the following configuration block to a new or existing .mvn/extensions.xml
file in your Maven project. Maven automatically downloads the extension from Maven Central when you run your build.
.mvn/extensions.xml
<extensions>
<extension>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<version>1.22.2</version>
</extension>
</extensions>
You can also add the extension jar into the lib/ext
folder of your Maven installation. This is useful if you are packaging a custom Maven installation for your organization and you want Develocity to be available to all your projects out of the box.
The extension is configured through one or more gradle-enterprise.xml
files and the pluginManagement
sections of your pom.xml
files. Similarly to the extensions.xml
file, the gradle-enterprise.xml
file can be placed in your Maven project’s .mvn
directory. Unless you intend to publish a Build Scan to scans.gradle.com, the minimum configuration required is the Develocity server URL.
.mvn/gradle-enterprise.xml
<gradleEnterprise>
<server>
<url>https://develocity.mycompany.com</url>
</server>
</gradleEnterprise>
Other mechanisms for configuring Develocity are available, including alternate file locations for gradle-enterprise.xml
and programmatic configuration with a custom Maven extension. For the full reference of the extension’s configuration, see the configuration reference. All available configuration options will be introduced over the coming sections.
Since version 1.2, the Develocity Maven extension captures an identifier used to uniquely represent a given workspace.
|
Using Build Scans
Build Scans are a record of what happened during a build, captured and visualized by Develocity.
Build Scans are an important tool for developing and maintaining Maven builds. They provide insights into exactly what your builds are doing, helping you identify problems with the build environment, performance, and more. They can also help you understand and improve the build more generally, and make collaborating with others easier.
Develocity is a commercial product for companies that can be hosted on their own systems and ships with a Build Scan server and a Build Cache backend implementation. scans.gradle.com is a Build Scan server available for free, hosted by Gradle Inc.
There are two aspects to working with Build Scans:
-
Data collection
-
Publishing
Enabling publication of Build Scans
Enabling publication of Build Scans depends on whether you are publishing to a Develocity instance or scans.gradle.com. In the case of Develocity, you need to specify the server’s location. In the case of scans.gradle.com, you need to accept the terms of use.
Set the location of your Develocity instance
When you publish Build Scans to a Develocity instance, you must configure the location of the Develocity server.
gradleEnterprise.setServer("https://develocity.mycompany.com");
$ mvn package -Dgradle.enterprise.url=https://develocity.mycompany.com
<gradleEnterprise>
<server>
<url>https://develocity.mycompany.com</url>
</server>
</gradleEnterprise>
The precise URL you need depends on the hostname that your Develocity instance has been configured with. If in doubt, be sure to ask whomever manages that instance.
You may encounter a warning about an untrusted certificate when connecting to Develocity over HTTPS. The ideal solution is for someone to add a valid SSL certificate to the Develocity instance, but we recognise that you may not be able to do that. In this case, set the allowUntrustedServer
option to true
:
gradleEnterprise.setAllowUntrustedServer(true);
$ mvn package -Dgradle.enterprise.allowUntrustedServer=true
<gradleEnterprise>
<server>
<allowUntrusted>true</allowUntrusted>
</server>
</gradleEnterprise>
This is a convenient workaround during the initial evaluation, but it is a serious security issue and should not be used in production. |
Accept the scans.gradle.com terms of use
In order to publish to scans.gradle.com, you need to accept the terms of use.
buildScan.setTermsOfServiceUrl("https://gradle.com/help/legal-terms-of-use");
buildScan.setTermsOfServiceAgree("true");
$ mvn package -Dgradle.scan.termsOfService.url=https://gradle.com/help/legal-terms-of-use -Dgradle.scan.termsOfService.accept=true
<gradleEnterprise>
<buildScan>
<termsOfService>
<url>https://gradle.com/help/legal-terms-of-use</url>
<accept>true</accept>
</termsOfService>
</buildScan>
</gradleEnterprise>
Be sure to check the terms of use at the URL shown in the above fragment.
Once you have accepted the terms of use, you can start publishing Build Scans to scans.gradle.com.
If you don’t accept the terms of use, as explained above, you will be prompted to agree to the terms of use on the command line, before any attempt of publishing a Build Scan. This can be useful if you share your |
Integrating your CI tool
Jenkins
The Gradle Jenkins plugin prominently displays links to the Build Scan for any Gradle or Maven build that produce Build Scans, which makes it convenient to access the Build Scans. See the following screenshot for an example:
Besides that, the plugin allows you to instrument all CI jobs and to publish a Build Scan without modifying the underlying projects. This eases the adoption of Build Scans within the company and allows configuring the Develocity Gradle plugin or Develocity Maven extension in a central place. For more information please read the documentation here.
TeamCity
The TeamCity Build Scan plugin prominently displays links to the Build Scan for any Gradle or Maven build that produce Build Scans, which makes it convenient to access the Build Scans. See the following screenshot for an example:
Besides that, the plugin allows you to instrument all CI jobs and to publish a Build Scan without modifying the underlying projects. This eases the adoption of Build Scans within the company and allows configuring the Develocity Gradle plugin or Develocity Maven extension in a central place. For more information please read the documentation here.
Bamboo
The Develocity Bamboo plugin prominently displays links to the Build Scan for any Gradle or Maven build that produce Build Scans, which makes it convenient to access the Build Scans. See the following screenshot for an example:
Besides that, the plugin allows you to instrument all CI jobs and to publish a Build Scan without modifying the underlying projects. This eases the adoption of Build Scans within the company and allows configuring the Develocity Gradle plugin or Develocity Maven extension in a central place. For more information please read the documentation here.
GitLab templates
The Develocity GitLab templates allow you to instrument CI jobs and to publish a Build Scan without modifying the project’s build scripts. This eases the adoption of Build Scans within the company and allows configuring the Develocity Gradle plugin or Develocity Maven extension at the CI level. For more information please read the documentation here.
Controlling when Build Scans are published
Once you’ve gone through the initial setup of the previous section, you are ready to start publishing Build Scans. But when should you publish them? Every time you run a build? Only when the build fails? It’s up to you. The Develocity Maven extension has several options that allow you to use whatever approach works best.
Publishing every build run
This is the default. There are many advantages to publishing Build Scans regularly, such as being able to track the behavior and performance of a build over time. It makes no sense relying on ad-hoc publishing of scans in such a situation as it’s easy to forget on the command line. Should you decide to explicitly enforce this default option, you can do this as follows:
buildScan.publishAlways();
<gradleEnterprise>
<buildScan>
<publish>ALWAYS</publish>
</buildScan>
</gradleEnterprise>
This approach means that you get a Build Scan for every successful and failed build that runs, including from your continuous integration infrastructure and your developers.
If you want to deactivate Build Scans for a particular build, you can pass the -Dscan=false
system property to Maven.
Publishing on demand
We imagine that when you first start experimenting with Build Scans, you won’t want to publish them all the time until you become familiar with the implications. Even then, you may have good reason not to go all-in and automate the process. That’s where one-off Build Scans come in.
If you only want to publish Build Scans when explicitly requested, use the following option:
buildScan.publishOnDemand();
scan
system property to Maven
$ mvn clean verify -Dscan
<gradleEnterprise>
<buildScan>
<publish>ON_DEMAND</publish>
</buildScan>
</gradleEnterprise>
When using Develocity Maven extension 1.16 or above, you can also publish a Build Scan for the most recently run build by invoking the build-scan-publish-previous
goal.
$ mvn clean verify --offline
$ mvn gradle-enterprise:build-scan-publish-previous
Publishing based on criteria
Many of you will want a bit more control over exactly when Build Scans are published without resorting to using -Dscan
each time. Perhaps you only want to publish Build Scans when the build fails, or if the build is running on your continuous integration infrastructure. Such scenarios are covered by the options in the following table.
buildScan.publishAlwaysIf(true); // Publish a build scan if the given condition is true
, regardless of whether the build succeeds or fails
buildScan.publishOnFailure(); // Publish a build scan only when the build fails
buildScan.publishOnFailureIf(true); // Publish a build scan only if the condition is true
and the build fails
<gradleEnterprise>
<buildScan>
<publish>ON_FAILURE</publish>
</buildScan>
</gradleEnterprise>
Giving a more concrete example, let’s say you only want to publish Build Scans from your CI system, which is identified by having a CI
environment variable. This configuration will do the trick:
buildScan.publishAlwaysIf(System.getenv("CI") != null);
<gradleEnterprise>
<buildScan>
<publish>#{env['CI'] == null ? 'ON_DEMAND' : 'ALWAYS'}</publish>
</buildScan>
</gradleEnterprise>
Configuring background uploading
(Maven extension 1.5+, Develocity 2020.2+)
By default, Build Scans are uploaded in the background after the build has finished. This allows the build to finish sooner, but can be problematic in build environments (e.g. ephemeral CI agents) that terminate as soon as the build is finished, as the upload may be terminated before it completes. Background uploading should be disabled for such environments.
Prior to version 1.5 of the Maven extension, Build Scans are always uploaded before the build finishes. |
Background Build Scan upload can be disabled programmatically, via a system property, or via the gradle-enterprise.xml
configuration file.
buildScan.setUploadInBackground(false);
gradle.scan.uploadInBackground
system property to Maven
$ mvn clean verify -Dgradle.scan.uploadInBackground=false
<gradleEnterprise>
<buildScan>
<backgroundBuildScanUpload>false</backgroundBuildScanUpload>
</buildScan>
</gradleEnterprise>
It may be desirable to conditionally set the value based on the environment.
buildScan.setUploadInBackground(System.getenv("CI") == null);
gradle.scan.uploadInBackground
system property only on the CI build configuration
$ mvn clean verify -Dgradle.scan.uploadInBackground=false
<gradleEnterprise>
<buildScan>
<backgroundBuildScanUpload>#{env['CI'] == null}</backgroundBuildScanUpload>
</buildScan>
</gradleEnterprise>
Configuring project identifier
(Maven extension 1.19+, Develocity 2023.3+)
Detailed information regarding project-level access control can be found here.
Versions before 1.19 of this extension do not allow specifying project identifier |
Project identifier can be set programmatically, via a system property, or via the gradle-enterprise.xml
configuration file.
gradleEnterprise.setProjectId("myProject");
gradle.enterprise.projectId
system property to Maven
$ mvn clean verify -Dgradle.enterprise.projectId=myProject
<gradleEnterprise>
<projectId>myProject</projectId>
</gradleEnterprise>
Authenticating with Develocity
(Maven extension 1.3+, Develocity 2019.4+)
Develocity installations may be configured to require Build Scan publishing to be authenticated. Additionally, installations may be configured to only allow certain users to publish Build Scans.
Develocity access keys should be treated with the same secrecy as passwords. They are used to authorize access to Develocity from a build. |
Automated access key provisioning
The easiest way to configure a build environment to authenticate with Develocity is to use the following goal:
$ mvn gradle-enterprise:provision-access-key
When executed, it opens your web browser and asks to confirm provisioning of a new access key. You will be asked to sign in to Develocity in your browser first if you are not already signed in.
When confirmed, a new access key will be generated and stored in the .develocity/keys.properties
file within the Maven user home directory (~/.m2
by default).
Any existing access key for the same server will be replaced in the file, but will not be revoked at the server for use elsewhere. To revoke old access keys, sign in to Develocity and access “My settings” via the user menu at the top right of the page.
If your browser cannot be opened automatically at the correct page, you will be asked to manually open a link provided in the build console. |
Manual access key configuration
Access keys can also be configured manually for an environment, when automated provisioning is not suitable.
Creating access keys
To create a new access key, sign in to Develocity and access “My settings” via the user menu at the top right of the page. From there, use the “Access keys” section to generate an access key.
The access key value should then be copied and configured in your build environment via file or via environment variable.
Via file
Develocity access keys are stored inside the Maven user home directory (~/.m2
by default), at .develocity/keys.properties
, in a Java properties file. The property name refers to the host name of the server, and the value is the access key.
develocity.mycompany.com=7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq
The file may contain multiple entries. The first entry for a given host value will be used.
Via environment variable
The access key may also be specified via the GRADLE_ENTERPRISE_ACCESS_KEY
environment variable. This is typically more suitable for CI build environments.
The environment variable value format is «server host name»=«access key»
.
$ export GRADLE_ENTERPRISE_ACCESS_KEY=develocity.mycompany.com=7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq && \
mvn package
The server host name is specified in order to prevent the access key being transmitted to a different server than intended. In the rare case that you require access keys for multiple servers, you can specify multiple entries separated by semicolons (requires Maven extension 1.9+, Develocity 2021.1+).
$ export GRADLE_ENTERPRISE_ACCESS_KEY=develocity1.mycompany.com=7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq;develocity2.mycompany.com=9y4agfiubqqjea4vonghohvuyra5bnvszop4asbqee3m3sm67w5k && \
mvn package
Via configuration
(Maven extension 1.11+)
The accessKey
can also be set via the extension’s configuration.
gradleEnterprise.setServer("https://develocity.mycompany.com");
gradleEnterprise.setAccessKey("7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq");
<gradleEnterprise>
<server>
<url>https://develocity.mycompany.com</url>
<accessKey>7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq</accessKey>
</server>
</gradleEnterprise>
An access key configured for the server this way will take precedence over an access key set via the environment variable or access key file.
Short-lived access tokens
Develocity access keys are long-lived, creating risks if they are leaked. To avoid this, users can use short-lived access tokens to authenticate with Develocity. Access tokens can be used wherever an access key would be used. Access tokens are only valid for the Develocity instance that created them.
Develocity server version 2024.1+ supports access tokens. |
Changing a Develocity instance’s hostname will cause all existing access tokens to become invalid. |
To create an access token:
-
Get an access key or access token for the user you wish to create a token for.
-
Decide which permissions the new access token should have.
-
If project-level access control is enabled, decide which projects the new access token should be able to access.
-
Decide how long the new access token should live.
-
Make a POST request to
/api/auth/token
, optionally with the following parameters. The response will be the access token.-
A
permissions=
query parameter with the config values of each permission you wish to grant. By default, all permissions for the credential used to authenticate the token request are granted to the created token. -
If project-level access control is enabled, a
projectIds=
query parameter with the ID of each project you wish to grant access to. By default, all projects for the credential used to authenticate the token request are granted to the created token. -
An
expiresInHours=
query parameter with the token’s intended lifetime in hours, with a maximum of 24. The default is two hours, or the remaining lifetime of the credential used to authenticate the request, whichever is smaller.
-
The requested permissions and project ids can be specified as comma-seperated lists or repeated parameters. For example, ?projectIds=a,b&projectIds=c
is valid and will request projects a
, b
, and c
.
If project-level access control is not enabled, all access tokens will be granted the “Access all data without an associated project” permission even if it is not explicitly requested. |
If the user creating the token does not have one of the requested permissions or projects, Develocity will respond with a 403 Forbidden error. If an access token is used to authenticate the creation request, its permissions and projects will be used for this check instead of the user’s. The request will also error if the requested lifetime would cause the new access token to expire after the one used to authenticate the request. Together, this means you cannot create an access token with more access or a later expiration than the credentials used to authenticate the request.
See the API documentation for more details on the /api/auth/token endpoint. |
Here is an example using CURL to create an access token:
$ curl -X POST https://ge.mycompany.com/api/auth/token?permissions=publishScan,writeCache,accessDataWithoutAssociatedProject&projectIds=project-a,project-b&expiresInHours=1 \
-H "Authorization: Bearer 7asejatf24zun43yshqufp7qi4ovcefxpykbwzqbzilcpwzb52ja"
eyJraWQiOiJ0ZXN0LWtleSIsImFsZyI6IlJTMjU2IiwidHlwIjoiSldUIn0.eyJpc19hbm9ueW1vdXMiOmZhbHNlLCJwZXJtaXNzaW9ucyI6WyJSRUFEX1ZFUlNJT04iLCJFWFBPUlRfREFUQSIsIkFDQ0VTU19EQVRBX1dJVEhPVVRfQVNTT0NJQVRFRF9QUk9KRUNUIl0sInByb2plY3RzIjp7ImEiOjEsImIiOjJ9LCJ1c2VyX2lkIjoic29tZS1pZCIsInVzZXJuYW1lIjoidGVzdCIsImZpcnN0X25hbWUiOiJhIiwibGFzdF9uYW1lIjoidXNlciIsImVtYWlsIjoiYkBncmFkbGUuY29tIiwic3ViIjoidGVzdCIsImV4cCI6NzIwMCwibmJmIjowLCJpYXQiOjAsImF1ZCI6ImV4YW1wbGUuZ3JhZGxlLmNvbSIsImlzcyI6ImV4YW1wbGUuZ3JhZGxlLmNvbSIsInRva2VuX3R5cGUiOiJhY2Nlc3NfdG9rZW4ifQ.H1_NEG1xuleP-WIAY_uvSmdd2o7i_-Ko3qhlo04zvCgrElJe7_F5jNuqsyDfnb5hvKlOe5UKG_7QPTgY9-3pFQ
The resulting token would have the following permissions:
-
“Publish Build Scans”
-
“Read and write Build Cache data”
-
“Access all data without an associated project”
And it would have access to these projects:
-
“project-a”
-
“project-b”
The token would only be usable for one hour.
Capturing goal input files
(Maven extension v1.1+)
Build Scans capture hashes of goal inputs, to enable identifying changes to inputs when comparing builds, among other features. The overall hash value of each goal input property enables identifying which properties changed for a goal execution (e.g. the source or the classpath for Java compilation) when comparing two builds. Since Maven extension 1.21, the paths and content hashes of individual input files of each property are also captured by default. For older versions, this can be enabled on an opt-in basis. They allow identifying which individual files changed for a goal execution when comparing two builds.
When to enable/disable
Capturing goal input files increases the amount of data transmitted to the Build Scan server at the end of the build. If the network connection to the Build Scan server is poor, it may increase the time required to transmit. Additionally, it may also increase the data storage requirements for the Build Scan server. In such cases, capturing of goal input files can be disabled.
However, if you are using Develocity and utilising its Build Cache to accelerate your builds, it is strongly recommended to enable it as identifying which files have changed between builds with build comparison is extremely effective for diagnosing unexpected Build Cache misses.
If you are using Develocity for Predictive Test Selection enabling capture of goal input files is a prerequisite.
How to enable/disable
File fingerprint capture can be enabled/disabled programmatically, via a system property, or via the develocity.xml
configuration file.
// For extension < 1.11
buildScan.setCaptureGoalInputFiles(true);
// For extension >= 1.11
buildScan.getCapture().setGoalInputFiles(true);
develocity.scan.captureFileFingerprints
system property to Maven
$ mvn clean verify -Dgradle.scan.captureGoalInputFiles=true
<gradleEnterprise>
<buildScan>
<captureGoalInputFiles>true</captureGoalInputFiles> <!-- For extension < 1.11-->
<capture> <!-- For extension in [1.11,1.21[ -->
<goalInputFiles>true</goalInputFiles>
</capture>
</buildScan>
</gradleEnterprise>
Capturing build and test outputs
(Maven extension v1.11+)
By default, outputs generated during the build are captured and displayed in Build Scans.
Note that when disabling test output capturing, test failures will still be captured.
When to disable
You may want to skip capturing build or test outputs for security/privacy reasons (i.e., some outputs may leak sensitive data), or performance/storage reasons (i.e., some goals/tests may produce a lot of outputs that are irrelevant for your usage of Build Scans).
How to disable
Output capture can be disabled programmatically, via a system property, or via the gradle-enterprise.xml
configuration file.
buildScan.getCapture().setBuildLogging(false);
buildScan.getCapture().setTestLogging(false);
gradle.scan.captureBuildLogging
and gradle.scan.captureTestLogging
system properties to Maven
$ mvn clean verify -Dgradle.scan.captureBuildLogging=false -Dgradle.scan.captureTestLogging=false
<gradleEnterprise>
<buildScan>
<capture>
<buildLogging>false</buildLogging>
<testLogging>false</testLogging>
</capture>
</buildScan>
</gradleEnterprise>
Capturing resource usage
(Maven extension 1.22+)
Build Scans capture information on key resources of the machine executing the build. This includes CPU load, memory, disk usage, network activity, and the names of the most CPU-intensive processes. These insights can help analyze poor build performance, whether due to the build needing too many resources or factors external to the build. It can also help understand if the machine is underutilized and if it could do more work.
By default, resource usage is captured and displayed in Build Scans.
When to disable
You may want to skip capturing resource usage for security/privacy reasons. Note that the names of processes external to the build (i.e. not the build process nor its descendants) can be obfuscated.
How to disable
Resource usage capture can be enabled/disabled programmatically, via a system property, or via the develocity.xml
configuration file.
buildScan.getCapture().setResourceUsage(false);
develocity.scan.captureResourceUsage
system property to Maven
$ mvn clean verify -Ddevelocity.scan.captureResourceUsage=false
<gradleEnterprise>
<buildScan>
<capture>
<resourceUsage>false</resourceUsage>
</capture>
</buildScan>
</gradleEnterprise>
Extending Build Scans
You can easily include extra custom information in your Build Scans in the form of tags, links and values. This is a very powerful mechanism for capturing and sharing information that is important to your build and development process.
This information can be anything you like. You can tag all builds run by your continuous integration tool with a CI
tag. You can capture the name of the environment that the build published to as a value. You can link to the source revision for the build in an online tool such as GitHub. The possibilities are endless.
You can see how the custom data appears in figures 2 and 3:
Develocity allows listing and searching across all of the Build Scans in the system. You can find and filter Build Scans by tags and custom values, in addition to project name, outcome and other properties. In figure 4, for example, we are filtering for all Maven Build Scans that have the tag "CI" and a git branch name of "release":
Adding tags
Tags are typically used to indicate the type or class of a build, or a key characteristic. They are prominent in the user interface and quickly inform a user about the nature of a build. A build can have zero or more tags.
buildScan.tag("my tag");
scan.tag.<tag>
system property to Maven
$ mvn package -Dscan.tag.CI
<gradleEnterprise>
<buildScan>
<tags>
<tag>my tag</tag>
</tags>
</buildScan>
</gradleEnterprise>
pom.xml
<project>
<!-- other build configuration -->
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<buildScan>
<tags>
<tag>my tag</tag>
</tags>
</buildScan>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</project>
Prefer the programmatic access. If specified in parent POM, tags will be applied to all projects inheriting from it. |
Note that the order in which you declare the tags doesn’t affect the Build Scan view. They are displayed in alphabetical order, with any all-caps labels displayed before the rest.
You can see the effect of a custom tag in figure 2.
The Develocity Maven extension imposes limits on captured tags:
|
Adding links
Builds rarely live in isolation. Where does the project source live? Is there online documentation for the project? Where can you find the project’s issue tracker? If these exist and have a URL, you can add them to the Build Scan.
buildScan.link("my link", "http://my-site.com");
scan.link.<name>=<URL>
system property to Maven
$ mvn package -Dscan.link.VCS=https://github.com/myorg/my-super-project/tree/my-new-feature
<gradleEnterprise>
<buildScan>
<links>
<link>
<name>my link</name>
<url>http://my-site.com</url>
</link>
</links>
</buildScan>
</gradleEnterprise>
pom.xml
<project>
...
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<buildScan>
<links>
<link>
<name>my link</name>
<url>http://my-site.com</url>
</link>
</links>
</buildScan>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</project>
Prefer the programmatic access. If specified in parent POM, links will be applied to all projects inheriting from it. |
Links can also be added in your project POM.
The <name> is simply a string identifier that you choose and that means something to you.
You can see the effect of a custom link in figure 2, which shows how a label for a given VCS (here GitHub) becomes a hyperlink that anyone viewing the Build Scan can follow.
The Develocity Maven extension imposes limits on captured links:
|
Adding custom values
Some information just isn’t useful without context. What does "1G" mean? You might guess that it represents 1 gigabyte, but of what? It’s only when you attach the label "Max heap size for build" that it makes sense. The same applies to git commit IDs, for example, which could be interpreted as some other checksum without a suitable label.
Custom values are designed for these cases that require context. They’re standard key-value pairs, in which the key is a string label of your choosing and the values are also strings, often evaluated from the build environment.
buildScan.value("my name", "my value");
scan.value.<name>=<value>
system property to Maven
$ mvn package -Dscan.value.CIBuildType=QA_Build
<gradleEnterprise>
<buildScan>
<values>
<value>
<name>my name</name>
<value>my value</value>
</value>
</values>
</buildScan>
</gradleEnterprise>
pom.xml
<project>
...
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<buildScan>
<values>
<value>
<name>Build Number</name>
<value>${project.buildNumber}</value>
</value>
</values>
</buildScan>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</project>
Prefer the programmatic access. If specified in parent POM, custom values will be applied to all projects inheriting from it. |
As with tags, you can filter Build Scans by custom values in Develocity.
The Develocity Maven extension imposes limits on captured custom values:
|
Callbacks
The Build Scan API allows to programmatically interact with the Build Scan configuration of the Develocity Maven extension. Please see the Javadoc for the complete API documentation.
Executing operations at the end of the build
(Maven extension v1.2+)
What if you want to execute some code based on data that is only available late in the build? For example, you might want to label a build as "built-from-clean" if the clean
goal was run. But you don’t know if that’s the case until the goal execution plan is ready.
The Maven extension provides a buildFinished()
hook that you can use for these situations. It defers attaching custom data until the build has finished running. As an example, imagine you want to report how much disk space was taken up by the output directory. The build doesn’t know this until it’s finished, so the solution is to calculate the disk space and attach it to a custom value in the buildFinished()
hook:
File outputDir = new File(mavenSession.getCurrentProject().getBuild().getOutputDirectory());
buildScan.buildFinished(buildResult -> {
long size = org.apache.commons.io.FileUtils.sizeOfDirectory(outputDir);
buildScan.value("Disk usage (target dir)", String.valueOf(size));
});
The buildFinished()
action has access to a BuildResult
instance that you can use to determine whether the build failed or not, like so:
buildScan.buildFinished(buildResult -> {
buildResult.getFailures().forEach(failure ->
buildScan.value("Failed with", failure.getMessage())
);
});
Executing operations when a Build Scan is published
(Maven extension v1.2+)
You might want to perform a custom operation when a Build Scan is published, like notifying an internal tool of your company. To do this , you can use the BuildScanApi#buildScanPublished()
method:
buildScan.buildScanPublished(it -> {
try {
Files.write(Paths.get("buildScans.txt"), it.getBuildScanId().getBytes(), StandardOpenOption.APPEND);
} catch (IOException e) {
throw new UncheckedIOException("Failed to write to journal", e);
}
});
Executing expensive operations
(Maven extension v1.2+)
Some data that you may wish to add to your Build Scan can be expensive to capture. For example, capturing the Git commit ID may require executing the git
command as an external process, which is expensive. To do this without slowing your build down, you can use the BuildScanApi#background()
method:
buildScan.background(api -> {
try {
File projectDir = mavenSession.getCurrentProject().getBasedir();
String commitId = org.eclipse.jgit.lib.ObjectId.toString(
org.eclipse.jgit.api.Git.open(projectDir)
.getRepository()
.resolve("HEAD")
);
api.value("Git Commit ID", commitId);
} catch (IOException e) {
throw new UncheckedIOException("Failed to read Git Commit ID", e);
}
});
This method takes a function that will be executed on a separate thread, which allows Maven to continue without waiting for the expensive work to complete.
All background work will be completed before finishing the build and publishing the Build Scan.
Any errors that are thrown by the background action will be logged and captured in the Build Scan.
See the BuildScanApi#background() API reference for more information.
Executing operations only once
(Maven extension v1.2.3+)
You may want to ensure that a given operation is only executed once for the whole execution of a multi-project Maven build.
The Maven extension provides an executeOnce()
hook that you can use for these situations. It must be provided with an identifier, and can call any service provided by the API. The identifier is used to guarantee that the provided action will be executed at most once.
// This will be executed once
buildScan.executeOnce("capture custom data", api -> api.tag("my custom tag"));
// This will not be executed and will silently be ignored
buildScan.executeOnce("capture custom data", api -> api.tag("my other custom tag"));
// This will be executed once
buildScan.executeOnce("publish to journal", api -> api.buildScanPublished(journalServer::add));
Obfuscating identifying data
(Maven extension v1.3.1+)
Build Scans capture certain identifying information such as the operating system username, hostname, network addresses, and CPU-intensive process names. You may choose to obfuscate this data so that it is not decipherable in Build Scans when viewed. To do this, you can use the BuildScanApi#obfuscation()
method.
With Maven extension v1.6.3+, you can register obfuscation values on the gradle-enterprise.xml. These will always be applied, even in case of very early build failures, that would prevent programmatic configuration via the BuildScan API. If the BuildScan API gets eventually called, obfuscation functions registered with it will have precedence over the values defined via XML.
The following examples show registering obfuscation functions for the different identifying data.
buildScan.obfuscation(obfuscation -> obfuscation.username(s -> s.chars()
.mapToObj(c -> String.valueOf(Character.getNumericValue(c)))
.collect(java.util.stream.Collectors.joining())
));
<gradleEnterprise>
<buildScan>
<obfuscation>
<!-- Use a redacted value. -->
<username>obfuscated</username>
</obfuscation>
</buildScan>
</gradleEnterprise>
---
<gradleEnterprise>
<buildScan>
<obfuscation>
<!-- Use Spring Expression Language. The 'username' variable can be used to get access to the username that would be captured. -->
<username>{username.substring(0,1)}</username>
</obfuscation>
</buildScan>
</gradleEnterprise>
---
<gradleEnterprise>
<buildScan>
<obfuscation>
<!-- Use Spring Expression Language. The 'sha512' method can be used. -->
<username>{sha512(username)}</username>
</obfuscation>
</buildScan>
</gradleEnterprise>
buildScan.obfuscation(obfuscation -> obfuscation.hostname(s -> s.chars()
.mapToObj(c -> String.valueOf(Character.getNumericValue(c)))
.collect(java.util.stream.Collectors.joining())
));
<gradleEnterprise>
<buildScan>
<obfuscation>
<!-- Use a redacted value. -->
<hostname>obfuscated</hostname>
</obfuscation>
</buildScan>
</gradleEnterprise>
---
<gradleEnterprise>
<buildScan>
<obfuscation>
<!-- Use Spring Expression Language. -->
<hostname>#{isTrue(env['CI']) ? 'CI agent' : 'Local agent'}</hostname>
</obfuscation>
</buildScan>
</gradleEnterprise>
buildScan.obfuscation(obfuscation -> obfuscation.ipAddresses(addresses -> addresses.stream()
.map(address -> "0.0.0.0")
.collect(java.util.stream.Collectors.toList())
));
<gradleEnterprise>
<buildScan>
<obfuscation>
<!-- Use a redacted value.-->
<ipAddresses>{{'0.0.0.0'}}</ipAddresses>
</obfuscation>
</buildScan>
</gradleEnterprise>
---
<gradleEnterprise>
<buildScan>
<obfuscation>
<!-- Use Spring Expression Language. The 'sha512' method can be used. The 'ipAddresses' variable can be used to get access to the list of IP addresses that would be captured. -->
<ipAddresses>{sha512(ipAddresses)}</ipAddresses>
</obfuscation>
</buildScan>
</gradleEnterprise>
buildScan.obfuscation(obfuscation -> obfuscation.externalProcessName(s -> s.chars()
.mapToObj(c -> String.valueOf(Character.getNumericValue(c)))
.collect(java.util.stream.Collectors.joining())
));
<gradleEnterprise>
<buildScan>
<obfuscation>
<!-- Use a redacted value.-->
<externalProcessName>obfuscated</externalProcessName>
</obfuscation>
</buildScan>
</gradleEnterprise>
See the BuildScanApi#obfuscation() API reference for more information.
Troubleshooting
Failed background Build Scan uploads
When using background Build Scan uploading (default behaviour since Maven extension version 1.5, see this section for configuration options) upload failures are not visible in the build logging due to occurring in a background process after the build has finished. Instead, errors are logged to a file located at ~/.m2/.develocity/build-scan-data/upload-failure.log
. If this additional information does not help to resolve the failure, please contact technical support and include the contents of this log file.
If the background upload process fails to start, a warning is shown in the build console and uploading is performed in the build process. If this occurs, please contact technical support with the log files located at ~/.m2/.develocity/build-scan-data/<<extension-version>>/pending-uploads/*.log
.
Slow resolution of host name
Build Scans attempt to determine the host name of the machine. An issue affecting macOS can cause a delay when doing this in some environments.
If you see a warning during your build that resolving the local host name is slow, you can workaround the problem by adding a host name mapping to your /etc/hosts
file.
Add these lines to your /etc/hosts
file, substituting your computer name for 'mbpro' in the below snippet:
127.0.0.1 localhost mbpro.local
::1 localhost mbpro.local
Forked Maven builds
Several Maven plugins fork a new Maven build during the execution of a build. When the project is configured to publish a Build Scan, the forked Maven build will publish one as well. Depending on the use case, this behavior is desirable or not. The Develocity Maven extension does not detect if it’s executed within a forked Maven build to avoid publishing a Build Scan. In some circumstances and specific setups it can lead to errors on the forked Maven build and we then advise you to disable the Build Scan functionality of the Develocity Maven extension for such builds. This does not affect the use of the Build Cache.
The following sections show how to disable publishing a Build Scan for various Maven plugins that spawn forked Maven builds.
Maven invoker plugin
For the Maven invoker plugin set the gradle.scan.disabled
system property to true
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
<configuration>
...
<properties>
<gradle.scan.disabled>true</gradle.scan.disabled>
</properties>
...
</configuration>
...
</plugin>
Maven verifier
For the Maven verifier you can set the gradle.scan.disabled
CLI option on the Verifier
to true
.
verifier.addCliOption("-Dgradle.scan.disabled=true");
Maven archetype plugin
While integration testing an archetype with the Maven archetype plugin a Maven build will be forked. To disable Build Scan publishing, you can set the gradle.scan.disabled
system property to true
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-archetype-plugin</artifactId>
<configuration>
...
<properties>
<gradle.scan.disabled>true</gradle.scan.disabled>
</properties>
...
</configuration>
...
</plugin>
Maven release plugin
For the Maven release plugin set the gradle.scan.disabled
system property to true
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
...
<arguments>
-Dgradle.scan.disabled=true
</arguments>
...
</configuration>
...
</plugin>
Using the Build Cache
The Build Cache speeds up your builds by reusing outputs from any previous build, on any machine that is connected to the same Build Cache backend. It does this by reducing the inputs of a goal execution down to a strong hash key and storing the execution’s output under that key. It supports a local Build Cache that allows other subsequent builds on the same machine to reuse the outputs whenever they execute a goal with the same inputs. The full benefit of the Build Cache is realized when also using the remote backend that Develocity provides. This remote Build Cache allows you to share cached outputs across your whole team, including local and CI builds.
Please refer to the Build Cache guide for step-by-step instructions on how to get started and in-depth explanations of important concepts. Moreover, the guide shows how to measure the effectiveness of the Build Cache in your project and explains how to roll out the Build Cache in your organization.
The build caching functionality for Maven requires a Develocity license. The free |
Configuring the Build Cache
In order to use build caching for Apache Maven, you need to configure the location of your Develocity server.
gradleEnterprise.setServer("https://develocity.mycompany.com");
$ mvn package -Dgradle.enterprise.url=https://develocity.mycompany.com
<gradleEnterprise>
<server>
<url>https://develocity.mycompany.com</url>
</server>
</gradleEnterprise>
The precise URL you need depends on the hostname that your Develocity instance has been configured with. If in doubt, be sure to ask whomever manages that instance.
You may encounter a warning about an untrusted certificate when connecting to Develocity over HTTPS. The ideal solution is for someone to add a valid SSL certificate to the Develocity instance, but we recognise that you may not be able to do that. In this case, set the allowUntrustedServer
option to true
:
gradleEnterprise.setAllowUntrustedServer(true);
$ mvn package -Dgradle.enterprise.allowUntrustedServer=true
<gradleEnterprise>
<server>
<allowUntrusted>true</allowUntrusted>
</server>
</gradleEnterprise>
This is a convenient workaround during the initial evaluation, but it is a serious security issue and should not be used in production. |
Configuring the local Build Cache
The extension uses a local Build Cache to store build outputs in the local filesystem. It prevents network round-trips by storing both outputs that local builds created, as well as outputs that were downloaded from the remote Build Cache.
Disabling the local Build Cache
The local Build Cache is enabled by default. This can be changed by setting the enabled
option to false
.
buildCache.getLocal().setEnabled(false);
$ mvn package -Dgradle.cache.local.enabled=false
<gradleEnterprise>
<buildCache>
<local>
<enabled>false</enabled>
</local>
</buildCache>
</gradleEnterprise>
Disabling local store
(Maven extension 1.14+)
By default, outputs are stored in the local Build Cache if it is enabled and the build includes the clean
lifecycle phase. Storing outputs in the local Build Cache can be disabled explicitly by setting the storeEnabled
option to false
.
buildCache.getLocal().setStoreEnabled(false);
$ mvn package -Dgradle.cache.local.storeEnabled=false
<gradleEnterprise>
<buildCache>
<local>
<storeEnabled>false</storeEnabled>
</local>
</buildCache>
</gradleEnterprise>
Changing the local Build Cache directory
The local Build Cache is located at ${user.home}/.m2/.develocity/build-cache
by default. This can be changed by setting the directory
option.
buildCache.getLocal().setDirectory(new File("path/to/local/build-cache"));
$ mvn package -Dgradle.cache.local.directory=path/to/local/build-cache
<gradleEnterprise>
<buildCache>
<local>
<directory>/path/to/local/build-cache</directory>
</local>
</buildCache>
</gradleEnterprise>
It is a common practice in large organizations to put the user home on a network share. Since the underlying motivation of a local Build Cache is to prevent network round-trips, you should explicitly configure the local Build Cache directory to a path on the local filesystem. |
Configuring local Build Cache cleanup
To prevent the local Build Cache from growing in size indefinitely, the local Build Cache directory is cleaned up periodically. By default, the cleanup interval is 24 hours and the retention time is 7 days. The cleanup can be disabled by setting the enabled
option to false
.
buildCache.getLocal().getCleanupPolicy().setEnabled(false);
$ mvn package -Dgradle.cache.local.cleanup.enabled=false
<gradleEnterprise>
<buildCache>
<local>
<cleanup>
<enabled>false</enabled>
</cleanup>
</local>
</buildCache>
</gradleEnterprise>
The cleanup interval and retention time are controlled by the interval
and retention
options. The formats accepted are based on the ISO-8601 duration format PnDTnHnMn.nS
.
buildCache.getLocal().getCleanupPolicy().setRetentionPeriod(java.time.Duration.ofDays(30));
buildCache.getLocal().getCleanupPolicy().setCleanupInterval(java.time.Duration.ofDays(10));
$ mvn package -Dgradle.cache.local.cleanup.retention=P30D -Dgradle.cache.local.cleanup.interval=P10D
<gradleEnterprise>
<buildCache>
<local>
<cleanup>
<retention>P30D</retention>
<interval>P10D</interval>
</cleanup>
</local>
</buildCache>
</gradleEnterprise>
Using the Build Cache to store fingerprints of external dependencies
The Build Cache can optionally be used to store and retrieve fingerprints of external dependency jar files, in addition to the local fingerprint cache in the user’s Maven home directory,
When enabled, fingerprint recalculation across machines is avoided. This offers a considerable performance improvement when the build has large jar file dependencies or when the build is executed on machines with slow disk I/O.
However, in case of high latency to the remote Build Cache, it can have an adverse effect on build performance.
Therefore, storing and retrieving external dependency jar fingerprints in the Build Cache is disabled by default since version 1.13 of the Develocity Maven extension. It must be enabled explicitly via a system property.
$ mvn package -Dgradle.cache.cacheFingerprintsInBuildCache=true
With a remote Build Cache, it is possible that the round-trip time to store and retrieve fingerprints exceeds the time to calculate fingerprints. Benchmarking your build with and without fingerprint caching is advised. |
Working offline
In order to work offline, the extension needs to have run in online mode at least once in the past 24 hours to check whether the given Develocity server allows build caching for Maven. The result of this check is stored in a token in the user home. As long as you are working online, the token is refreshed every hour. The local Build Cache will keep working in offline mode until that token expires after 24 hours.
Configuring the remote Build Cache
Develocity provides a Build Cache node that is built into the server. Additionally, remote Build Cache nodes can be spun up and connected to the server. By default, the built-in Build Cache node of the Develocity server is used.
Using a different Build Cache node
The address of the remote Build Cache node can be configured in the server
option.
buildCache.getRemote().getServer().setUrl(java.net.URI.create("http://my-node/cache/"));
$ mvn package -Dgradle.cache.remote.url=http://my-node/cache/
<gradleEnterprise>
<buildCache>
<remote>
<server>
<url>http://my-node/cache/</url>
</server>
</remote>
</buildCache>
</gradleEnterprise>
Note that you still need to configure the address of your Develocity server in the top-level server
option.
Similar to the top-level Develocity server configuration, the remote Build Cache server configuration also provides an
Using the Programmatic configuration (Maven extension v1.7+)
Add the following to gradle-enterprise.xml
|
This is a convenient workaround during the initial evaluation, but it is a serious security issue and should not be used in production. |
Supplying remote Build Cache credentials
When using Maven extension version 1.15+, Develocity 2022.3+ and Develocity Build Cache Nodes 13+, the same access key credential used for Build Scan publishing, Test Distribution and other functions can be used for build cache access control.
Alternatively, a specific username and password can be specified that will be used instead of any available access key. The username and password can be specified directly in your Develocity configuration, or via a Maven settings.xml
file.
buildCache.getRemote().getServer().getCredentials().setUsername("my-username");
buildCache.getRemote().getServer().getCredentials().setPassword("my-password");
$ mvn package -Dgradle.cache.remote.username=my-username -Dgradle.cache.remote.password=my-password
<gradleEnterprise>
<buildCache>
<remote>
<server>
<credentials>
<username>my-username</username>
<password>my-password</password>
</credentials>
</server>
</remote>
</buildCache>
</gradleEnterprise>
Instead of putting plain-text passwords into the configuration file, you should inject them via environment variables as demonstrated below.
<gradleEnterprise>
<buildCache>
<remote>
<server>
<credentials>
<username>${env.GRADLE_ENTERPRISE_CACHE_USERNAME}</username>
<password>${env.GRADLE_ENTERPRISE_CACHE_PASSWORD}</password>
</credentials>
</server>
</remote>
</buildCache>
</gradleEnterprise>
Supplying remote Build Cache credentials via Maven settings.xml
Alternatively, you can configure the Build Cache node credentials in the settings.xml
file, using Maven’s password encryption feature to safely store these credentials.
Note that credentials specified directly via Develocity configuration take precedence over the credentials specified in a settings.xml
file.
<servers>
<server>
<id>my-node</id>
<username>my-username</username>
<password>my-password</password>
</server>
</servers>
The Build Cache node with the ID my-node
can then be referenced in the remote Build Cache configuration.
buildCache.getRemote().getServer().setServerId("my-node");
$ mvn package -Dgradle.cache.remote.serverId=my-node
<gradleEnterprise>
<buildCache>
<remote>
<server>
<id>my-node</id>
<url>http://my-node/cache/</url>
</server>
</remote>
</buildCache>
</gradleEnterprise>
Disabling the remote Build Cache
The remote Build Cache is enabled by default. This can be changed by setting the enabled
option to false
.
buildCache.getRemote().setEnabled(false);
$ mvn package -Dgradle.cache.remote.enabled=false
<gradleEnterprise>
<buildCache>
<remote>
<enabled>false</enabled>
</remote>
</buildCache>
</gradleEnterprise>
Enabling remote store
Since the remote Build Cache is shared with other developers and CI machines, storing in the remote Build Cache is disabled by default. Storing outputs in the remote Build Cache can be enabled by setting the storeEnabled
option to true
.
buildCache.getRemote().setStoreEnabled(true);
$ mvn package -Dgradle.cache.remote.storeEnabled=true
<gradleEnterprise>
<buildCache>
<remote>
<storeEnabled>true</storeEnabled>
</remote>
</buildCache>
</gradleEnterprise>
In general, the remote Build Cache should only be populated by controlled build environments such as CI servers. Therefore, the recommendation is to only enable it on the CI server. |
Using Expect-Continue
(Maven extension 1.12+)
The HTTP Build Cache client allows opt-in use of HTTP Expect-Continue. This causes PUT requests to happen in two parts: first a check whether a body would be accepted, then transmission of the body if the server indicates it will accept it. This is particularly suitable for Build Cache servers that routinely redirect or reject PUT requests, as it avoids transmitting the cache entry just to have it rejected (e.g. the cache entry is larger than the Build Cache will allow). This additional check incurs extra latency when the server accepts the request, but reduces latency when the request is rejected or redirected.
While the Develocity Build Cache Node supports Expect-Continue, not all HTTP servers and proxies reliably do. Be sure to check that your Build Cache server does support it before enabling.
buildCache.getRemote().getServer().setUseExpectContinue(true);
$ mvn package -Dgradle.cache.remote.useExpectContinue=true
<gradleEnterprise>
<buildCache>
<remote>
<server>
<useExpectContinue>true</useExpectContinue>
</server>
</remote>
</buildCache>
</gradleEnterprise>
Redirects
(Maven extension 1.13+)
3xx
redirecting responses will be followed automatically.
Servers must take care when redirecting PUT
requests as only 307
and 308
redirect responses will be followed with a PUT
request. All other redirect responses will be followed with a GET
request, as per RFC 7231, without the entry payload as the body.
Allowing insecure protocols
(Maven extension 1.13+)
Using the remote Build Cache by default enforces the use of HTTPS to make sure your data is only sent via encrypted connections. If the Build Cache server, or any server in a redirect chain, does not use HTTPS the request will be aborted. This validation can be disabled by setting the allowInsecureProtocol
option to true
.
buildCache.getRemote().getServer().setAllowInsecureProtocol(true);
$ mvn package -Dgradle.cache.remote.allowInsecureProtocol=true
<gradleEnterprise>
<buildCache>
<remote>
<server>
<allowInsecureProtocol>true</allowInsecureProtocol>
</server>
</remote>
</buildCache>
</gradleEnterprise>
This is a convenient workaround during the initial evaluation, but it is a serious security issue and should not be used in production. |
Runtime classpath normalization
A common pattern is to have some build logic that writes volatile data to some files. For example your build might write a timestamp to a build.properties
file. This helps to identify the source of a build artifact. However, this also causes problems with build caching: when Maven executes tests, the runtime classpath becomes part of the cache key for that test run. Any resource file that is processed by Maven is also added to that runtime classpath. In consequence, if a build generates a build timestamp, this causes the runtime classpath to change on every build invocation, resulting in cache misses. To circumvent this situation the Maven extension provides several configuration options to normalize the runtime classpath in order to deal with this volatility.
Ignoring arbitrary files
The following snippet shows you how to ignore any file called META-INF/build.properties
on any runtime classpath in the given project. You can share this setting across many projects by putting it in the pluginManagement
section of your parent POM. You can use ANT-style patterns like META-INF/**/*.sql
as well.
buildCache.registerNormalizationProvider(context -> context
.configureRuntimeClasspathNormalization(
normalization -> normalization
.setIgnoredFiles("META-INF/build.properties")
));
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<normalization>
<runtimeClassPath>
<ignoredFiles>
<ignoredFile>META-INF/build.properties</ignoredFile>
</ignoredFiles>
</runtimeClassPath>
</normalization>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Files matching the patterns |
Ignoring specific entries in properties files
(Maven extension 1.8+)
Since properties files are a common file format to store data generated by the build, the normalization DSL provides special support for ignoring specific entries in properties files. Again, ANT-style patterns can be used to match relevant properties files. In the following example any files named build.properties
in com/example
or any subdirectory are matched and the value of the property build.timestamp
is ignored:
buildCache.registerNormalizationProvider(context -> context
.configureRuntimeClasspathNormalization(
normalization -> normalization
.addPropertiesNormalization("com/example/**/build.properties", "build.timestamp")
));
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<normalization>
<runtimeClassPath>
<propertiesNormalizations>
<propertiesNormalization>
<path>com/example/**/build.properties</path>
<ignoredProperties>
<ignore>build.timestamp</ignore>
</ignoredProperties>
</propertiesNormalization>
</propertiesNormalizations>
</runtimeClassPath>
</normalization>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
A common location to store properties files is the META-INF directory. Thus, the normalization DSL provides a shortcut for normalizing files matching META-INF/**/*.properties
buildCache.registerNormalizationProvider(context -> context
.configureRuntimeClasspathNormalization(
normalization -> normalization
.configureMetaInf(metaInf -> metaInf.setIgnoredProperties("app.version"))
));
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<normalization>
<runtimeClassPath>
<metaInf>
<ignoredProperties>
<ignore>app.version</ignore>
</ignoredProperties>
</metaInf>
</runtimeClassPath>
</normalization>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Normalizing contents of META-INF
(Maven extension 1.8+)
The <metaInf>
configuration element offers even more convenience configuration settings for normalizing the contents of the META-INF directory. For example, you may only want to ignore one or more attributes in MANIFEST files, e.g. Implementation-Version
instead of ignoring the whole file. This can be done as follows:
buildCache.registerNormalizationProvider(context -> context
.configureRuntimeClasspathNormalization(
normalization -> normalization
.configureMetaInf(metaInf -> metaInf.setIgnoredAttributes("Implementation-Version"))
));
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<normalization>
<runtimeClassPath>
<metaInf>
<ignoredAttributes>
<ignore>Implementation-Version</ignore>
</ignoredAttributes>
</metaInf>
</runtimeClassPath>
</normalization>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
If you want to ignore MANIFEST files completely there’s the <ignoreManifest>
configuration as a shorthand for that. It’s the equivalent of adding META-INF/MANIFEST.MF
as an ignored file.
buildCache.registerNormalizationProvider(context -> context
.configureRuntimeClasspathNormalization(
normalization -> normalization
.configureMetaInf(metaInf -> metaInf.setIgnoreManifest(true))
));
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<normalization>
<runtimeClassPath>
<metaInf>
<ignoreManifest>true</ignoreManifest>
</metaInf>
</runtimeClassPath>
</normalization>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
In situations where you have several changing files in the META-INF directory, you might want to ignore the contents of that directory completely. The <ignoreCompletely>
configuration is a shorthand for adding META-INF/**
to ignored files.
buildCache.registerNormalizationProvider(context -> context
.configureRuntimeClasspathNormalization(
normalization -> normalization
.configureMetaInf(metaInf -> metaInf.setIgnoreCompletely(true))
));
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<normalization>
<runtimeClassPath>
<metaInf>
<ignoreCompletely>true</ignoreCompletely>
</metaInf>
</runtimeClassPath>
</normalization>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
The more you ignore using runtime classpath normalization, the more likely false cache hits become. You should use these features with care and try to narrow down the scope of normalizations as much as possible, e.g. you should prefer normalizing a single MANIFEST attribute over ignoring the META-INF directory completely. |
System property normalization
It is common to use system properties as vehicles to transport information between different executions. It is also not unheard of that these system properties do not have a direct effect on the results of the execution of specific goals.
One example would be having a temporary folder name or a timestamp passed to a test goal. These will change in each execution, but in certain cases, do not determine the result of these executions. These are the cases where system property normalization can be used.
Ignoring system properties by keys
The normalization provides a way to ignore certain system properties by their key
buildCache.registerNormalizationProvider(context -> context
.configureSystemPropertiesNormalization(
normalization -> normalization
.setIgnoredKeys("examplePropertyName")
));
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<normalization>
<systemProperties>
<ignoredKeys>
<ignore>examplePropertyName</ignore>
</ignoredKeys>
</systemProperties>
</normalization>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Declaring inputs and outputs
The Build Cache works based on inputs and outputs. For each supported goal execution a cache key is calculated by inspecting all inputs. The cache key is then used to lookup the outputs of that execution in the cache. If no result can be found, the goal is executed and the outputs are stored in the Build Cache under the cache key. This section explains how input and outputs can be fine-tuned.
The extension already configures caching for some plugins and goals out of the box. A list of those plugins and goals can be seen in Cacheable plugins and goals.
Adding additional inputs and outputs to a plugin or execution
The predefined inputs and outputs of any supported goal can be augmented by declaring them in the <pluginManagement>
section of your pom.xml
file. A common use case for declaring additional input files are test cases that read from a location that is not automatically tracked. For example, you might have Cucumber specification files located in the src/test/specs
directory. Any change to the files in that directory may change the result of running the tests. So changing specification files should result in rerunning the tests and not loading the results from the cache. Without additional configuration the Build Cache is unaware of these additional inputs and will therefore load the result from the Build Cache even if specification files change.
Declaring additional inputs
The following will add the directory src/test/specs
as an input to all executions of the Apache Maven Surefire plugin. Any files in that folder which match the given includes and excludes will then be tracked as part of the cache key:
buildCache.registerMojoMetadataProvider(context -> {
context.withPlugin("maven-surefire-plugin",
() -> context.inputs(inputs -> inputs
.fileSet(
"specs",
"src/test/specs",
fileSet -> fileSet
.include("**/*.feature")
.exclude("archive/**/*.feature")
.normalizationStrategy(MojoMetadataProvider.Context.FileSet.NormalizationStrategy.RELATIVE_PATH)
))
);
});
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<inputs>
<fileSets>
<fileSet>
<name>specs</name>
<paths>
<path>src/test/specs</path>
</paths>
<includes>
<include>**/*.feature</include>
</includes>
<excludes>
<exclude>archive/**/*.feature</exclude>
</excludes>
<normalization>RELATIVE_PATH</normalization>
</fileSet>
</fileSets>
</inputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
While processing inputs, various normalization strategies can be applied in order to raise the effectiveness of the Build Cache. In other words, normalization strategies are a way of ignoring changes to input files that are irrelevant for the goal execution. The following input normalization strategies are supported:
Normalization Strategy | Description | ignoreEmptyDirectories | ignoreLineEndings |
---|---|---|---|
IGNORED_PATH |
Considers the full content of files, but ignores their path. |
Not Supported |
Supported |
NAME_ONLY |
Considers the full content of files, but only tracks their name and not the rest of their path. |
Supported |
Supported |
RELATIVE_PATH |
The default strategy. Considers the full content of a file, but only tracks their path relative to their root directory. The root directory is the directory that was added as an input. The path of that root directory itself is ignored. |
Supported |
Supported |
ABSOLUTE_PATH |
Considers the full content of files as well as their absolute path. Using this strategy is strongly discouraged, as the project directory (and thus all absolute paths) are usually different on different machines, which prevents cache hits. |
Supported |
Supported |
CLASSPATH |
Considers only the information relevant for running Java code. |
Not Supported |
Supported |
COMPILE_CLASSPATH |
Considers only the information relevant for compiling Java code. This means for example that only class files are considered and private implementation details like method bodies are ignored. |
Not Supported |
Not Supported |
Ignoring empty directories
(Maven extension 1.8+)
The NAME_ONLY
, RELATIVE_PATH
, and ABSOLUTE_PATH
strategies support additional normalization options. Their sensitivity to the presence of empty directories in the source tree can be controlled. The default is to take empty directories into account. This means that adding an empty directory to the source tree will result in a cache miss. The following configuration causes empty directories to be ignored:
buildCache.registerMojoMetadataProvider(context -> {
context.withPlugin("maven-surefire-plugin",
() -> context.inputs(inputs -> inputs
.fileSet(
"specs",
"src/test/specs",
fileSet -> fileSet
.normalizationStrategy(MojoMetadataProvider.Context.FileSet.NormalizationStrategy.RELATIVE_PATH)
.emptyDirectoryHandling(MojoMetadataProvider.Context.FileSet.EmptyDirectoryHandling.IGNORE) (1)
))
);
});
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<inputs>
<fileSets>
<fileSet>
<name>specs</name>
<paths>
<path>src/test/specs</path>
</paths>
<normalization>
<strategy>RELATIVE_PATH</strategy>
<ignoreEmptyDirectories>true</ignoreEmptyDirectories> (1)
</normalization>
</fileSet>
</fileSets>
</inputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
1 | Mark empty directories as ignorable |
A common reason for having empty directories in the source tree is using a version control system like Git that only keeps tracks of files. When one developer deletes a directory tree on their machine and another developer pulls that change from the repository, Git will only delete the files contained in that directory tree leaving parent directories empty. |
Ignoring line endings
(Maven extension 1.11+)
The ignoreLineEndings
option allows authors to specify that line endings in text files should be normalized for Build Cache checks, so that files that only differ by line endings will be considered identical. Binary files, on the other hand, will not be affected by this normalization.
Line ending normalization only applies to text files encoded with the ASCII character set or one of its supersets (e.g., UTF-8). Text files encoded in a non-ASCII character set (e.g., UTF-16) will be treated as binary files and will not be subject to line ending normalization. |
buildCache.registerMojoMetadataProvider(context -> {
context.withPlugin("maven-surefire-plugin",
() -> context.inputs(inputs -> inputs
.fileSet(
"specs",
"src/test/specs",
fileSet -> fileSet
.normalizationStrategy(MojoMetadataProvider.Context.FileSet.NormalizationStrategy.RELATIVE_PATH)
.lineEndingHandling(MojoMetadataProvider.Context.FileSet.LineEndingHandling.NORMALIZE) (1)
))
);
});
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<inputs>
<fileSets>
<fileSet>
<name>specs</name>
<paths>
<path>src/test/specs</path>
</paths>
<normalization>
<strategy>RELATIVE_PATH</strategy>
<ignoreLineEndings>true</ignoreLineEndings> (1)
</normalization>
</fileSet>
</fileSets>
</inputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
1 | Mark line endings as ignorable |
All strategies except COMPILE_CLASSPATH
support this option.
The Maven extension normalizes line endings in source files when computing the Build Cache key for compile
or testCompile
goals of the maven-compiler-plugin.
Declaring additional outputs
Cucumber can be configured to generate various types of reports. These reports may be located in an output folder different from the default test report folder. In order to store them in the Build Cache for later retrieval the output location needs to be declared as an additional output. The following will add the additional output directory ${project.build.directory}/cucumber
to the default-test
execution of the surefire plugin. The contents of this directory will become part of the Build Cache archive for this execution.
buildCache.registerMojoMetadataProvider(context -> {
context.withPlugin("maven-surefire-plugin", () -> {
if ("cucumber-tests".equals(context.getMojoExecution().getExecutionId())) {
context.outputs(outputs -> outputs.directory("cucumber-reports", "${project.build.directory}/cucumber"));
}
}
);
});
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>cucumber-tests</id>
<outputs>
<directories>
<directory>
<name>cucumber-reports</name>
<path>${project.build.directory}/cucumber</path>
</directory>
</directories>
</outputs>
</execution>
</executions>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Configuring caching for a specific goal execution is not limited to declaring additional outputs. The same constructs for defining additional inputs that have been shown before can also be used for specific goal executions. |
Overriding inputs and outputs
The predefined inputs and outputs of any supported goal that are used by the Develocity Maven extension can be overridden, i.e. redefined with a custom value. A common use case is to override the value of an input property because it contains an absolute path that would prevent cache hits on other machines. For example, the maven-checkstyle-plugin has a propertyExpansion
input property that may contain an absolute path in some use cases.
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<propertyExpansion>checkstyle.additional.suppressions.file=${project.basedir}/custom-suppressions.xml</propertyExpansion>
</configuration>
</plugin>
In this case, the propertyExpansion
input property can be redefined for the purpose of cache key computation in Develocity while the Maven goal’s implementation will continue to read the existing configuration.
buildCache.registerMojoMetadataProvider(context -> {
context.withPlugin("maven-checkstyle-plugin",
() -> context.inputs(inputs -> inputs
.property("propertyExpansion", "checkstyle.additional.suppressions.file=ignored") (1)
.fileSet(
"checkstyle.additional.suppressions.file",
"${project.basedir}/custom-suppressions.xml", (2)
fileSet -> fileSet
.normalizationStrategy(MojoMetadataProvider.Context.FileSet.NormalizationStrategy.IGNORED_PATH)
.lineEndingHandling(MojoMetadataProvider.Context.FileSet.LineEndingHandling.NORMALIZE)
)
)
);
});
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
<inputs>
<properties>
<property>
<name>propertyExpansion</name>
<value>checkstyle.additional.suppressions.file=ignored</value> (1)
</property>
</properties>
<fileSets>
<fileSet>
<name>checkstyle.additional.suppressions.file</name>
<paths>
<path>${project.basedir}/custom-suppressions.xml</path> (2)
</paths>
<normalization>
<strategy>IGNORED_PATH</strategy>
<ignoreLineEndings>true</ignoreLineEndings>
</normalization>
</fileSet>
</fileSets>
</inputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
1 | Redefine value of propertyExpansion input property |
2 | Track contents of ${project.basedir}/custom-suppressions.xml as inputs ignoring the file name and the type of line endings |
Disabling build caching for a plugin or execution
You can disable caching on a fine-grained level in the <pluginManagement>
section of your pom.xml
file. The following will disable caching for all executions of the failsafe plugin in the given project:
buildCache.registerMojoMetadataProvider(context -> {
context.withPlugin("maven-failsafe-plugin",
() -> context.outputs(outputs -> outputs.notCacheableBecause("these tests verify integration with other systems and should rerun even if our inputs didn't change"))
);
});
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<outputs>
<notCacheableBecause>these tests verify integration with other systems and should rerun even if our inputs didn't change</notCacheableBecause>
</outputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
You can also disable caching for a specific execution. Other executions of that plugin will then still remain cacheable. The following will disable caching only for the systems-integration-test
execution of the failsafe plugin. Other tests will remain cacheable.
buildCache.registerMojoMetadataProvider(context -> {
context.withPlugin("maven-failsafe-plugin", () -> {
if ("systems-integration-test".equals(context.getMojoExecution().getExecutionId())) {
context.outputs(outputs -> outputs.notCacheableBecause("these tests verify integration with other systems and should rerun even if our inputs didn't change"));
}
}
);
});
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<id>systems-integration-test</id>
<outputs>
<notCacheableBecause>these tests verify integration with other systems and should rerun even if our inputs didn't change</notCacheableBecause>
</outputs>
</execution>
</executions>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Disabling storing outputs for a specific goal or execution
(Maven extension 1.14.3+)
By default, outputs are stored in the Build Cache if it is enabled and the build includes the clean
lifecycle phase. Disabling storing outputs of a specific goal can be achieved by setting the storeEnabled
option to false
on the outputs
configuration of the goal’s plugin or execution.
buildCache.registerMojoMetadataProvider(context -> {
context.withPlugin("maven-compiler-plugin", () -> context.outputs(outputs -> outputs.storeEnabled(false)));
});
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<outputs>
<storeEnabled>false</storeEnabled>
</outputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
An example use case is when local development has the side effect of corrupting outputs of a goal (e.g. when the IDE and Maven use the same compilation output directory). Without disabling storing outputs to the Build Cache, this can lead to issues with corrupt cache entries being loaded which make downstream goals fail (to resolve such a situation you can use the -DrerunGoals
command line argument). To avoid this situation, the above sample configuration for the compile goal disables storing its outputs in a local-only enabled Maven profile. On CI, outputs will still be stored in the Build Cache so that local developer builds are able to reuse cache entries from prior CI builds.
The following example shows how to configure the local profile to disable storing outputs generated by the compile goal. To check if the build is executed locally we check that the environment variable CI
is not set.
buildCache.registerMojoMetadataProvider(context -> {
context.withPlugin("maven-compiler-plugin", () -> {
if (!Boolean.parseBoolean(System.getenv("CI"))) {
context.outputs(outputs -> outputs.storeEnabled(false));
}
});
});
<profiles>
<profile>
<id>local</id>
<activation>
<property>
<name>!env.CI</name>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<outputs>
<storeEnabled>false</storeEnabled>
</outputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
Conditionally skipping a goal execution
(Maven extension 1.15+)
You can conditionally skip a goal execution by configuring the skipIfTrue
option with one or several Mojo
properties of type boolean
. If the value of any configured property is true
, then the goal execution will be skipped.
buildCache.registerMojoMetadataProvider(context -> {
context.withPlugin("maven-enforcer-plugin", () -> {
context.skipIfTrue("skip"); (1)
if ("enforce-banned-dependencies".equals(context.getMojoExecution().getExecutionId())) {
context.skipIfTrue("skip"); (2)
}
});
});
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<skipIfTrue>
<property>skip</property> (1)
</skipIfTrue>
<executions>
<execution>
<id>enforce-banned-dependencies</id>
<skipIfTrue>
<property>skip</property> (2)
</skipIfTrue>
</execution>
</executions>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
1 | Will skip all executions of maven-enforcer-plugin if skip property is set |
2 | Will skip only specific execution of maven-enforcer-plugin if skip property is set |
An example use case is a goal that supports skipping of its execution via setting a specific boolean property. Even if a goal execution is skipped via such a property, the Build Cache will still attempt to retrieve outputs from a previous execution. In order to avoid unnecessary computation and network overhead, the name of the specific boolean property can be declared via skipIfTrue
.
All the supported goals are already configured to skip the Build Cache if the goal is skipped.
Making other goals cacheable
The extension allows you to make any goal cacheable, beyond the ones that are supported out of the box. Take great care to define all of the goal’s inputs and outputs before doing so, to avoid false cache hits and follow-up errors.
When making goals cacheable, you don’t need to repeat the values of all their inputs and outputs. You can simply provide the name of each property and the extension will look up the value in the goal’s configuration. The extension will make sure that you have handled all configuration parameters of the goal in this way. If some parameter is irrelevant for the purposes of caching, e.g. because it only affects console output, you can tell the extension to ignore it.
For input properties, the extension supports all primitives, Strings, Enums and Collections, Arrays and Maps of those. Any other types need to be broken down using the nestedProperties
(for a single complex type) or iteratedProperties
(for a Collection of complex types) configuration.
buildCache.registerMojoMetadataProvider(context -> {
context.withPlugin("awesome-but-slow-plugin", () -> {
if ("my.company".equals(context.getMojoExecution().getPlugin().getGroupId())) {
context.inputs(inputs -> inputs
.fileSet("sources", fileSet -> fileSet.includesProperty("includes").excludesProperty("excludes"))
.properties("encoding")
.ignore("logWarnings")
)
.nested("forkOptions", nestedContext -> nestedContext.inputs(inputs -> inputs.properties("maxHeap")))
.iterate("targetPlatforms", iteratedContext -> iteratedContext.inputs(inputs -> inputs.properties("architecture", "linkingMode")))
.outputs(outputs -> outputs.directory("outputDir").cacheable("This plugin has CPU-bound goals with well-defined inputs and outputs"));
}
}
);
});
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<groupId>my.company</groupId>
<artifactId>awesome-but-slow-plugin</artifactId>
<inputs>
<fileSets>
<fileSet>
<name>sources</name>
<includesProperty>includes</includesProperty>
<excludesProperty>excludes</excludesProperty>
</fileSet>
</fileSets>
<properties>
<property>
<name>encoding</name>
</property>
</properties>
<ignoredProperties>
<ignore>logWarnings</ignore>
</ignoredProperties>
</inputs>
<nestedProperties>
<property>
<name>forkOptions</name>
<inputs>
<properties>
<property>
<name>maxHeap</name>
</property>
</properties>
</inputs>
</property>
</nestedProperties>
<iteratedProperties>
<property>
<name>targetPlatforms</name>
<inputs>
<properties>
<property>
<name>architecture</name>
</property>
<property>
<name>linkingMode</name>
</property>
</properties>
</inputs>
</property>
</iteratedProperties>
<outputs>
<directories>
<directory>
<name>outputDir</name>
</directory>
</directories>
<cacheableBecause>this plugin has CPU-bound goals with well-defined inputs and outputs</cacheableBecause>
</outputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Troubleshooting
While working with the Build Cache you may encounter situations where build results are not retrieved from the Build Cache, although you would expect them to. This section provides guidance for analyzing and solving these problems.
Debugging cache operations
The extension provides several loggers to make analyzing problems with build caching easier. To show the effective Build Cache configuration, use the develocity.goal.cache
logger:
$ mvn clean verify -Dorg.slf4j.simpleLogger.log.develocity.goal.cache=debug [DEBUG] Using the Build Cache with the following configuration: Local Build Cache: enabled directory: /Users/johndoe/.m2/.gradle-enterprise/build-cache cleanup: enabled retention: 168h interval: 24h Remote Build Cache: enabled url: https://my-server/cache/ authenticated: false storeEnabled: false allowUntrustedServer: false useExpectContinue: false
The develocity.goal.cache
logger will also print the result of determining the cacheability of the executed goals:
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-build-scan-extension-sample --- [INFO] skip non existing resourceDirectory /Users/johndoe/workspace/maven-build-scan-quickstart/src/main/resources [DEBUG] Build caching was not enabled for this goal execution because the 'resources' goal was not supported. [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-build-scan-extension-sample --- [DEBUG] Local cache miss [DEBUG] Remote cache miss [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /Users/johndoe/workspace/maven-build-scan-quickstart/target/classes [DEBUG] Stored outputs in the local Build Cache
All information printed by the |
Finding the cause of cache misses
Sometimes you might encounter a situation where a goal execution is not avoided by using the Build Cache although you would expect it to be. For example, if you run the same build twice without any changes, the outputs of all supported goals should be retrieved from the local Build Cache (if it is enabled). If this is not the case, this almost always is caused by unstable inputs, e.g. a timestamp being added to a file by some build logic. In order to identify which inputs change between builds the Maven build comparison feature can be used. Simply run the same Maven build twice and compare those two builds. To make it easier to find unstable input files capturing of goal input files should be explicitly enabled using -Dgradle.scan.captureGoalInputFiles=true
Capturing goal input files has an impact on build performance. For this reason it is disabled by default. |
Once the Build Scans have been published they can be compared in Develocity. In this example, the build was configured to write a timestamp to the build.properties
file. When comparing the two builds this shows up nicely in the comparison.
Once the changing input is identified, the build can be changed to be reproducable or normalization can be used to ignore the changing input.
Solving common causes of cache misses
Some widely used Maven plugins are a common cause of cache misses because they produce changing build results. This chapter shows you how to solve them.
JAXB
Old versions of the XJC binding compiler generate classes with methods in random order on each invocation. This has been fixed in JAXB 2.2.11. Since there are several Maven plugins available for JAXB, you need to find out which release of the plugin you are using includes the fixed JAXB release. For example the jaxb2-maven-plugin includes the fix starting from release 2.1.
Another cause of unstable build results when using JAXB is the fact that the XJC binding compiler generates a header containing a timestamp into all Java classes. This behavior is controlled by the --no-header
option which is false
by default (= always generate a header). To prevent this add the corresponding configuration to the Maven plugin you use, for example:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.4</version>
<configuration>
<noGeneratedHeaderComments>true</noGeneratedHeaderComments>
</configuration>
</plugin>
If you’re using the maven-jaxb2-plugin it’s still a good idea to remove unnecessary instability from its outputs. However, the Gradle Enterprise Maven Extension supports caching its generate
goal even if file headers are being generated. Thus, downstream goals will not be affected by its changing outputs when they are loaded from the cache.
Some Maven JAXB plugins generate code based on the current system’s locale if not configured otherwise. This leads to unstable outputs depending on the configuration of the machine that executes the build, which in turn can lead to cache misses. For this reason the locale to use during code generation should be explicitly configured. Both the jaxb2-maven-plugin and the maven-jaxb2-plugin provide a <locale>
option for this.
maven-bundle-plugin
Older versions of the maven-bundle-plugin generate a timestamp in the MANIFEST.MF
file. To prevent this, use version 5.1.5
+ of the plugin or adjust the plugin configuration as following:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
<instructions>
<_removeheaders>Bnd-LastModified</_removeheaders>
</instructions>
</configuration>
</plugin>
Note that the underscore in <_removeheaders>
is not a typo.
maven-resources-plugin
A common pattern is to write a build timestamp to a build.properties
file using Maven resource filtering. One way to fix this is using normalization to ignore the file. Alternatively the build can be adjusted by moving the generation of the timestamp to a separate profile that is only executed when creating a release:
build.timestamp=${timestamp}
<properties>
<timestamp>2019-03-07 12:00:00.000</timestamp>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<profile>
<id>release</id>
<properties>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss.S</maven.build.timestamp.format>
<timestamp>${maven.build.timestamp}</timestamp>
</properties>
</profile>
maven-surefire-plugin
JAR file in test classpath
By default, the test runtime classpath used by the maven-surefire-plugin
contains the classes directory of project dependencies if the build has been started with the mvn clean test
command. If the build was started using mvn clean package
or a later lifecycle phase, then, instead of the classes directory, the test runtime classpath will contain the JAR file. Such behavior might lead to unexpected cache misses.
To prevent such a situation you can configure the maven-jar-plugin
to produce the JAR file before the test
phase. For example by binding the default-jar
execution to the process-test-resources
phase:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<phase>process-test-resources</phase>
</execution>
</executions>
</plugin>
Such a change will force the maven-surefire-plugin
to always use the JAR file and will help to avoid cache misses.
Using with native-maven-plugin from GraalVM
Using the native-maven-plugin
from org.graalvm.buildtools
will prevent caching the output of the Surefire test goals. The native-maven-plugin
will register an untracked output folder under target/test-ids
which causes the goals to become uncacheable. To solve this, declare the folder as an output for the Surefire plugin in the configuration of the gradle-enterprise-maven-extension
as follows:
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<outputs>
<directories>
<directory>
<name>test-ids</name>
<path>${project.build.directory}/test-ids</path>
</directory>
</directories>
</outputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Using system properties
When the maven-surefire-plugin
is used with <systemPropertyVariables>
defined in the plugin’s configuration, if any of the defined properties contain a path, this path must be declared as an extra input/output parameter on the gradle-enterprise-plugin’s `surefire-plugin
related configuration. When the paths are not declared the task will not be cacheable and the goal’s cacheability reason will display Goal execution marked as not cacheable: Build caching was not enabled for this goal execution because system property 'samplesDir' with value '$path' was used as a command line argument, but not declared as an input or output
.
THe following example shows 3 system properties being configured and how to declare them respectively for cacheability.
<build>
<!-- ... -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.2</version>
<configuration>
<systemPropertyVariables>
<test.project.directory>${test.project.directory}</test.project.directory>
<test.output.directory>${test.output.directory}</test.output.directory>
<project.build.directory.testids>${project.build.directory}/test-ids</project.build.directory.testids>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<inputs>
<fileSets>
<fileSet>
<name>generatedTestDir</name>
<paths>
<path>${test.project.directory}</path>
</paths>
</fileSet>
</fileSets>
</inputs>
<outputs>
<directories>
<directory>
<name>testCacheDir</name>
<path>${test.output.directory}</path>
</directory>
<directory>
<name>testIdsDir</name>
<path>${project.build.directory}/test-ids</path>
</directory>
</directories>
</outputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
Alternatively normalization could be used to ignore certain system properties. Please refer to the system property normalization section of the extension user manual for details.
maven-failsafe-plugin
The maven-failsafe-plugin provides two goals: integration-test
and verify
. The former runs in the integration-test
phase of the build and writes its results to a summary file. The latter runs in the verify
phase, reads the summary file, and fails the build in case of test failures.
When configuring multiple Failsafe executions, they use the same output location for the summary file by default. This will prevent all but the first execution of the integration-test
goal to be cacheable due to overlapping outputs. In order to get cache hits for all executions, you should configure a different summary file for each of them:
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<id>first-execution</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<!-- ... -->
<summaryFile>${project.build.directory}/failsafe-reports/first-failsafe-summary.xml</summaryFile>
</configuration>
</execution>
<execution>
<id>second-execution</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<!-- ... -->
<summaryFile>${project.build.directory}/failsafe-reports/second-failsafe-summary.xml</summaryFile>
</configuration>
</execution>
</executions>
</plugin>
If you have configured multiple executions that execute the same or an overlapping set of test classes (e.g. with different parameters), you should in addition change the reports directory, for example:
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<id>first-execution</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<!-- ... -->
<reportsDirectory>${project.build.directory}/first-failsafe-reports</reportsDirectory>
<summaryFile>${project.build.directory}/first-failsafe-reports/failsafe-summary.xml</summaryFile>
</configuration>
</execution>
<execution>
<id>second-execution</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<!-- ... -->
<reportsDirectory>${project.build.directory}/second-failsafe-reports</reportsDirectory>
<summaryFile>${project.build.directory}/second-failsafe-reports/failsafe-summary.xml</summaryFile>
</configuration>
</execution>
</executions>
</plugin>
maven-compiler-plugin
When invoking the build without the clean
lifecycle, the Build Cache is in read-only mode. Existing cache entries produced by earlier builds are then reused but no new entries are stored. This works for all Maven goals that are supported out of the box with the exception of the maven-compiler-plugin. Since the maven-compiler-plugin can be used in conjunction with other plugins that produce class files (e.g. when also using another JVM language like Kotlin or Groovy in the same project), it uses the classes output directory (usually target/classes
) as an input. Therefore, builds without clean
will have different inputs and thus a different cache key.
Use pom.xml
merge strategies to solve misconfigurations
When there is a pom.xml configuration for the Gradle Enterprise Maven extension (e.g. runtime classpath normalization or declaring inputs and outputs for given plugins) on a parent pom.xml
and another configuration on a child pom.xml
, it can happen that the given configurations are merged incorrectly, resulting in a misconfiguration of the Gradle Enterprise Maven extension. To see the effective pom.xml
that is used during the execution of the build on any given project mvn help:effective-pom
can be executed, and the effective pom.xml
is printed to the console. If a check of the Gradle Enterprise Maven extension configuration shows that it’s invalid or not properly merged, then a different merge strategy can be applied as mentioned in this blog post.
In this example we have a parent project and a child project which both have specific Gradle Enterprise configurations for the compiler and Surefire mojos. The following excerpt is from the parent pom.xml
:
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<version>1.22.2</version>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<outputs>
<notCacheableBecause>something</notCacheableBecause> (1)
</outputs>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<inputs>
<properties>
<property>
<name>additionalProperty</name> (2)
<value>${additionalProperty}</value>
</property>
</properties>
</inputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
1 | Parent POM configures compiler mojo to be not cacheable |
2 | Parent POM configures Surefire mojo to track an additionalProperty as input |
This excerpt is from the child pom.xml
where we want to keep the configuration of the compiler mojo defined on the parent pom.xml
and add another property as input to the Surefire mojo:
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<version>1.22.2</version>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId> (1)
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<inputs>
<properties combine.children="append">
<property>
<name>anotherAdditionalProperty</name> (2)
<value>${anotherAdditionalProperty}</value>
</property>
</properties>
</inputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
1 | Child POM configures to inherit compiler mojo configuration from parent POM |
2 | Child POM configures Surefire mojo to track an anotherAdditionalProperty as input |
Due to the merging strategies available for Maven POM files there are several pitfalls:
-
If a child POM file wants to inherit the configuration of a parent POM file, it needs to declare the same plugins in the exact same order as in the parent POM such that Maven properly merges the two POM files.
-
If some elements of a parent POM need to be extended in a child POM, the above explained merges strategies should be taken into account. In the example child POM we use the
combine.children="append"
merge strategy to append theanotherAdditionalProperty
input to the existingadditionalProperty
input declared on the parent POM.
With the above setup the merged child POM produced by retrieving the effective POM via executing mvn help:effective-pom
resulted in the following merged child POM:
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<version>1.22.2</version>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<outputs>
<notCacheableBecause>something</notCacheableBecause> (1)
</outputs>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<inputs>
<properties combine.children="append"> (2)
<property>
<name>additionalProperty</name>
<value>${additionalProperty}</value>
</property>
<property>
<name>anotherAdditionalProperty</name>
<value>${anotherAdditionalProperty}</value>
</property>
</properties>
</inputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
1 | Merged child POM inherits the compiler mojo configuration from parent POM |
2 | Merged child POM configures Surefire mojo to track both properties as inputs |
Rerunning goals to deal with invalid cache entries
In rare circumstances the Build Cache might be filled with an invalid entry, e.g. when another process deletes the outputs of a goal while the cache entry is being created. In this case you can use the -DrerunGoals
command line argument to rerun the goals and overwrite the faulty cache entry.
Using Test Distribution
(Maven extension 1.8+, Develocity 2020.5+)
Develocity Test Distribution takes your existing test suites and distributes them across remote agents to execute them faster.
For information on how to use Test Distribution, please consult the Test Distribution User Manual. |
Using Predictive Test Selection
(Maven extension 1.14+, Develocity 2022.2+)
Develocity Predictive Test Selection allows developers to get faster feedback by running only tests that are likely to provide useful feedback on a particular code change using a probabilistic machine learning model.
For information on how to use Predictive Test Selection, please consult the Predictive Test Selection User Manual. |
Appendix A: Configuration reference
gradle-enterprise.xml
Most aspects of the Develocity Maven extension are configured in the gradle-enterprise.xml
configuration file. Some options can be overwritten by system properties.
The gradle-enterprise.xml
file can be put into several locations. These files are merged and their properties overwritten based on the precedence rules below:
-
<maven-home>/conf/gradle-enterprise.xml
is used to set global defaults for a given Maven installation. This is useful when you ship a custom Maven distribution to your teams. The location of this configuration file can be overwritten using the-Dgradle.global.config
argument. This can be useful for CI environments where changing the Maven installation is not possible. -
<classpath>/gradle-enterprise.xml
is used for organization-wide or team-wide configuration and overrides the global configuration. This allows to package agradle-enterprise.xml
file in the root of a custom extension jar that can be reused across projects. -
<project-dir>/.mvn/gradle-enterprise.xml
is used for project-specific configuration and overrides the classpath configuration. -
<user-home>/.m2/gradle-enterprise.xml
is used for user-specific configuration and overrides the project configuration. The location of this configuration file can be overwritten using the-Dgradle.user.config
argument. This can be useful for CI environments where changing the user home is not possible.
The example below shows a full reference of everything you can configure in this file.
Be sure to include the XML namespace declarations to get auto-completion in your IDE. The latest version of the schema is available at https://www.gradle.com/schema/gradle-enterprise-maven.xsd, or you can get a specific schema version by appending the Develocity Maven extension version to the schema location, e.g. https://www.gradle.com/schema/gradle-enterprise-maven-1.22.2.xsd. IntelliJ IDEA will mark unknown schemas as missing and they have to be explicitly fetched via the quick fix dialog (Alt + Enter). There is an open issue to make this more user-friendly. |
<gradleEnterprise
xmlns="https://www.gradle.com/gradle-enterprise-maven" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.gradle.com/gradle-enterprise-maven https://www.gradle.com/schema/gradle-enterprise-maven.xsd">
<!-- Whether the Develocity Maven extension should be enabled. Defaults to true. System property is 'gradle.enterprise.enabled'. -->
<enabled>true</enabled>
<!-- Project identifier to be sent to the Develocity server when build scan is published. System property is 'gradle.enterprise.projectId'. -->
<projectId>myProject</projectId>
<server>
<!-- ID used to reference an element in the settings.xml. System property is 'gradle.enterprise.serverId'. -->
<id>my-server</id>
<!-- Address of the Develocity server. System property is 'gradle.enterprise.url'. -->
<url>http://my-server/</url>
<!-- Whether untrusted connections to the Develocity server should be accepted. Defaults to false. System property is 'gradle.enterprise.allowUntrustedServer'. -->
<allowUntrusted>false</allowUntrusted>
<!-- The access key (without any hostname prefix) for authenticating with the Develocity server. Environment variable is 'GRADLE_ENTERPRISE_ACCESS_KEY'. -->
<accessKey>7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq</accessKey>
</server>
<!-- Storage directory for caches and temporary data. Defaults to ${user.home}/.m2/.gradle-enterprise. System property is 'gradle.enterprise.storage.directory'. -->
<storageDirectory>/some/location</storageDirectory>
<buildScan>
<!-- Behavior of publishing build scans. Possible values are ALWAYS, ON_FAILURE, ON_DEMAND. Defaults to ALWAYS. The 'scan' system property can be used to publish on demand. -->
<publish>ALWAYS</publish>
<!-- Terms of service acceptance (mandatory to publish to scans.gradle.com) -->
<termsOfService>
<!-- Address of the terms of use. Must be 'https://gradle.com/help/legal-terms-of-use'. Defaults to an empty string. System property is 'gradle.scan.termsOfService.url'. -->
<url></url>
<!-- Signal acceptance of the terms of use. Must be 'true'. Defaults to false. System property is 'gradle.scan.termsOfService.accept'. -->
<accept>false</accept>
</termsOfService>
<!-- Whether to upload the build scan in background. Defaults to true. System property is 'gradle.scan.uploadInBackground' -->
<backgroundBuildScanUpload>false</backgroundBuildScanUpload>
<!-- For extension < 1.11 - DEPRECATED: Whether to capture content hashes of each input file for build scan comparison. Defaults to false. System property is 'gradle.scan.captureGoalInputFiles' -->
<captureGoalInputFiles>true</captureGoalInputFiles>
<!-- For extension >= 1.11 -->
<capture>
<!-- Whether to capture content hashes of each input file for build scan comparison. Defaults to false. System property is 'gradle.scan.captureGoalInputFiles' -->
<goalInputFiles>true</goalInputFiles>
<!-- Whether to capture build output for build scans. Defaults to true. System property is 'gradle.scan.captureBuildLogging' -->
<buildLogging>true</buildLogging>
<!-- Whether to capture test output for build scans. Defaults to true. System property is 'gradle.scan.captureTestLogging' -->
<testLogging>true</testLogging>
</capture>
<!-- Obfuscated values for captured build scan data (optional). -->
<obfuscation>
<!-- The obfuscated username to capture (optional). -->
<username></username>
<!-- The obfuscated hostname to capture for local and public hostnames (optional). -->
<hostname></hostname>
<!-- The obfuscated IP addresses to capture (optional). -->
<ipAddresses></ipAddresses>
</obfuscation>
<!-- List of tags to capture. Additionally, system properties like 'scan.tag.<tag>' can be used to add tags. -->
<tags>
<tag>my tag</tag>
</tags>
<!-- List of links to capture. Additionally, system properties like 'scan.link.<name>=<url>' can be used to add links. -->
<links>
<link>
<name>my link</name>
<url>http://my-site.com</url>
</link>
</links>
<!-- List of custom values to capture. Additionally, system properties like 'scan.value.<name>=<value>' can be used to add custom values. -->
<values>
<value>
<name>my name</name>
<value>my value</value>
</value>
</values>
</buildScan>
<buildCache>
<!-- Local cache configuration -->
<local>
<!-- Whether the local cache is enabled. Defaults to true. System property is 'gradle.cache.local.enabled'. -->
<enabled>true</enabled>
<!-- Whether to store outputs in the local build cache (as opposed to only loading from it). Defaults to true. System property is 'gradle.cache.local.storeEnabled'. -->
<storeEnabled>true</storeEnabled>
<!-- Local cache directory. Defaults to ${user.home}/.m2/.gradle-enterprise/build-cache. System property is 'gradle.cache.local.directory'. -->
<directory>/some/other/location</directory>
<!-- Local cache cleanup configuration -->
<cleanup>
<!-- Whether local cache cleanup is enabled. Defaults to true. System property is 'gradle.cache.local.cleanup.enabled'. -->
<enabled>true</enabled>
<!-- Items in the cache that were not used in this period will be deleted. Defaults to P7D. System property is 'gradle.cache.local.cleanup.retention'. -->
<retention>P30D</retention>
<!-- Interval at which the cleanup occurs. Defaults to P1D. System property is 'gradle.cache.local.cleanup.interval'. -->
<interval>P10D</interval>
</cleanup>
</local>
<!-- Remote cache configuration -->
<remote>
<!-- Remote cache server configuration -->
<server>
<!-- Optionally use the ID of a server specified in your settings.xml to use its credentials. System property is 'gradle.cache.remote.serverId'. -->
<id>remote-cache</id>
<!-- URL of the remote cache. Defaults to ${gradle.enterprise.url}/cache/. System property is 'gradle.cache.remote.url'. -->
<url>http://my-node/cache/</url>
<!-- Optionally specify the credentials. The credentials specified here take precedence over the credentials in your settings.xml -->
<credentials>
<!-- The username to use to connect to an authenticated cache node. System property is 'gradle.cache.remote.username'. -->
<username>some-username</username>
<!-- The password to use to connect to an authenticated cache node. System property is 'gradle.cache.remote.password'. -->
<password>some-password</password>
</credentials>
<!-- Whether the remote cache accepts untrusted connections. Defaults to false. System property is 'gradle.cache.remote.allowUntrustedServer'. -->
<allowUntrusted>true</allowUntrusted>
<!-- Whether the client should enforce the use of HTTPS. Setting it to true will enable the usage of unencrypted HTTP. System property is 'gradle.cache.remote.allowInsecureProtocol'. -->
<allowInsecureProtocol>true</allowInsecureProtocol>
<!-- Whether the client should use HTTP Expect-Continue (https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3) when storing data on the server. System property is 'gradle.cache.remote.useExpectContinue'. -->
<useExpectContinue>true</useExpectContinue>
</server>
<!-- Whether the remote cache is enabled. Defaults to true. System property is 'gradle.cache.remote.enabled'. -->
<enabled>true</enabled>
<!-- Whether to store outputs in the remote build cache (as opposed to only loading from it). Defaults to false. System property is 'gradle.cache.remote.storeEnabled'. -->
<storeEnabled>true</storeEnabled>
</remote>
<!-- Whether the 'clean' lifecycle phase is required in order to store outputs in the build cache. Defaults to true. System property is 'gradle.cache.requireClean'. -->
<!-- You should only set this to 'false' when the build is started from a clean working directory. Otherwise, produced build cache entries may be incorrect. -->
<requireClean>true</requireClean>
</buildCache>
</gradleEnterprise>
Expression support
The gradle-enterprise.xml
configuration file supports two types of expressions that are evaluated when reading the configuration file:
-
${…}
-
Maven-style expression (behaves like in pom.xml) for simple use cases, e.g. referencing an environment variable (e.g.
${env.CACHE_USERNAME}
) -
#{…}
-
Spring Expression Language (SpEL) expressions for more complex use cases, e.g. converting an environment variable into a boolean (e.g. #{env['CI'] == null})
For both expression types, the following objects can be referenced:
-
session
-
the current
MavenSession
object (e.g.${session.request.cacheNotFound}
or#{session.request.cacheNotFound}
) -
basedir
-
the base directory of the build (e.g.
${basedir/src}
or#{basedir}/src
)
In addition, the following objects and functions can be referenced in SpEL expressions:
-
properties: Properties
-
user/system/profile properties (e.g.
#{properties['user.dir']}
). These are the same properties you can reference using the${«property-name»}
syntax.
User properties are passed via-D
on the command-line. System properties are provided by the runtime and containSystem.getProperties()
as well asenv.
-prefixed environment variables. Profile properties refer to properties defined in active Maven profiles. -
env: Map<String, String>
-
environment variables (e.g.
#{env['CI']}
) -
username: String
-
The username of the agent running the build (e.g.
#{username}
) -
ipAddresses: List<String>
-
The IP addresses of the agent running the build (e.g.
#{ipAddresses}
) -
isTrue(Object): boolean
-
returns
true
unless the supplied object’sString
value case-insensitively equalsfalse
,0
,0.0
, ornull
(e.g.#{isTrue(true)}
) -
isFalse(Object): boolean
-
returns
true
if the supplied object’sString
value case-insensitively equalsfalse
,0
,0.0
, ornull
(e.g.#{isFalse(false)}
) -
sha512(Object): Object
-
returns a SHA-512 String representation of the supplied object’s
String
value. If the supplied object is aList
, returns a list of the individualsha512
call for each item of the list.
The following example shows how to use both expression types to configure local and CI builds with a single gradle-enterprise.xml
file. It uses the JENKINS_URL
environment variable (which is present in builds on Jenkins) to determine whether the build is running locally or on CI. Based on that, it enables the local Build Cache and background Build Scan upload only for local builds but enables writing to the remote Build Cache only for CI builds. Moreover, it determines the URL of the remote Build Cache based on the fictional REGION
environment variable. Lastly, it uses Maven-style expressions to configure the remote Build Cache credentials based on custom environment variables that are typically injected by the CI server.
<gradleEnterprise
xmlns="https://www.gradle.com/gradle-enterprise-maven" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.gradle.com/gradle-enterprise-maven https://www.gradle.com/schema/gradle-enterprise-maven.xsd">
<buildScan>
<backgroundBuildScanUpload>{env['JENKINS_URL'] == null}</backgroundBuildScanUpload>
<obfuscation>
<username>{sha512(username)}</username>
<hostname>{isTrue(env['CI']) ? 'CI agent' : 'Local agent'}</hostname>
<ipAddresses>{sha512(ipAddresses)}</ipAddresses>
</obfuscation>
</buildScan>
<buildCache>
<local>
<enabled>{env['JENKINS_URL'] == null}</enabled>
</local>
<remote>
<server>
<url>{env['REGION'].startsWith('us') ? 'https://us.example.org/cache' : 'https://eu.example.org/cache'}</url>
<credentials>
<username>${env.GRADLE_ENTERPRISE_CACHE_USERNAME}</username>
<password>${env.GRADLE_ENTERPRISE_CACHE_PASSWORD}</password>
</credentials>
</server>
<enabled>true</enabled>
<storeEnabled>#{env['JENKINS_URL'] != null}</storeEnabled>
</remote>
</buildCache>
</gradleEnterprise>
pom.xml
The Develocity Maven extension also allows you to configure module-specific aspects in the corresponding pom.xml
file. This allows you to share common configuration between your project by putting it in a parent POM. See the example below for a full reference.
In order to get auto-completion in your IDE, be sure to include the XML namespace and schema location as shown in the example below. The latest version of the schema is always available at https://www.gradle.com/schema/gradle-enterprise-maven-project.xsd, or you can get a specific schema version by appending the Develocity Maven extension version to the schema location, e.g. https://www.gradle.com/schema/gradle-enterprise-maven-project-1.22.2.xsd. IntelliJ IDEA will mark unknown schemas as missing and they have to be explicitly fetched via the quick fix dialog (Alt + Enter). There is an open issue to make this more user-friendly. Please note that auto-completion is currently only supported by Eclipse. For IntelliJ IDEA, there’s an open issue to add such a feature. |
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd
https://www.gradle.com/gradle-enterprise-maven-project https://www.gradle.com/schema/gradle-enterprise-maven-project.xsd">
<!-- other build configuration -->
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<configuration>
<gradleEnterprise xmlns="https://www.gradle.com/gradle-enterprise-maven-project">
<normalization>
<runtimeClassPath>
<ignoredFiles>
<ignoredFile>META-INF/build.properties</ignoredFile>
</ignoredFiles>
<propertiesNormalizations>
<propertiesNormalization>
<path>com/example/**/build.properties</path>
<ignoredProperties>
<ignore>build.timestamp</ignore>
</ignoredProperties>
</propertiesNormalization>
</propertiesNormalizations>
<metaInf>
<ignoreManifest>true</ignoreManifest>
<ignoreCompletely>true</ignoreCompletely>
<ignoredAttributes>
<ignore>Implementation-Version</ignore>
</ignoredAttributes>
<ignoredProperties>
<ignore>app.version</ignore>
</ignoredProperties>
</metaInf>
</runtimeClassPath>
</normalization>
<plugins>
<!-- an example of adding more details to an already cacheable plugin -->
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<inputs>
<fileSets>
<fileSet>
<name>samples</name>
<paths>
<path>src/test/samples</path>
</paths>
<includes>
<include>**/*.sample</include>
</includes>
<excludes>
<exclude>archive/**/*.sample</exclude>
</excludes>
<normalization>NAME_ONLY</normalization>
</fileSet>
<fileSet>
<name>config</name>
<paths>
<path>src/main/config</path>
</paths>
<normalization>
<strategy>RELATIVE_PATH</strategy>
<ignoreEmptyDirectories>true</ignoreEmptyDirectories>
<ignoreLineEndings>true</ignoreLineEndings>
</normalization>
</fileSet>
</fileSets>
</inputs>
<outputs>
<files>
<file>
<name>summary</name>
<path>target/test-results/summary.txt</path>
</file>
</files>
<directories>
<directory>
<name>screenshots</name>
<path>target/test-results/screenshots</path>
</directory>
</directories>
<notCacheableBecause>these tests verify integration with other systems and should rerun even if our
inputs didn't change
</notCacheableBecause>
</outputs>
<localState>
<fileSets>
<fileSet>
<name>someTemporaryStuff</name>
<paths>
<path>target/myTestFramework/tmp</path>
</paths>
</fileSet>
</fileSets>
</localState>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<inputs>
<!-- same as above -->
</inputs>
<outputs>
<!-- same as above -->
</outputs>
<localState>
<!-- same as above -->
</localState>
</execution>
</executions>
</plugin>
<!-- an example of making a custom plugin cacheable -->
<plugin>
<groupId>my.company</groupId>
<artifactId>awesome-but-slow-plugin</artifactId>
<inputs>
<fileSets>
<fileSet>
<name>sources</name>
<includesProperty>includes</includesProperty>
<excludesProperty>excludes</excludesProperty>
</fileSet>
</fileSets>
<properties>
<property>
<name>encoding</name>
</property>
</properties>
<ignoredProperties>
<ignore>logWarnings</ignore>
</ignoredProperties>
</inputs>
<nestedProperties>
<property>
<name>forkOptions</name>
<inputs>
<properties>
<property>
<name>maxHeap</name>
</property>
</properties>
</inputs>
</property>
</nestedProperties>
<iteratedProperties>
<property>
<name>targetPlatforms</name>
<inputs>
<properties>
<property>
<name>architecture</name>
</property>
<property>
<name>linkingMode</name>
</property>
</properties>
</inputs>
</property>
</iteratedProperties>
<outputs>
<directories>
<directory>
<name>outputDir</name>
</directory>
</directories>
<cacheableBecause>this plugin has CPU-bound goals with well-defined inputs and outputs</cacheableBecause>
</outputs>
<localState>
<fileSets>
<fileSet>
<name>tempDir</name>
</fileSet>
</fileSets>
</localState>
</plugin>
</plugins>
<buildScan>
<tags>
<tag>my tag</tag>
</tags>
<links>
<link>
<name>my link</name>
<url>http://my-site.com</url>
</link>
</links>
<values>
<value>
<name>Build Number</name>
<value>${project.buildNumber}</value>
</value>
</values>
</buildScan>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Programmatic configuration
In order to access the Develocity Maven extension API to perform programmatic configuration of Build Scans and the Build Cache you need to create a Maven extension. The Common Custom User Data Maven Extension provided by Gradle Inc. provides an example. This extension can be applied directly to your project, or can serve as a template project for your own extension implementation.
Please see the API reference for more details.
Appendix B: Captured information
The Develocity Maven extension captures information while the build is running and transmits it to a server after the build has completed.
Most of the information captured can be considered to be build data. This includes the name of the projects in your build, the executed goals, plugins and other things of this nature. Some more general environmental information is also captured. This includes your Java version, operating system, hardware, country, timezone and other things of this nature.
Notably, the actual source code being built and the output artifacts are not captured. However, error messages emitted by compilers or errors in tests may reveal aspects of the source code.
Listing
The list below details the notable information captured by the Develocity Maven extension and transmitted in a Build Scan.
-
Environment
-
User home (system property
'user.home'
) -
Maven home (system property
'maven.home'
) -
Username (system property
'user.name'
) (Can be obfuscated) -
Local hostname (environment variable
'COMPUTERNAME'
/'HOSTNAME'
) (Can be obfuscated) -
Public hostname (Can be obfuscated)
-
Local IP addresses (Can be obfuscated)
-
-
Build
-
Build invocation options (e.g. requested phases and goals, switches)
-
Build console output
-
Build failure exception messages and stacktraces
-
Build Cache configuration
-
Background Build Scan publication
-
Maven Build Cache extension cache report
-
Access
Build Scans published to a Develocity installation are viewable by all users that can reach the server and have the required roles, should Identity Access Management (IAM) be turned on. Develocity provides a search interface for discovering and finding individual Build Scans.
Build Scans published to scans.gradle.com are viewable by anyone with the link assigned when publishing the Build Scan. Links to individual Build Scans are not discoverable and cannot be guessed, but may be shared.
Appendix C: Cacheable plugins and goals
The extension caches the following plugins and goals out of the box. Unless otherwise noted, all their parameters are tracked as part of the cache key.
More build cache configurations for additional Maven plugins, which are not supported out of the box by Develocity, can be viewed here.
maven-compiler-plugin
Supported versions: 3.1 and above
Supported goals:
-
compile
-
testCompile
Caching is automatically disabled if:
-
a non-javac toolchain is used
The following use cases currently require disabling the Build Cache for this plugin:
-
using annotation processors that read files outside of Maven’s resource directories
-
using annotation processors that generate sources outside of Maven’s generated sources directory
-
using any non-deterministic annotation processors
Compile avoidance
Unless there are annotation processors on the classpath, the extension uses compile avoidance so your sources are only recompiled if the signatures of the classes on the compile classpath have changed.
maven-surefire-plugin and maven-failsafe-plugin
Supported versions: 2.12.4 and above for Build Cache, 2.15 (except for 2.19 to 2.20.1) and above for Build Scans, 2.22.2 and above for Test Distribution and Predictive Test Selection.
Supported goals:
-
surefire:test
-
failsafe:integration-test
Caching is automatically disabled if:
-
<debugForkedProcess>
is true -
<workingDirectory>
is changed to something different from the project’s root dir
Test results for surefire:test are stored in the Build Cache whenever the goal succeeds. Thus, by default, only successful or skipped test results are cached. However, if <testFailureIgnore> is set to true , test failures are cached as well. |
The following use cases currently require disabling the Build Cache for these plugins:
-
non-deterministic tests (e.g. tests with random parameters)
-
tests that read files that are not on the test classpath (e.g.
new File("src/test/samples")
) -
tests that write additional results that you absolutely need (e.g. screenshots for failed UI tests)
-
tests that read environment variables that are not explicitly declared using the
<environmentVariables>
property -
tests that use Java agents that read additional inputs or create additional outputs, except for JaCoCo, which is explicitly supported
The following properties are deliberately not tracked as inputs, because they should not influence the test result:
-
all concurrency settings, e.g.
<threadCount>
-
user properties (passed via
-D
to Maven) that are not declared in the goal configuration using<systemPropertyVariables>
,<systemProperties>
, or<argLine>
.
If a user property (e.g. -Dmy.custom.property=someValue
) influences the outcome or behavior of tests, it should be tracked as an input by declaring it explicitly:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<my.custom.property>${my.custom.property}</my.custom.property>
</systemPropertyVariables>
</configuration>
</plugin>
jacoco-maven-plugin
Supported versions: 0.5 and above
Supported goals:
-
none of JaCoCo’s own goals are cached
-
surefire and failsafe remain cacheable when JaCoCo is used
The JaCoCo plugin hooks into surefire and failsafe as a Java agent, or can preemptively instrument classes when used in 'offline' mode. The extension automatically tracks all JaCoCo agent options (and the jacoco-agent.destfile
system property for Maven extension 1.16.2+), when determining the cache key for surefire and failsafe tests. The JaCoCo execution data file is cached as an additional output of the test execution.
Caching is automatically disabled if:
-
<append>
is true
To allow tests to be cached while using JaCoCo, have each surefire/failsafe execution write to a separate data file and use a jacoco:merge
or jacoco:report-aggregate
goal to create a merged data file or an aggregated report.
maven-jaxb2-plugin/jaxb-maven-plugin (org.jvnet.jaxb2.maven2/org.jvnet.jaxb)
Supported plugin artifact ids:
-
maven-jaxb2-plugin
-
maven-jaxb20-plugin
-
maven-jaxb21-plugin
-
maven-jaxb22-plugin
-
maven-jaxb23-plugin
-
jaxb-maven-plugin
Supported versions: 0.12.3 and above
Supported goals:
-
generate
Caching is automatically disabled if:
-
a non-local URL is used to declare a catalog, schema, or binding
The following use cases currently require disabling the Build Cache for these plugins:
-
non-local URL references to schemas or bindings with changing content from within schema or binding files
The following properties are deliberately not tracked as inputs, because they should not influence the result of code generation:
-
logging settings (
verbose
) -
proxy settings (
proxyHost
,proxyPort
,proxyUsername
,proxyPassword
,useActiveProxyAsHttpproxy
) -
settings for the plugin’s up-to-date check and incremental build feature (
forceRegenerate
,removeOldOutput
,produces
,cleanPackageDirectories
)
maven-javadoc-plugin
Supported versions: 2.7 and above
Supported goals:
-
javadoc:javadoc
-
javadoc:javadoc-no-fork
-
javadoc:test-javadoc
-
javadoc:test-javadoc-no-fork
-
javadoc:jar
-
javadoc:test-jar
Caching is automatically disabled if:
-
<skip>
is true
The following properties are deliberately not tracked as inputs, because they should not influence the javadoc output:
maven-checkstyle-plugin
Supported versions: 2.14 and above
Supported goals:
-
check
-
checkstyle
-
checkstyle-aggregate
Caching is automatically disabled if:
-
<skip>
is true
The following properties are deliberately not tracked as inputs, because they do not influence the outcome of the goal:
Absolute paths in output files are ignored
Checkstyle’s output files contain absolute paths that are deliberately ignored by the extension. Thus, when loading the goal’s outputs from cache, the referenced paths might not exist on the machine that is executing the build. In case that’s problematic for you, please disable the Build Cache for this goal. |
Appendix D: Anatomy of the .develocity directory
By default, the Develocity Maven extension stores temporary data in the ${user.home}/.m2/.develocity
directory. If you want to customize this location, use one of the following options:
gradleEnterprise.setStorageDirectory(java.nio.file.Paths.get("/path/to/new/storage/directory"));
$ mvn clean verify -Dgradle.enterprise.storage.directory=path/to/new/storage/directory
<gradleEnterprise>
<storageDirectory>/path/to/new/storage/directory</storageDirectory>
</gradleEnterprise>
The directory may contain the following subdirectories:
- build-cache
-
Location of the local Build Cache
- build-cache-tmp
-
Temporary directory for loading and storing entries in the remote Build Cache in case the local Build Cache is disabled
- build-scan-data
-
Data collected to create a Build Scan
- fingerprint-cache
-
Location of the local fingerprint cache
- token-cache
-
Location of cached entitlement tokens
The |
Appendix E: Release history
Please refer to the Develocity Maven Extension User Manual for the release history starting with version 1.21. |
1.20.1
-
[NEW] Build Cache: Add support for the
maven-javadoc-plugin
version3.6.3
-
[NEW] Build Cache: Add support for the
jaxb-maven-plugin
version4.0.2
-
[FIX] The Maven extension does not ignore
.mvn/.gradle-enterprise
folder by default when generating a project viainit
goal
Compatible with scans.gradle.com and Develocity 2023.4 or later.
1.20
-
[NEW] Build Cache: Add support for
mojoExecution
property in an upcoming version ofmaven-javadoc-plugin
-
[NEW] Build Cache: Add support for
outputTimestamp
property in an upcoming version ofmaven-compiler-plugin
-
[NEW] Predictive Test Selection: Selection profile can be configured via new
pts.profile
system property -
[NEW] Test Distribution/Predictive Test Selection: Add support for develocity-testing-annotations version 2.0
-
[NEW] Test Distribution/Predictive Test Selection: Fall back to regular execution if
fallbackToRegularExecutionOnMissingJUnitPlatform
POM configuration property or system property is set and JUnit Platform is not available -
[FIX] Build Scan: Test event capturing fails if TestNG
@DataProvider
creates arguments with failingtoString
method in framework versions 6.x -
[FIX] Build Cache: Develocity Maven extension might store corrupt build cache entries if the
clean
goal is not executed first -
[FIX] Test Distribution: Retry filters are not respected if tests are configured to be retried in a new JVM
-
[FIX] Test Distribution/Predictive Test Selection: JUnit’s parallel execution configuration is not respected if a single test executor is used
Compatible with scans.gradle.com and Develocity 2023.4 or later.
1.19.3
-
[NEW] Predictive Test Selection: Selection profile can be configured via new
pts.profile
system property -
[FIX] Build Scan: Test data cannot be captured if TestNG test method is invoked multiple times on different threads
-
[FIX] Build Scan: Intermittent concurrency issue capturing test events in builds using many threads
-
[FIX] Test Distribution/Predictive Test Selection: JUnit’s parallel execution configuration is not respected if a single test executor is used
Compatible with scans.gradle.com and Develocity 2023.3 or later.
1.19.2
-
[NEW] Build Cache: Add support for
maven-javadoc-plugin
3.6.0 -
[NEW] Build Cache: Add support for
jaxb-maven-plugin
3.0.0 -
[NEW] Predictive Test Selection: Add
pts.enabled
system property to enable / disable PTS
Compatible with scans.gradle.com and Develocity 2023.3 or later.
1.19.1
-
[FIX] Extension is not applied to builds run by IntelliJ IDEA Maven Embedder
-
[FIX] Build Cache: Failsafe test results are cached when JVM terminates
-
[FIX] Build Cache: Failsafe test results are cached when tests are timed out
Compatible with scans.gradle.com and Develocity 2023.3 or later.
1.19
-
[NEW] Add
help
goal which provides details on the custom goals of the extension -
[NEW] Add
init
goal to ease applying and configuring the extension on a Maven project -
[NEW] Add support for project level access control
-
[NEW] Build Cache: Add support for
legacyMode
property in an upcoming version ofmaven-javadoc-plugin
-
[FIX] Test Distribution: The duration of output file transfers sometimes exceeds the duration of the executor assignment
-
[FIX] Test Distribution: Local executors are sometimes reported as released after the goal has finished
-
[FIX] Test Distribution/Predictive Test Selection: Automatic Java modules trigger execution on module path rather than classpath
Compatible with scans.gradle.com and Develocity 2023.3 or later.
1.18.4
-
[NEW] Build Scans: Improve management of Maven internal lifecycle components
-
[FIX] Improve resiliency of test output capturing when running tests with JUnit4
Compatible with scans.gradle.com and Gradle Enterprise 2023.2 or later.
1.18.3
-
[NEW] Build Cache: Introduce the option to turn off fingerprinting inputs Compatible with scans.gradle.com and Gradle Enterprise 2023.2 or later.
1.18.2
-
[NEW] Build Cache: Improve error handling while fingerprinting inputs
Compatible with scans.gradle.com and Gradle Enterprise 2023.2 or later.
1.18.1
-
[NEW] Test Distribution/Predictive Test Selection: Add support for JUnit 5.10’s new test dry run mode
-
[FIX] Test Distribution: Local test executors are reported as released after test goal has finished
-
[FIX] Test Distribution: Finish event for test execution rarely has older timestamp than its start event
-
[FIX] Test Distribution: Re-scheduled tests are reported after the test executor has been released
Compatible with scans.gradle.com and Develocity 2023.2 or later.
1.18
-
[NEW] Build Cache: Avoid trying to upload too-large cache entries to built-in and remote Build Cache nodes
-
[NEW] Build Cache: Add support for normalizing system properties
-
[NEW] Build Cache: Add support for
annotationProcessorPathsUseDepMgmt
property inmaven-compiler-plugin
-
[NEW] Build Cache: Add support for
additionalClasspathDependencies
property in an upcoming version ofmaven-surefire-plugin
-
[NEW] Test Distribution: Capture configuration and runtime insights in Build Scans
-
[NEW] Predictive Test Selection: Introduce mode to run remaining tests, i.e. tests that haven’t been executed for the same inputs
-
[NEW] Predictive Test Selection: Introduce selection profiles (conservative/standard/fast) to influence how many tests are selected
-
[FIX] Build Cache: Misconfiguration of goal execution cacheability is not surfaced
-
[FIX] Build Cache: Incorrect display of cacheability reason for system properties
-
[FIX] Build Cache:
NullPointerException
when outputname
is not configured -
[FIX] Test Distribution: JaCoCo coverage output transfer from agents for builds running on Windows
-
[FIX] Predictive Test Selection: Selection requests failing due to sporadic network issues are not retried
Compatible with scans.gradle.com and Develocity 2023.2 or later.
1.17.4
-
[NEW] Build Cache: Compatibility with the
jaxb-maven-plugin
version2.0.2
-
[FIX] Test Distribution/Predictive Test Selection: Test Discovery results with failures are incorrectly cached
-
[FIX] Test Distribution/Predictive Test Selection: Timeout for awaiting response from Develocity is too short when under heavy load
-
[FIX] Predictive Test Selection/Test Retry: Confusing failure message when tests could not be retried
Compatible with scans.gradle.com and Develocity 2023.1 or later.
1.17.3
-
[NEW] Build Cache: Add support for
excludeGeneratedSources
property in an upcoming version ofmaven-checkstyle-plugin
-
[FIX] Build Scan: Classpath conflict when capturing tests for custom Maven extensions
-
[FIX] Build Scan: Failures when capturing test events when using priorities or running test in parallel for TestNG
-
[FIX] Build Cache: Misleading error message for untracked system properties in surefire goals
-
[FIX] Build Cache: Maven Checkstyle plugin comma-separated includes and excludes are not supported
-
[FIX] Test Distribution/Predictive Test Selection: Configuration failure for Surefire/Failsafe goals on Maven 3.9.3 and later
Compatible with scans.gradle.com and Develocity 2023.1 or later.
1.17.2
-
[FIX] Build Scan: Test capturing of JUnit 4 Parameterized test classes executed concurrently in the same JVM
Compatible with scans.gradle.com and Develocity 2023.1 or later.
1.17.1
-
[FIX] Test Distribution: Build fails for TestNG test classes with
@AfterClass
methods belonging to different suites -
[FIX] Test Distribution: Upload of input files with very long names sporadically fails
-
[FIX] Predictive Test Selection: Changed must-run configuration not applied when rerunning test goal
Compatible with scans.gradle.com and Develocity 2023.1 or later.
1.17
-
[FIX] Test Distribution/Predictive Test Selection: Missing implicit injection of JUnit Jupiter or Vintage engine when missing from test runtime classpath
Compatible with scans.gradle.com and Develocity 2023.1 or later.
1.16.6
-
[FIX] Build Scan: Dynamically added projects are not captured when discovered during dependency resolution
-
[FIX] Build Scan:
javax.net.ssl.*
properties are not forwarded to the background upload process -
[FIX] Build Cache: incorrect server address may yield “Invalid cookie header” warning in build logs
-
[FIX] Test Distribution: classpath conflict with Apache commons-lang and commons-io
Compatible with scans.gradle.com and Develocity 2022.4 or later.
1.16.5
-
[FIX] Build Cache: Compile avoidance warning is shown when build cache is disabled
-
[FIX] Test Distribution: Build fails if remote executors are preferred but getting an agent estimation from Develocity times out
Compatible with scans.gradle.com and Develocity 2022.4 or later.
1.16.4
-
[NEW] Build Cache: Compatibility with the
maven-enforcer-plugin
version3.2.1
-
[NEW] Build Cache: Add support for
useModulePath
property added inmaven-compiler-plugin
version3.11.0
Compatible with scans.gradle.com and Develocity 2022.4 or later.
1.16.3
-
[FIX] Build Scan: Wrong extension application type attribution when passing multiple extensions via the
maven.ext.class.path
system property -
[FIX] Build Scan: Develocity server URL is not honoured when using the
build-scan-publish-previous
goal -
[FIX] Build Scan: Build fails when applying Maven Build Cache extension
-
[FIX] Build Scan: Build fails for TestNG
@Factory
test class used in combination with@DataProvider
-
[FIX] Build Scan: Sporadic processing errors of tests retried in a single forked JVM
Compatible with scans.gradle.com and Develocity 2022.4 or later.
1.16.2
-
[NEW] Build Cache: Automatically track the JaCoCo
jacoco-agent.destfile
system property as an output -
[NEW] Build Cache: Automatically mark a goal execution as not cacheable if the JaCoCo
jacoco-agent.append
system property is present and set totrue
-
[NEW] Test Distribution: Do not wait for remote executors when
remoteExecutionPreferred=true
but no Develocity server is configured -
[FIX] Test Distribution: Unnecessary connection attempts to Develocity server despite Test Distribution being disabled
Compatible with scans.gradle.com and Develocity 2022.4 or later.
1.16.1
-
[NEW] Local build caching for Maven no longer requires authorization from the Develocity server
-
[FIX]
GradleEnterpriseListener
components are not discovered under certain circumstances -
[FIX] Apache RAT Maven plugin fails the build due to Develocity internal files
Compatible with scans.gradle.com and Develocity 2022.4 or later.
1.16
-
[NEW] Add built-in support for develocity-testing-annotations
-
[NEW] Add automatic discovery of the
com.gradle
plugin group, for plugin prefix resolutions -
[NEW] Build Scan: Use reported
displayName
, e.g. Jupiter’s@DisplayName
, instead of the method name as test name for tests run via JUnit Platform or Test Distribution -
[NEW] Build Scan: Add
build-scan-publish-previous
goal to publish a Build Scan for the last executed build -
[NEW] Predictive Test Selection: Persists complete test results in cache
-
[NEW] Predictive Test Selection: Test discovery results are cached locally
-
[FIX] Extensions passed as relative path to the
maven.ext.class.path
system property are not properly attributed to theMAVEN_EXT_CLASSPATH
application type -
[FIX] Access key defined in Develocity XML configuration is not taken into account for remote build cache authentication
-
[FIX] Predictive Test Selection: Fails with a misleading "internal error" if test task input files could not be determined
Compatible with scans.gradle.com and Develocity 2022.4 or later.
1.15.5
-
[NEW] Test Distribution: Retry file upload on content digest mismatch
-
[FIX] Predictive Test Selection: Handling of multiple unique IDs per fully-qualified test class name
Compatible with scans.gradle.com and Develocity 2022.3 or later.
1.15.4
-
[NEW] Build Scan: Ignore missing file input roots
-
[NEW] Test Distribution: Delete remaining files in temporary workspaces on remote agents in case of failures
-
[NEW] Test Distribution: Use
gradle-enterprise-maven-extension/<version>
asUser-Agent
for HTTP requests -
[NEW] Test Distribution/Predictive Test Selection: Detect and fail for unsupported test engines
-
[FIX] Test Distribution: Concurrency issue causing Surefire/Failsafe goals to fail with
CancellationException
-
[FIX] Test Distribution: Log misleading ClassNotFoundException message on Test Distribution agents when stopping worker while session is being opened
-
[FIX] Test Distribution: Write to temporary workspaces after worker on Test Distribution agents was asked to stop
Compatible with scans.gradle.com and Develocity 2022.3 or later.
1.15.3
-
[FIX] Predictive Test Selection: Remove misleading warning when running with
-Dscan
without having<publish>ALWAYS</publish>
configured
Compatible with scans.gradle.com and Develocity 2022.3 or later.
1.15.2
-
[NEW] Build Cache: Add support for
showCompilationChanges
property inmaven-compiler-plugin
-
[NEW] Build Cache: Add support for
maven-checkstyle-plugin
3.2.0
Compatible with scans.gradle.com and Develocity 2022.3 or later.
1.15.1
-
[FIX] Predictive Test Selection: Handle projects non-local root POMs
Compatible with scans.gradle.com and Develocity 2022.3 or later.
1.15
-
[NEW] Build Scan: Capture the value of
storeEnabled
goal configuration property -
[NEW] Build Scan: Capture the location of the Maven home directory
-
[NEW] Build Scan: Capture Maven extensions applied to the build
-
[NEW] Build Cache: Allow configuring inputs and outputs of Maven goals via
BuildCacheApi
-
[NEW] Build Cache: Allow configuring runtime classpath normalization via
BuildCacheApi
-
[NEW] Build Cache: Allow skipping Maven executions if the given
skipIfTrue
property is set -
[NEW] Test Distribution: Added configuration option to restrict the number of partitions for remote session to reduce the impact of disconnects
-
[NEW] Test Distribution: Added option to restrict where a test can be executed (
localOnly
,remoteOnly
) -
[FIX] Build Scan: Builds with dynamically added projects during build time are supported
-
[FIX] Build Scan: Enhance showing minimum supported plugin version for non cacheable goals for very old plugin versions
-
[FIX] Build Scan: Message is printed when
publishIfAuthenticated
is set and build does not publish a Build Scan -
[FIX] Build Scan: Enhance resiliency on errors during
ExecutionListener
callbacks -
[FIX] Build Scan: Regenerate malformed workspace IDs
-
[FIX] Build Cache:
null
Mojo arguments values do not break cacheability
Compatible with scans.gradle.com and Develocity 2022.3 or later.
1.14.4
-
[NEW] Test Distribution: Added configuration option to restrict the number of partitions for remote session to reduce the impact of disconnects
-
[FIX] Build Scan: Enhance showing minimum supported plugin version for non cacheable goals for very old plugin versions
-
[FIX] Build Scan: Improved warning message when a Build Scan can’t be published
-
[FIX] Build Scan: Builds with dynamically added projects during build time are supported
Compatible with scans.gradle.com and Develocity 2022.2 or later.
1.14.3
-
[NEW] Add goal/execution specific
storeEnabled
flag to not store build cache outputs -
[FIX] Multiple application of extension via
-Dmaven.ext.class.path
system property may cause internal errors -
[FIX] Predictive Test Selection: Test classes with multiple test IDs no longer cause internal errors
Compatible with scans.gradle.com and Develocity 2022.2 or later.
1.14.2
-
[NEW] Allow setting more configuration options via system properties (e.g.
gradle.enterprise.allowUntrustedServer
)
Compatible with scans.gradle.com and Develocity 2022.2 or later.
1.14.1
-
[NEW] Test Distribution: Add content digest header for uploaded files to ensure integrity
-
[FIX] Build Scan: Disable test capturing when using maven-surefire-plugin/maven-failsafe-plugin versions 2.19 to 2.20.1 due to a bug that was fixed in 2.21.0 and emit a corresponding warning
-
[FIX] Build Scan: Fix capturing of out of bound logs written by goal executions
-
[FIX] Build Scan: Events may be captured out of order under certain circumstances
-
[FIX] Build Scan: Incorrect message is displayed when applying the Develocity Maven extension from several locations
-
[FIX] Test Distribution/Predictive Test Selection: Resolve classpath conflicts when a project has runtime JUnit Platform dependencies
-
[FIX] Predictive Test Selection: Avoid failing test goals with configured include/exclude filters if no tests were selected
-
[FIX] Predictive Test Selection: Fix sporadic inaccuracy of estimated durations of not selected tests by a few milliseconds
Compatible with scans.gradle.com and Develocity 2022.2 or later.
1.14
-
[NEW] Build Cache: Introduce read-only mode for non-clean builds
-
[NEW] Predictive Test Selection: Add test selection support
-
[FIX] Build Cache: Allow reusing cache entries regardless of the JVM used to run Maven. Previously, the vendor and major version were part of every goal’s cache key. Now, only the major version of the JVM is taken into account for compile and test goals.
Compatible with scans.gradle.com and Develocity 2022.2 or later.
1.13.1
-
Build Cache: Fix fingerprint cache issue resulting in false-positive cache hits
-
Build Cache: Add support for
implicit
property inmaven-compiler-plugin
3.10.2 -
Test Distribution: Make WebSocket ping interval configurable via internal system property
Compatible with scans.gradle.com and Develocity 2022.1 or later.
1.13
-
Build Scan: Paths in a Build Scan have the user home directory normalized.
-
Build Scan: Capture whether
rerunGoals
system property is set. -
Build Cache: Accessing the remote build cache now follows redirects automatically and enforces usage of HTTPS by default (see Allowing insecure protocols if you need to continue using HTTP).
-
Build Cache: Fingerprints of external dependencies are no longer stored in the Build Cache by default (see Using the Build Cache to store fingerprints of external dependencies for use cases and instructions for re-enabling this behavior).
-
Build Cache: Add support for
enablePreview
property inmaven-compiler-plugin
3.10.1.
Compatible with scans.gradle.com and Develocity 2022.1 or later.
1.12.4
-
Build Cache: add support for
createMissingPackageInfoClass
anddebugFileName
properties inmaven-compiler-plugin
3.10.0
Compatible with scans.gradle.com and Develocity 2021.4 or later.
1.12.3
-
Build Scan: Properly handle errors within goal fingerprinting
-
Build Cache: Allow configuring
useExpectContinue
viaBuildCacheApi
-
Build Cache: Update Spring from 5.3.12 to 5.3.15 to avoid false reports of CVE-2021-22060 vulnerability
Compatible with scans.gradle.com and Develocity 2021.4 or later.
1.12.2
-
Build Scan: Fix memory leak when running tests in a forked VM
Compatible with scans.gradle.com and Develocity 2021.4 or later.
1.12.1
-
Build Scan: Improve error handling around user callbacks
-
Build Scan: Improve SOCKS proxy server support
Compatible with scans.gradle.com and Develocity 2021.4 or later.
1.12
-
Build Scan: Do not capture information about irrelevant empty directories
-
Build Scan: Capture directory sensitivity and line-ending sensitivity of goal file inputs
-
Build Scan: Protect against uncaught Maven errors
-
Build Cache: Add opt-in support for using HTTP Expect-Continue when uploading entries to the remote Build Cache
-
Test Distribution: Avoid waiting on remote executors when all tests have already been finished
Compatible with scans.gradle.com and Develocity 2021.4 or later.
1.11.1
-
Fix potential out-of-order Maven events in case of a skipped project, when using Develocity 2021.2.3+
-
Fail hard if Develocity Maven extension is applied via copying the jar in
<maven-home>/lib
-
Build Scan: Properly capture OS name and version for macOS 11+
-
Test Distribution: Fix retry behavior for Spock 2 Stepwise test classes
Compatible with scans.gradle.com and Develocity 2021.3 or later.
1.11
-
Programmatically access the
GradleEnterpriseApi
with a customGradleEnterpriseListener
implementation -
Allow configuring access key via
GradleEnterpriseApi
andgradle-enterprise.xml
-
Fix build/test output capturing when empty byte arrays are written to
System.out
/System.err
-
Build Scan: Allow opt-out from build and test log capturing
-
Build Scan: Avoid capturing identical tags
-
Build Scan: Fix potential out-of-order event stream with Maven tests
-
Build Scan: Allow capturing links up until 100,000 characters
-
Build Cache: Add support for line ending normalization
-
Test Distribution: Add support for JDK 16 and above without having to specify
--add-opens
JVM arguments -
Test Distribution: Validate
waitTimeoutInSeconds
to be positive -
Test Distribution: Only warn about unsupported properties if they are configured
-
Test Distribution: Improve error message when forked test JVM terminates unexpectedly
Compatible with scans.gradle.com and Develocity 2021.3 or later.
1.10.5
-
Build Cache: Prevent incomplete Build Cache entries in rare concurrent build scenarios
-
Build Cache: Improve failure message when Maven is invoked with an invalid configuration
Compatible with scans.gradle.com and Develocity 2021.2 or later.
1.10.4
-
Test Distribution: Capture logging as test output when logging frameworks are initialized before test execution
Compatible with scans.gradle.com and Develocity 2021.2 or later.
1.10.3
-
Allow configuring storage directory via
gradle-enterprise.xml
-
Allow configuring
requireClean
viaBuildCacheApi
-
Allow disabling the extension via
gradle-enterprise.xml
,GradleEnterpriseApi
, orgradle.enterprise.enabled
system property
Compatible with scans.gradle.com and Develocity 2021.2 or later.
1.10.2
-
Build Scan: Snapshot dependency artifact resolutions of
maven-metadata.xml
artifacts are properly captured -
Build Scan: Out of bound test output events are not captured
-
Build Scan: Also use programmatically configured storage directory (introduced in
1.10.1
) for temporary files
Compatible with scans.gradle.com and Develocity 2021.2 or later.
1.10.1
-
Build Scan: Introduce new
GradleEnterpriseApi
-
Build Scan: Restore support for custom locales (e.g.
tr-TR
) -
Test Distribution: JUnit Platform artifacts on the test runtime classpath/module path take precedence over those included in the extension
-
Test Distribution: Merge JaCoCo coverage data when using a single remote executor along with local executors
Compatible with scans.gradle.com and Develocity 2021.2 or later.
1.10
-
Build Scan: Capture test output
-
Build Scan: Read user input without requiring the Plexus Interactivity dependency
-
Test Distribution: Support Java Platform Module System (JPMS)
-
Test Distribution: Time out and retry when upgrading a connection to WebSockets hangs
-
Test Distribution: Exclude environment variables configured in the
excludedEnvironmentVariables
Surefire/Failsafe parameter when forking local test JVMs -
Test Distribution: Agents are released on agent shutdown once the current partition is finished
Compatible with scans.gradle.com and Develocity 2021.2 or later.
1.9.2
-
Build Cache: Add support for
xrefTestLocation
property in maven-checkstyle-plugin 3.2.0 -
Build Cache: Add support for
dependencyLinks
andaddStylesheets
properties in maven-javadoc-plugin 3.3.0 -
Test Distribution: Fix cross-OS path mapping to cope with a broader range of inputs
-
Test Distribution: Reuse temporary workspace on test distribution agents across sessions when
reuseForks
isfalse
-
Test Distribution/Build Cache: Add support for
includeJUnit5Engines
andexcludeJUnit5Engines
property in maven-surefire-plugin and maven-failsafe-plugin 3.0.0-M6
Compatible with scans.gradle.com and Develocity 2021.1 or later.
1.9.1
-
Build Scan: Reduced memory usage when capturing goal input files
-
Build Scan: Fixed rare case of duplicated dependencies capturing
-
Build Scan: Fixed captured exception messages in some cases
-
Test Distribution: Fixed potentially hanging build when agents disconnect before starting test execution
-
Test Distribution: Compatibility with JDK 16 without having to configure
<argLine>
-
Test Distribution: Improved reporting of unrecoverable failures that occurred on Test Distribution agents
-
Test Distribution: Fixed interoperability issue when using Test Distribution agents running on Linux from builds running on Windows
-
Test Distribution: Fixed reporting of output emitted during startup of forked JVMs on Test Distribution agents
-
Test Distribution/Build Scan: Fixed reporting of tests that were in progress when a forked JVM crashed to be listed as "skipped"
Compatible with scans.gradle.com and Develocity 2021.1 or later.
1.9
-
Build Scan: add Maven dependency resolution capturing
-
Build Scan/Test Distribution: the
GRADLE_ENTERPRISE_ACCESS_KEY
environment variable allows specifying the access keys for multiple hosts -
Build Cache: stricter validation of the Develocity pom.xml configuration
-
Test Distribution: improve test scheduling by creating smaller partitions
-
Test Distribution: add support for once-per-JVM setup/teardown behavior via implementations of
LauncherSessionListener
introduced in JUnit 5.8.0-M1 -
Test Distribution: optimize local execution of single test classes
-
Test Distribution: configuring
maxLocalExecutors
takes precedence overforkCount
-
Reduced memory usage for builds with lots of input files
Compatible with scans.gradle.com and Develocity 2021.1 or later.
1.8.3
-
Fix resource leakage when used from IntelliJ IDEA
-
Properly disambiguate parameterized TestNG tests
-
Add support for
failOnFlakeCount
property in maven-surefire-plugin 3.0.0-M6
Compatible with scans.gradle.com and Develocity 2020.5 or later.
1.8.2
-
Missing source roots are treated like empty source roots in Build Scan comparisons
-
Warnings are logged for unsupported Surefire/Failsafe config parameters even when explicitly set to their default value when Test Distribution is enabled
-
Test Distribution output file archives are sanity checked before unpacking to ensure only regular files and directories are created inside the target directory (CVE-2021-26719)
-
Temporary Test Distribution output files are stored in
target/test-distribution-outputs
instead of directly intest-distribution-outputs
in the project’s base directory
Compatible with scans.gradle.com and Develocity 2020.5 or later.
1.8.1
-
Test goals without test classes no longer fail if Test Distribution is enabled without JUnit Platform test engine on the classpath
-
Potential deadlock when Test Distribution broker connection is lost while tests are being executed is now avoided
-
Output of JVM which discovers / executes tests is printed in case it exits with non-zero exit code
-
Failed attempts to read from or write to the fingerprint cache are now logged as errors but no longer cause the build to fail
-
Fix sporadic
ArithmeticException
when reconnecting to the Develocity server for Test Distribution -
File uploads with non-retryable failures now cause test goals to fail instead of making the build hang
-
Fix file path normalization to properly capture file roots (e.g. workspace, local Maven repository)
Compatible with scans.gradle.com and Develocity 2020.5 or later.
1.8
-
Added support for Test Distribution
-
Build Cache now supports normalization of MANIFEST and properties files
-
Build Cache now ignores empty directories being added or removed to the source tree when calculating cache keys for the maven-compiler-plugin and maven-checkstyle-plugin
-
The <normalization> element in the POM DSL now provides a way to specify that empty directories should be ignored during Build Cache key calculation
-
Tests with failed assumptions in @BeforeAll methods are now captured in Build Scans correctly
Compatible with scans.gradle.com and Develocity 2020.5 or later.
1.7.2
-
Track versions of JDK 15 and later correctly as input for code compilation, test execution, and Javadoc generation
-
Fix performance issue caused by querying the machine’s network interfaces for every goal execution
Compatible with scans.gradle.com and Develocity 2020.4 or later.
1.7.1
-
Fix race condition when using forked test VMs
Compatible with scans.gradle.com and Develocity 2020.4 or later.
1.7
-
Capture workspace directory project name as top level project name
-
Prevent build exception if using a Maven Surefire/Failsafe plugin < 2.12
-
Properly detect identical tests run by different forked VMs
-
Improve handling of invalid plugin cache configuration in Maven POM DSL
-
Set the content length header when provisioning access keys for improved compatibility with some load balancers
Compatible with scans.gradle.com and Develocity 2020.4 or later.
1.6.8
-
Correctly handle multiple occurrences of failed dependencies
Compatible with scans.gradle.com and Develocity 2020.3 or later.
1.6.7
-
Add support for
runOrderRandomSeed
property in maven-surefire-plugin and maven-failsafe-plugin 3.0.0-M6 -
Correctly handle multiple executions of the same Maven project
Compatible with scans.gradle.com and Develocity 2020.3 or later.
1.6.6
-
Properly link logs from sub-processes to the parent goal execution
-
Protect against unexpected failures during project execution
-
Fix error with Maven Build Cache when executing a goal early
Compatible with scans.gradle.com and Develocity 2020.3 or later.
1.6.5
-
Introduce
BuildCacheApi
to programmatically configure the Maven Build Cache
Compatible with scans.gradle.com and Develocity 2020.3 or later.
1.6.4
-
Fix Build Scans publishing from IntelliJ 2020.2+
Compatible with scans.gradle.com and Develocity 2020.3 or later.
1.6.3
-
Protect against potentially duplicated Maven
SessionStarted
execution event callback firing -
Support obfuscation of identifying data via
gradle-enterprise.xml
Compatible with scans.gradle.com and Develocity 2020.3 or later.
1.6.2
-
Fix test capturing when the JUnit Platform is called from within test code with a modified class loader
Compatible with scans.gradle.com and Develocity 2020.3 or later.
1.6.1
-
Fix project structure capturing for sub modules
-
Fix capturing of skipped test classes
-
Fix test capturing when the JUnit Platform is called from within test code
Compatible with scans.gradle.com and Develocity 2020.3 or later.
1.6
-
Capture if the Build Scan was uploaded in the background
-
Capture the full project structure when the build is run from a sub-module
-
Do not print test capturing warning for projects with empty test classes directory
-
Fix potential socket stream security vulnerability when capturing tests (CVE-2020-15777)
Compatible with scans.gradle.com and Develocity 2020.3 or later.
1.5.3
-
Build caching now supports custom
javac
executables configured for the maven-compiler-plugin
Compatible with scans.gradle.com and Develocity 2020.2 or later.
1.5.2
-
Maven Extension XML project XSD is fixed
-
Error when using
null
values in proxy configuration is fixed
Compatible with scans.gradle.com and Develocity 2020.2 or later.
1.5.1
-
Credentials for remote Build Cache can be specified via
gradle-enterprise.xml
-
Support usage of SpEL expressions in
gradle-enterprise.xml
-
Support supply of
gradle-enterprise.xml
via custom extension jar on the Maven classpath -
Race condition in Apache Commons Logging class instantiation is mitigated
-
Stale Build Scan files are cleaned up
Compatible with scans.gradle.com and Develocity 2020.2 or later.
1.5
-
Uploads Build Scans in the background after the build has finished
-
Add caching support for Surefire
forkNode
andjdkToolchain
properties
Compatible with scans.gradle.com and Develocity 2020.2 or later.
1.4.1
-
Fix capturing of unresolvable conflicts in Maven dependency graphs
Compatible with scans.gradle.com and Develocity 2020.1 or later.
1.4
-
Capture Maven dependencies in Build Scans
-
Fix test capturing when failure in class-level method happens under special conditions
Compatible with scans.gradle.com and Develocity 2020.1 or later.
1.3.6
-
Cache configuration declared using the POM DSL takes precedence over built-in configuration
Compatible with scans.gradle.com and Develocity 2019.4 or later.
1.3.5
-
Extension is deactivated automatically in incompatible IntelliJ IDEA versions
Compatible with scans.gradle.com and Develocity 2019.4 or later.
1.3.4
-
Add caching support for maven-javadoc-plugin 3.2.0
-
Add caching support for maven-checkstyle-plugin 3.1.1
-
Fix handling of compile source roots when loading outputs of the maven-compiler-plugin from cache
Compatible with scans.gradle.com and Develocity 2019.4 or later.
1.3.3
-
Build Cache does no longer store broken symbolic links
Compatible with scans.gradle.com and Develocity 2019.4 or later.
1.3.2
-
Test capturing is disabled when tests are executed with Java < 8
-
Improved help message when authentication is required for Build Scan publishing
-
Mitigation if slow local host name resolution on macOS
Compatible with scans.gradle.com and Develocity 2019.4 or later.
1.3.1
-
Users can provide obfuscation functions for captured username, local IP addresses and hostnames
-
String interpolation in Surefire
argLine
property is supported
Compatible with scans.gradle.com and Develocity 2019.4 or later.
1.3
-
Add support for authenticated Build Scans feature
-
Add support for maven-javadoc-plugin 3.2.0
-
Add support for maven-surefire-plugin and maven-failsafe-plugin 3.0.0-M4
-
Logs on debug level are not captured
-
Ignore additional Maven extension applications, when another instance is already applied
Compatible with scans.gradle.com and Develocity 2019.4 or later.
1.2.8
-
Global
gradle-enterprise.xml
is now read from${maven.home}/conf
in Maven < 3.5.0 -
Fixed hanging build due to race condition when an error during data capturing occurred
Compatible with scans.gradle.com and Develocity 2019.3 or later.
1.2.7
-
Extension behaves more lenient towards unusual embeddings of Maven
-
Goal cache key only contains the major Java version
Compatible with scans.gradle.com and Develocity 2019.3 or later.
1.2.6
-
Reduced runtime and memory allocation overhead of test capturing
Compatible with scans.gradle.com and Develocity 2019.3 or later.
1.2.5
-
Fixed project structure capturing when a goal is executed very early in the build
-
Fixed test capturing when a custom test provider is specified
Compatible with scans.gradle.com and Develocity 2019.3 or later.
1.2.4
-
Fixed test capturing when test started event cannot be found
-
Fixed test capturing when duplicate JUnit 4 Descriptions are found
Compatible with scans.gradle.com and Develocity 2019.3 or later.
1.2.3
-
Add
executeOnce
Maven Build Scan API -
Fixed concurrency issue in test capturing
-
Handle multi-threading and fail-fast scenarios for Maven < 3.6.2
-
Handling of Maven workspace ID is enhanced
Compatible with scans.gradle.com and Gradle Enterprise 2019.3 or later.
1.2.2
-
TestNG tests handle orphaned failure events
-
Fixed build hangs when failure occurred during test processing
-
Fixed exceptions in test capturing
Compatible with scans.gradle.com and Gradle Enterprise 2019.3 or later.
1.2.1
-
Support failing
@Before*
/@After*
annotations in all supported test frameworks -
Support failing TestNG
dependOnMethods
anddependsOnGroups
tests -
Don’t fail when
null
test method name or test class name is encountered -
Gradle Enterprise server set by configuration is now retrievable from the
BuildScanApi
Compatible with scans.gradle.com and Gradle Enterprise 2019.3 or later.
1.2
-
Capture tests executed in Surefire/Failsafe 2.15+ for JUnit 4/5 and TestNG frameworks
-
Capture console output
-
Add adjacent Build Scans support for Maven by capturing the workspace ID, unique per project workspace
-
Fixed origin Build Scan link when there is no reference to the output producing goal
-
Fixed project structure capturing when other extensions/plugins update the internal Maven projects
-
Fixed event serialization error when using custom tags/links/values via the
BuildScanApi
-
Enhanced the
BuildScanApi
:-
Register a background action
-
Register an action to be done as late as possible before publishing
-
Register an action to be done when a Build Scan is published
-
Set terms of use params programmatically
-
Set server programmatically
-
Set if untrusted servers are allowed programmatically
-
Specify the publication behaviour programmatically
-
Specify whether goal input files should be captured programmatically
-
Compatible with scans.gradle.com and Gradle Enterprise 2019.3 or later.
1.1.4
-
Undeclared inputs are reported correctly on Windows
-
Registering additional inputs/outputs works in the presence of mixed line separators
Compatible with scans.gradle.com and Gradle Enterprise 2019.2 or later.
1.1.3
-
Add support for upcoming
maven-surefire-plugin/maven-failsafe-plugin
version3.0.0-M4
-
Build flags capturing is not based on the
MAVEN_CMD_LINE_ARGS
environment variable anymore -
Add support for
mojo-executor
Maven plugin -
Failed
maven-failsafe
tests are no longer cached
Compatible with scans.gradle.com and Gradle Enterprise 2019.2 or later.
1.1.2
-
Fixed a bug which resulted in wrong event order caused by system clock adjustments
-
Fix handling of
**
in include patterns of supported goals and custom input declarations
Compatible with scans.gradle.com and Gradle Enterprise 2019.2 or later.
1.1.1
-
Read project-specific
gradle-enterprise.xml
from same.mvn
directory that Maven uses to readextensions.xml
Compatible with scans.gradle.com and Gradle Enterprise 2019.2 or later.
1.1
-
Output of
javadoc:aggregate
is cached for maven-javadoc-plugin:2.7+ -
Output of
javadoc:aggregate-jar
is cached for maven-javadoc-plugin:2.7+ -
Output of
javadoc:aggregate-no-fork
is cached for maven-javadoc-plugin:2.7+ -
Output of
javadoc:test-aggregate
is cached for maven-javadoc-plugin:2.7+ -
Output of
javadoc:test-aggregate-jar
is cached for maven-javadoc-plugin:2.7+ -
Output of
javadoc:test-aggregate-no-fork
is cached for maven-javadoc-plugin:2.7+ -
Maven log no longer disappears when extension is applied twice
-
Skipped cacheable goals are reported as "skipped" instead of "not cacheable"
-
Local Build Cache issues fail the build instead of logging a warning
-
Extension only snapshots input files that match given include/exclude patterns
-
Fix
NullPointerException
when trying to resolve a non-existing plugin without version -
Parallel forked goal executions are captured correctly in Build Scans
-
Capture finer-grained fingerprint events
Compatible with scans.gradle.com and Gradle Enterprise 2019.2 or later.
1.0.8
-
Fix handling of null-valued system properties
-
Prevent non existing javadoc jars from being attached
-
java.io.tmpdir is ignored in surefire systemProperties/systemPropertyVariables
Compatible with scans.gradle.com and Gradle Enterprise 2019.1 or later.
1.0.7
-
Output of
javadoc:test-jar
is cached for maven-javadoc-plugin:2.7+ -
Output of
javadoc:jar
is cached for maven-javadoc-plugin:2.7+ -
Output of
javadoc:test-javadoc-no-fork
is cached for maven-javadoc-plugin:2.7+ -
Output of
javadoc:test-javadoc
is cached for maven-javadoc-plugin:2.7+ -
Output of
javadoc:javadoc-no-fork
is cached for maven-javadoc-plugin:2.7+ -
Output of
javadoc:javadoc
is cached for maven-javadoc-plugin:2.7+ -
Output of
generate
goal is cached for maven-jaxb2-plugin:0.12.3+ -
Output of
checkstyle:check
is cached for maven-checkstyle-plugin:2.14+ -
Output of
checkstyle:checkstyle
is cached for maven-checkstyle-plugin:2.14+ -
Output of
checkstyle:checkstyle-aggregate
is cached for maven-checkstyle-plugin:2.14+ -
Protect against double applications
-
Protect against event notifications received before initialization (workaround for MNG-6619)
-
Handle more absolute paths in JVM arguments out of the box
-
Broken
java
executables make goals non-cacheable instead of failing the build -
System properties now overwrite values in
gradle-enterprise.xml
-
Allow same file to appear in multiple output locations (e.g. the
summaryFile
of the maven-failsafe-plugin) -
User can add additional inputs and outputs to goal executions using the
pom.xml
DSL -
Command line arguments are normalized, removing all known input and output paths from them to allow relocation
-
Caching is deactivated for goals that contain undeclared file paths in their input properties (e.g. JVM args)
Compatible with scans.gradle.com and Gradle Enterprise 2019.1 or later.
1.0.6
-
Add support for code completion of
publishMode
ingradle-enterprise.xml
-
Support broken JARs in annotation processor detection
Compatible with scans.gradle.com and Gradle Enterprise 2019.1 or later.
1.0.5
-
Only fingerprints for external jars are stored in the Build Cache
-
Surefire statistics file and tempDir are tracked as local state
-
Performance improvements for jar fingerprinting and Build Cache load operations
-
More helpful error message for invalid Build Scan publishing mode configuration
Compatible with scans.gradle.com and Gradle Enterprise 2019.1 or later.
1.0.4
-
Fix ID generation for Build Cache events
-
Jar fingerprints are stored in the Build Cache
Compatible with scans.gradle.com and Gradle Enterprise 2019.1 or later.
1.0.3
-
Fix hashing of Build Cache operations, that was leading to event ID collisions
-
Support a proxy server when publishing Build Scans
-
Prevent publishing Build Scans when there is no entitlement
Compatible with scans.gradle.com and Gradle Enterprise 2019.1 or later.
1.0.2
-
Runtime classpath normalization recursively inspects WAR, EAR, ZIP and APK files
-
Track
runOrder
as input property for themaven-surefire-plugin
andmaven-failsafe-plugin
-
Fix project capturing to respect
<module>
declarations
Compatible with scans.gradle.com and Gradle Enterprise 2019.1 or later.
1.0.1
-
Restore compatibility with Maven <
3.5.2
-
Enhance console output of terms of uses
Compatible with scans.gradle.com and Gradle Enterprise 2019.1 or later.
1.0
-
Initial release
Compatible with scans.gradle.com and Gradle Enterprise 2019.1 or later.
Appendix F: Compatibility with Apache Maven and Develocity
Compatibility between versions of Apache Maven, Develocity, and the Develocity Maven extension can be found here.
Appendix G: Compatibility with Apache Maven plugins
Certain versions of the Apache Maven plugins listed below are incompatible with the Develocity Maven extension. If using one of those plugins, please ensure to use a compatible version.
Plugin | Compatible versions | Reason |
---|---|---|
3.1.0+ |
Previous versions trigger unexpected |
Appendix H: Compatibility with IntelliJ IDEA
No Build Scan data will be published and the Build Cache will not be used when running builds from IDEA versions below 2019.2 or version 2019.3. This is due to issues in these IDEA versions that we can’t work around. We recommend using IDEA 2019.3.1 or above to get the best experience.
Appendix I: Verifying the signature of the extension jar
The extension jar is published to Maven Central alongside its signature (cf. OSSRH Guide). The public key is published to https://keys.openpgp.org. You can verify the signature as follows:
$ curl -OL https://repo1.maven.org/maven2/com/gradle/gradle-enterprise-maven-extension/1.22.2/gradle-enterprise-maven-extension-1.22.2.jar && \
curl -OL https://repo1.maven.org/maven2/com/gradle/gradle-enterprise-maven-extension/1.22.2/gradle-enterprise-maven-extension-1.22.2.jar.asc && \
gpg --keyserver keys.openpgp.org --recv-key 7B79ADD11F8A779FE90FD3D0893A028475557671 && \
gpg --verify gradle-enterprise-maven-extension-1.22.2.jar.asc gradle-enterprise-maven-extension-1.22.2.jar
The output of the last command should look similar to the following:
gpg: Signature made Thu Sep 28 16:17:46 2023 CEST gpg: using RSA key 893A028475557671 gpg: Good signature from "Gradle Inc. <info@gradle.com>" [unknown] gpg: aka "Gradle Inc. <maven-publishing@gradle.com>" [unknown] gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: 7B79 ADD1 1F8A 779F E90F D3D0 893A 0284 7555 7671
This verifies that the artifact was signed with the private key that corresponds to the imported public key. The warning is emitted because you haven’t explicitly trusted the imported key (hence [unknown]
). One way of establishing trust is to verify the fingerprint over a secure channel. Please contact technical support should you wish to do so.
The access key used to sign older versions of the Gradle Enterprise Maven Extension is revoked. Verifying the signature of these prior versions is no longer possible. |
Appendix J: Running goals contributed by the Develocity Maven extension
The com.gradle
plugin group exposes the gradle-enterprise
prefix in Maven Central, which allows to execute goals exposed by the Develocity Maven extension with a shorter syntax.
-
When using Develocity Maven extension version 1.16 or above, the
com.gradle
plugin group is automatically added to the Maven execution request, so no configuration is needed. -
When using Develocity Maven extension version < 1.16, you must instruct Maven to search for goal prefixes within the
com.gradle
plugin group. You must add the following code snippet to your~/.m2/settings.xml
or${maven.home}/conf/settings.xml
.
<pluginGroups>
<pluginGroup>com.gradle</pluginGroup>
</pluginGroups>
Then, instead of executing
$ mvn com.gradle:gradle-enterprise-maven-extension:<<goal-name>>
you can execute
$ mvn gradle-enterprise:<<goal-name>>
When omitting the Develocity Maven extension version, Maven will select the latest version available. You can force using a given version by executing
but this does not work with the goal prefix syntax, unless you declare the extension in your
This will execute the goal from the <<version>> extension
|
Goals provided by the Develocity Maven extension
The following goals are exposed by the Develocity Maven extension.
build-scan-publish-previous
(Maven extension 1.16+)
Publishes a Build Scan for the most recently run build.
init
(Maven extension 1.19+)
Sets up the Develocity Maven extension in a Maven project. Without applying the Develocity Maven extension in the first place, you can execute:
mvn com.gradle:gradle-enterprise-maven-extension:1.22.2:init -Dgradle.enterprise.url=https://develocity.mycompany.com
It will:
-
Create/update the
.mvn/extensions.xml
with the given Develocity Maven extension release version:
mvn com.gradle:gradle-enterprise-maven-extension:1.22.2:init
-
Create/update the
.mvn/extensions.xml
with the Develocity Maven extension -
Create the
.mvn/gradle-enterprise.xml
pointing to the passed server -
Create/update
.gitignore
to ignore.mvn/.gradle-enterprise/
Appendix K: Migrating to the Develocity extension
There will be no further releases of the Gradle Enterprise Maven extension starting with Develocity 2024.3. It’s recommended to upgrade to the Develocity Maven extension as soon as possible. |
Starting with version 1.21, the extension is available under the “Develocity” brand. Please see the Develocity Maven Extension User Manual for the current documentation. Several APIs, system properties and configuration files have been deprecated with the rebranding and will be removed in the next major version. Therefore, please consider migrating to the new APIs where applicable to minimize the amount of necessary changes when updating to the next major version.
Recommended migration path
Assume the following example configuration of the Gradle Enterprise Maven extension:
<?xml version="1.0" encoding="UTF-8"?>
<extensions>
<extension>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<version>1.20.1</version>
</extension>
<extension>
<groupId>com.gradle</groupId>
<artifactId>common-custom-user-data-maven-extension</artifactId>
<version>1.13</version>
</extension>
</extensions>
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<gradleEnterprise
xmlns="https://www.gradle.com/gradle-enterprise-maven" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.gradle.com/gradle-enterprise-maven https://www.gradle.com/schema/gradle-enterprise-maven.xsd">
<server>
<url>https://develocity-samples.gradle.com</url>
<allowUntrusted>false</allowUntrusted>
</server>
<buildScan>
<capture>
<goalInputFiles>true</goalInputFiles>
</capture>
<backgroundBuildScanUpload>{isFalse(env['CI'])}</backgroundBuildScanUpload>
<publish>ALWAYS</publish>
</buildScan>
<buildCache>
<local>
<enabled>true</enabled>
</local>
<remote>
<enabled>true</enabled>
<storeEnabled>{isTrue(env['CI'])}</storeEnabled>
</remote>
</buildCache>
</gradleEnterprise>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>gradle-enterprise-maven-extension</artifactId>
<version>1.20.1</version>
<configuration>
<gradleEnterprise>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<inputs>
<properties>
<property>
<name>additionalProperty</name>
<value>${additionalProperty}</value>
</property>
</properties>
</inputs>
</plugin>
</plugins>
</gradleEnterprise>
</configuration>
</plugin>
</plugins>
</pluginManagement>
For a smooth migration, perform the following steps:
-
Update the extension’s version to
1.21+
in.mvn/extensions.xml
andpom.xml
-
Change the artifact ID to
develocity-maven-extension
in.mvn/extensions.xml
andpom.xml
-
Rename
.mvn/gradle-enterprise.xml
to.mvn/develocity.xml
-
Update
.gitignore
line from.mvn/.gradle-enterprise
to.mvn/.develocity
-
Follow the Updating access keys steps
-
If using the
common-custom-user-data-maven-extension
, update the extension’s version to2.0+
. For details on migrating a custom user data groovy script see here
After running a goal like ./mvnw clean
you will be informed about the usage of the deprecated APIs:
[WARNING] The following functionality has been deprecated and will be removed in the next major release of the Develocity Maven extension. Run with '-Ddevelocity.deprecation.captureOrigin=true' to see where the deprecated functionality is being used. For assistance with migration, see https://gradle.com/help/maven-extension-develocity-migration.
[WARNING] - The deprecated "gradleEnterprise.buildScan.publish" XML element has been replaced by "develocity.buildScan.publishing"
[WARNING] - The deprecated "gradleEnterprise.buildScan.capture.goalInputFiles" XML element has been replaced by "develocity.buildScan.capture.fileFingerprints"
Most of the violations can be fixed by replacing references of gradleEnterprise
with develocity
. Some APIs have been replaced by more descriptive and idiomatic alternatives. In this example, those APIs are goalInputFiles
and publish
. See Breaking API changes section for this and other examples. After these changes, your extensions.xml
and develocity.xml
should look like the following:
<?xml version="1.0" encoding="UTF-8"?>
<extensions>
<extension>
<groupId>com.gradle</groupId>
<artifactId>develocity-maven-extension</artifactId>
<version>1.21</version>
</extension>
<extension>
<groupId>com.gradle</groupId>
<artifactId>common-custom-user-data-maven-extension</artifactId>
<version>2.0</version>
</extension>
</extensions>
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<develocity
xmlns="https://www.gradle.com/develocity-maven" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.gradle.com/develocity-maven https://www.gradle.com/schema/develocity-maven.xsd">
<server>
<url>https://develocity-samples.gradle.com</url>
<allowUntrusted>false</allowUntrusted>
</server>
<buildScan>
<backgroundBuildScanUpload>{isFalse(env['CI'])}</backgroundBuildScanUpload>
</buildScan>
<buildCache>
<local>
<enabled>true</enabled>
</local>
<remote>
<enabled>true</enabled>
<storeEnabled>{isTrue(env['CI'])}</storeEnabled>
</remote>
</buildCache>
</develocity>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gradle</groupId>
<artifactId>develocity-maven-extension</artifactId>
<version>1.21</version>
<configuration>
<develocity>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<inputs>
<properties>
<property>
<name>additionalProperty</name>
<value>${additionalProperty}</value>
</property>
</properties>
</inputs>
</plugin>
</plugins>
</develocity>
</configuration>
</plugin>
</plugins>
</pluginManagement>
This solves all warnings for the example above. Please note that these warnings can also originate from an extension that configures Develocity. To identify the origin of the deprecated API usage, re-run the build with the develocity.deprecation.captureOrigin
system property set to true
. Usually, they have to be fixed in the third-party extension, and your build has to be updated to the newest version of the third-party extension after that. If you have custom extensions that depend on the Gradle Enterprise extension artifact, you must use the new com.gradle:develocity-maven-extension
, which replace the old com.gradle:gradle-enterprise-maven-extension
coordinate.
Deprecation warnings from transitive dependencies can be muted by setting the develocity.deprecation.muteWarnings system property to true . |
Updating access keys
Starting with version 1.21, access keys are stored in new locations:
-
The
GRADLE_ENTERPRISE_ACCESS_KEY
environment variable has been replaced withDEVELOCITY_ACCESS_KEY
-
The
~/.m2/.gradle-enterprise
directory has been replaced with~/.m2/.develocity
Any access keys stored at ~/.m2/.gradle-enterprise
will be automatically migrated to ~/.m2/.develocity
the first time a build is run after upgrading. However, the GRADLE_ENTERPRISE_ACCESS_KEY
environment variable will need to be renamed to DEVELOCITY_ACCESS_KEY
manually.
A deprecation warning will be printed if an access key is used from an old location.
To retain backwards compatibility, the extension will continue to look up access keys in the legacy locations, but future versions of the extension will drop support for them. |
Breaking API changes
In addition to the rename of the root API namespace to develocity
, certain APIs received more significant updates. See the API reference for complete overview of the updated API.
Updated file fingerprints capturing API
Starting with extension version 1.21, hashes of inputs of goals (and other units of work) will be captured by default. The legacy APIs for enabling file fingerprints capturing gradleEnterprise.buildScan.captureGoalInputFiles
and gradleEnterprise.buildScan.capture.goalInputFiles
have been replaced by develocity.buildScan.capture.fileFingerprints
.
If you previously configured gradleEnterprise.buildScan.capture.goalInputFiles = true
, then the explicit configuration can be removed as true
is now the default.
Updated terms of use API
Starting with extension version 1.21, the legacy API for accepting terms of service gradleEnterprise.buildScan.termsOfService
has been replaced by develocity.buildScan.termsOfUse
.
Updated Build Scan publication behavior
The Build Scan publication API has received a significant overhaul in the 1.21 version of the extension. It provides a new conditional publication API, and deprecates buildScan.publish
in favor of buildScan.publishing
. The migration can be performed as follows:
buildScan.publish | buildScan.publishing |
---|---|
No publish mode set (equivalent to |
No modifications necessary |
|
|
|
|
|
|
Please see Controlling when Build Scans are published for additional information about the new API.
Developing extensions that configure the Develocity Maven extension
For extensions that configure the Develocity Maven extension, please note that you will have to update references of com.gradle.maven.extension.api.GradleEnterpriseListener
to com.gradle.develocity.agent.maven.api.DevelocityListener
.