The Develocity Gradle plugin enables integration with Develocity and scans.gradle.com.
Prior versions of Develocity were known as “Gradle Enterprise” and used the (Legacy) Gradle Enterprise Gradle plugin. With Develocity 2024.1, that plugin has been deprecated in favor of the one documented in this user manual. Please refer to the Migrating to the Develocity plugin section for details. |
Getting set up
Version 3.18.2 is the latest version and is compatible with all Gradle 5.x and later versions. See Gradle 4.x and earlier if you are using an earlier version of Gradle.
The instructions in this section describe applying and configuring the plugin for a single Gradle project. See Integrating your CI tool for help with integrating all projects built within an environment.
Applying the plugin
Gradle 6.x and later
The com.gradle.develocity
plugin must be applied in the settings file of the build.
plugins {
id("com.gradle.develocity") version("3.18.2")
}
develocity {
// configuration
}
plugins {
id "com.gradle.develocity" version "3.18.2"
}
develocity {
// configuration
}
The plugin is configured via the develocity
extension available in the settings script, which is also available via the root project in project build scripts. The same instance is used for the settings extension and root project extension.
Gradle 5.x
The com.gradle.develocity
plugin must be applied to the root project of the build.
plugins {
id("com.gradle.develocity").version("3.18.2")
}
develocity {
// configuration
}
plugins {
id "com.gradle.develocity" version "3.18.2"
}
develocity {
// configuration
}
The plugin is configured via the develocity
extension of the root project in project build scripts.
Connecting to Develocity
To connect to a Develocity instance, you must configure the location of the Develocity server.
develocity {
server.set("https://develocity.mycompany.com")
}
develocity {
server = "https://develocity.mycompany.com"
}
Allowing untrusted SSL communication
If your Develocity server uses an SSL certificate that is not trusted by your build’s Java runtime, you will not be able to publish Build Scans without explicitly allowing untrusted servers.
To do this, set the allowUntrustedServer
option to true
:
develocity {
server.set("https://develocity.mycompany.com")
allowUntrustedServer.set(true)
}
develocity {
server = "https://develocity.mycompany.com"
allowUntrustedServer = true
}
Use of this configuration is a security risk as it makes it easier for a third party to intercept your Build Scan data. It should only be used as a short term workaround until the server can be configured with a trusted certificate.
Authenticating
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 provisionDevelocityAccessKey
task.
$ ./gradlew provisionDevelocityAccessKey
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 Gradle user home directory (~/.gradle
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, environment variable or the settings file.
Via file
Develocity access keys are stored inside the Gradle user home directory (~/.gradle
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 DEVELOCITY_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 DEVELOCITY_ACCESS_KEY=develocity.mycompany.com=7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq && \
./gradlew build
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.
$ export DEVELOCITY_ACCESS_KEY=ge1.mycompany.com=7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq;ge2.mycompany.com=9y4agfiubqqjea4vonghohvuyra5bnvszop4asbqee3m3sm67w5k && \
./gradlew build
Via settings file
The accessKey
option of the plugin allows the access key to be set via the settings file.
develocity {
server.set("https://develocity.mycompany.com")
accessKey.set("7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq")
}
develocity {
server = "https://develocity.mycompany.com"
accessKey = "7w5kbqqjea4vonghohvuyra5bnvszop4asbqee3m3sm6dbjdudtq"
}
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.
Connecting to scans.gradle.com
If the location of a Develocity server is not specified, Build Scans will be published to scans.gradle.com. This requires agreeing the terms of service, which can be found at https://gradle.com/terms-of-service.
You can agree to the terms of service by adding the following configuration to your build.
develocity {
buildScan {
termsOfUseUrl.set("https://gradle.com/help/legal-terms-of-use")
termsOfUseAgree.set("yes")
}
}
develocity {
buildScan {
termsOfUseUrl = "https://gradle.com/help/legal-terms-of-use"
termsOfUseAgree = "yes"
}
}
If you do not agree to the terms of service in your build, you will be asked interactively when trying to publish a Build Scan to scans.gradle.com each time you try to publish.
Be careful not to commit agreement to the terms of service into a project that may be built by others. |
Using Build Scans
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 Gradle plugin has several options that allow you to use whatever approach works best.
Publishing every build
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:
develocity {
buildScan {
publishing.onlyIf { true }
}
}
develocity {
buildScan {
publishing.onlyIf { true }
}
}
If you want to skip publishing a particular build, you can then add the --no-scan
argument to any Gradle build.
$ ./gradlew assemble --no-scan
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:
develocity {
buildScan {
publishing.onlyIf { false }
}
}
develocity {
buildScan {
publishing.onlyIf { false }
}
}
You can then add the --scan
argument to any Gradle build to publish a Build Scan.
$ ./gradlew assemble --scan
Interoperability with Gradle 8.4 and older
If the build does not apply the plugin, Gradle will automatically apply the most recent version available at the time that version of Gradle was released. Gradle versions older than 8.4 do not recognize the Develocity plugin as the replacement for deprecated Gradle Enterprise and Build Scan plugins. When This case will be highlighted using the following message: WARNING: Deprecated Gradle Enterprise plugin [version: 3.16.2] was applied alongside Develocity plugin. If your build uses the latest Develocity functionality, it may fail or not run as expected since the deprecated plugin may not support requested features. The simultaneous application of Develocity and Gradle Enterprise plugins will cause the build to fail in a future release of the Develocity plugin. To resolve the issue, upgrade to a newer Gradle version or configure on-demand publication using one of the options described in Publishing based on criteria section. |
You can also publish a Build Scan for the most recently run build by invoking the buildScanPublishPrevious
task added by the plugin.
$ ./gradlew buildScanPublishPrevious
Since the task name is quite long, it’s worth taking advantage of Gradle’s abbreviated command line notation for tasks:
$ ./gradlew bSPP
Publishing based on criteria
Many of you will want a bit more control over exactly when Build Scans are published without resorting to using --scan
each time. You may want to publish Build Scans only under the following conditions:
-
When the build fails
-
When the user running the build is authenticated with Develocity
-
If the build is running on CI
Such scenarios are covered by configuring a custom predicate.
develocity {
buildScan {
publishing.onlyIf { it.buildResult.failures.isNotEmpty() }
}
}
develocity {
buildScan {
publishing.onlyIf { !it.buildResult.failures.empty }
}
}
develocity {
buildScan {
publishing.onlyIf { it.authenticated }
}
}
develocity {
buildScan {
publishing.onlyIf { it.authenticated }
}
}
develocity {
buildScan {
publishing.onlyIf { !System.getenv("CI").isNullOrEmpty() }
}
}
develocity {
buildScan {
publishing.onlyIf { System.getenv("CI") }
}
}
You can use the other options in the same way. If you want to configure several things based on a set of criteria, you can use an if
condition instead:
develocity {
buildScan {
if (!System.getenv("CI").isNullOrEmpty()) {
publishing.onlyIf { true }
tag("CI")
}
}
}
develocity {
buildScan {
if (System.getenv("CI")) {
publishing.onlyIf { true }
tag "CI"
}
}
}
Configuring background uploading
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.
Disabling programmatically
The develocity.buildScan.uploadInBackground
property can be set to false
.
develocity {
buildScan {
uploadInBackground.set(false)
}
}
develocity {
buildScan {
uploadInBackground = false
}
}
It may be desirable to conditionally set the value based on the environment.
develocity {
buildScan {
uploadInBackground.set(System.getenv("CI") == null)
}
}
develocity {
buildScan {
uploadInBackground = System.getenv("CI") == null
}
}
Disabling via system property
Background uploading can be disabled by setting the scan.uploadInBackground
system property to false
. The system property setting always takes precedence over the programmatic setting.
The system property may be specified when invoking the build:
$ ./gradlew build -Dscan.uploadInBackground=false
Or, can be set as part of the environment with the JAVA_OPTS
or GRADLE_OPTS
environment variables:
$ export GRADLE_OPTS=-Dscan.uploadInBackground=false
Or, can be set in the user’s gradle.properties
file (i.e. ~/.gradle/gradle.properties
).
systemProp.scan.uploadInBackground=false
Configuring project identifier
Detailed information regarding project-level access control can be found here.
Setting programmatically
The develocity.projectId
property can be set to a necessary value.
develocity {
projectId.set("myProject")
}
develocity {
projectId = "myProject"
}
Setting via system property
Project identifier can be also set using the develocity.projectId
system property. The system property setting always takes precedence over the programmatic setting.
The system property may be specified when invoking the build:
$ ./gradlew build -Ddevelocity.projectId=myProject
Or, can be set as part of the environment with the JAVA_OPTS
or GRADLE_OPTS
environment variables:
$ export GRADLE_OPTS=-Ddevelocity.projectId=myProject
Or, can be set in the user’s gradle.properties
file (i.e. ~/.gradle/gradle.properties
).
systemProp.develocity.projectId=myProject
Capturing file fingerprints
Build Scans capture hashes of inputs of tasks (and other units of work), to enable identifying changes to inputs when comparing builds, among other features. The overall hash value of each input property enables identifying which properties changed for a task (e.g. the source or the classpath for Java compilation). In addition, the paths and content hashes of individual input files of each property are captured by default. They allow identifying which individual files changed for a task when comparing two builds.
When to disable
Capturing file fingerprints 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 a Build Scan server. In such cases, capturing file fingerprints can be disabled.
However, if you are using Develocity and utilising its Build Cache to accelerate your builds, it is strongly recommended to keep it enabled 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 file fingerprints is a prerequisite.
How to disable
Capture of file fingerprints can be enabled/disabled programmatically via the buildScan
extension, or via a system property.
Programmatically
To enable/disable programmatically, use the buildScan
extension added by the Develocity Gradle plugin.
develocity {
buildScan {
capture {
fileFingerprints.set(false)
}
}
}
develocity {
buildScan {
capture {
fileFingerprints = false
}
}
}
See the file fingerprints API reference.
Via system property
To enable/disable without modifying the build script, supply a scan.capture-file-fingerprints
system property to the build. If the property is set to false
, capture is disabled. Otherwise, capture is enabled. The environmental setting always takes precedence over the programmatic setting.
The system property may be specified when invoking the build:
$ ./gradlew build -Dscan.capture-file-fingerprints=false
Or, can be set as part of the environment with the JAVA_OPTS
or GRADLE_OPTS
environment variables:
$ export GRADLE_OPTS=-Dscan.capture-file-fingerprints=false
Or, can be set in the project’s gradle.properties
file, or the user’s gradle.properties
file (i.e. ~/.gradle/gradle.properties
).
systemProp.scan.capture-file-fingerprints=false
See the Build Environment chapter of the Gradle User Manual for more information on specifying system properties.
Capturing build and test outputs
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 tasks/tests may produce a lot of outputs that are irrelevant for your usage of Build Scans).
How to disable
Output capture can be enabled/disabled programmatically via the buildScan
extension, or via a system property.
Programmatically
To enable/disable programmatically, use the buildScan
extension added by the Develocity Gradle plugin.
develocity {
buildScan {
capture {
buildLogging.set(false)
testLogging.set(false)
}
}
}
develocity {
buildScan {
capture {
buildLogging = false
testLogging = false
}
}
}
See the build logging API reference and the test logging API reference.
Via system property
To enable/disable without modifying the build script, supply the scan.capture-build-logging
and/or scan.capture-test-logging
system properties to the build. If the property is set to false
, capture is disabled. Otherwise, capture is enabled. The environmental setting always takes precedence over the programmatic setting.
The system property may be specified when invoking the build:
$ ./gradlew build -Dscan.capture-build-logging=false -Dscan.capture-test-logging=false
Or, can be set as part of the environment with the JAVA_OPTS
or GRADLE_OPTS
environment variables:
$ export GRADLE_OPTS="-Dscan.capture-build-logging=false -Dscan.capture-test-logging=false"
Or, can be set in the project’s gradle.properties
file, or the user’s gradle.properties
file (i.e. ~/.gradle/gradle.properties
).
systemProp.scan.capture-build-logging=false
systemProp.scan.capture-test-logging=false
See the Build Environment chapter of the Gradle User Manual for more information on specifying system properties.
Capturing resource usage
(plugin 3.18+)
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. This data 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.
Users of Gradle’s configuration cache feature must use version 7.6 of Gradle or later to benefit from resource usage capturing. When using plugin 3.18+ with earlier versions of Gradle and configuration caching turned on, resource usage capturing will be automatically disabled, and a warning message will be printed. |
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 the buildScan
extension, or via a system property.
Programmatically
To enable/disable programmatically, use the buildScan
extension added by the Develocity Gradle plugin.
develocity {
buildScan {
capture {
resourceUsage.set(false)
}
}
}
develocity {
buildScan {
capture {
resourceUsage = false
}
}
}
See the resource usage API reference.
Via system property
To enable/disable without modifying the build script, supply the scan.capture-resource-usage
system properties to the build. If the property is set to false
, capture is disabled. Otherwise, capture is enabled. The environmental setting always takes precedence over the programmatic setting.
The system property may be specified when invoking the build:
$ ./gradlew build -Dscan.capture-resource-usage=false
Or, can be set as part of the environment with the JAVA_OPTS
or GRADLE_OPTS
environment variables:
$ export GRADLE_OPTS="-Dscan.capture-resource-usage=false"
Or, can be set in the project’s gradle.properties
file, or the user’s gradle.properties
file (i.e. ~/.gradle/gradle.properties
).
systemProp.scan.capture-resource-usage=false
See the Build Environment chapter of the Gradle User Manual for more information on specifying system properties.
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 1 and 2:
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 3, for example, we are filtering for all Build Scans that have the tag "CI" and a git branch name of "master":
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.
They can be added at build time via the tag()
method:
develocity {
buildScan {
tag(if (System.getenv("CI").isNullOrEmpty()) "Local" else "CI")
tag(System.getProperty("os.name"))
}
}
develocity {
buildScan {
if (System.getenv("CI")) {
tag "CI"
} else {
tag "Local"
}
tag System.getProperty("os.name")
}
}
As demonstrated by the example above, tags are typically applied either as fixed strings within a condition or evaluated at runtime from the environment. But there are no set rules that you need to follow—these are only suggestions.
The syntax for adding a tag is:
tag(<tag>)
where the <tag> is a string.
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.
The plugin imposes the following 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.
They can be added at build time via the link()
method:
develocity {
buildScan {
link("VCS", "https://github.com/myorg/sample/tree/${System.getProperty("vcs.branch")}")
}
}
develocity {
buildScan {
link "VCS", "https://github.com/myorg/sample/tree/${System.getProperty("vcs.branch")}"
}
}
The above example demonstrates how you can attach a link to an online VCS repository that points to a specific branch provided as a system property.
The syntax for adding a link is:
link(<label>, <URL>)
The <label> 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 1, which shows how a label Source becomes a hyperlink that anyone viewing the Build Scan can follow.
The plugin imposes the following 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.
They can be added at build time via the value()
method:
develocity {
buildScan {
value("Build Number", project.buildNumber)
}
}
develocity {
buildScan {
value "Build Number", project.buildNumber
}
}
The above example demonstrates how you can read the build number from a project property—assuming you have your build set up for this—and attach it to the Build Scans as a custom value.
The syntax for adding a value is:
value(<key>, <value>)
where both the <key>
and the <value>
are strings.
As with tags, you can filter Build Scans by custom values in Develocity.
The plugin imposes the following limits on captured custom values:
|
Adding data at the end of the build
The examples you have seen so far work well if when the custom data is available at the beginning of the build. But what if you want to attach data that’s only available later? For example, you might want to label a build as "built-from-clean" if the clean
task was run. But you don’t know if that’s the case until the task execution graph is ready.
The Develocity Gradle plugin 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 build
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:
develocity {
buildScan {
buildFinished {
value("Disk usage (output dir)", buildDir.walkTopDown().map { it.length() }.sum().toString())
}
}
}
develocity {
buildScan {
buildFinished {
value "Disk usage (output dir)", buildDir.directorySize().toString()
}
}
}
The buildFinished()
action has access to the rest of the build, including the Project
instance, so it can extract all sorts of information. It also has access to a BuildResult
instance that you can use to determine whether the build failed or not, like so:
buildFinished()
develocity {
buildScan {
buildFinished {
if (this.failures.isNotEmpty()) {
value("Failed with", this.failure.message)
}
}
}
}
buildFinished()
import com.gradle.scan.plugin.BuildResult
develocity {
buildScan {
buildFinished { BuildResult result ->
if (result.failures) {
value "Failed with", result.failure.message
}
}
}
}
The Gradle build tool has a |
Adding expensive data
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 buildScan.background()
method:
background()
to capture an expensive custom value with Gradle 6.2+ and Configuration Cache compatibility.
import org.gradle.kotlin.dsl.support.serviceOf
import java.io.ByteArrayOutputStream
...
develocity {
buildScan {
val execOps = serviceOf<ExecOperations>()
background {
val os = ByteArrayOutputStream()
execOps.exec {
commandLine("git", "rev-parse", "--verify", "HEAD")
standardOutput = os
}
value("Git Commit ID", os.toString())
}
}
}
background()
to capture an expensive custom value with Gradle 5.x
import java.io.ByteArrayOutputStream
...
develocity {
buildScan {
background {
val os = ByteArrayOutputStream()
exec {
commandLine("git", "rev-parse", "--verify", "HEAD")
standardOutput = os
}
value("Git Commit ID", os.toString())
}
}
}
background()
to capture an expensive custom value
develocity {
buildScan {
background {
def commitId = "git rev-parse --verify HEAD".execute().text.trim()
value "Git Commit ID", commitId
}
}
}
This method takes a function that will be executed on a separate thread, which allows Gradle 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 buildScan.background() API reference for more information.
Providing custom data via system properties
The examples up to this point have shown how your build file or init script can pull information from the environment, via environment variables and system properties. The Develocity Gradle plugin also allows you to inject any form of custom data through the use of specially named system properties. This can help you keep your build files clean of too much environment-specific information that may not be relevant to most of the users of the build.
These system properties take the following forms, depending on whether you want to inject a link, a tag or a custom value:
-Dscan.tag.<tag> -Dscan.link.<label>=<URL> -Dscan.value.<key>=<value>
Here are some concrete examples, which assume that the build has been configured to publish Build Scans automatically:
$ ./gradlew build -Dscan.tag.CI
$ ./gradlew build -Dscan.link.VCS=https://github.com/myorg/my-super-project/tree/my-new-feature
$ ./gradlew build "-Dscan.value.CIBuildType=QA_Build"
This feature is particularly useful for continuous integration builds as you can typically easily configure your CI tool to specify system properties for a build. It’s even common for CI tools to be able to inject system properties into a build that are interpolated with information from the CI system, such as build number.
$ ./gradlew build "-Dscan.value.buildNumber=$CI_BUILD_NUMBER"
Capturing the Build Scan ID or address
The address of the Build Scan is included in the output at the end of the build. However, you may wish to record the ID or URL of the Build Scan in some other way. The Develocity Gradle plugin allows you to register a callback that will receive this information. The callback is invoked after a Build Scan has been successfully published.
The example build script snippet below shows this feature being used to maintain a journal of created Build Scans.
Develocity provides the ability to search for Build Scans created by a certain user and/or from a particular host (along with other search criteria). |
import java.util.Date
develocity {
buildScan {
buildScanPublished {
file("scan-journal.log").appendText("${Date()} - ${this.buildScanId} - ${this.buildScanUri}\n")
}
}
}
import com.gradle.scan.plugin.PublishedBuildScan
develocity {
buildScan {
buildScanPublished { PublishedBuildScan scan ->
file("scan-journal.log") << "${new Date()} - ${scan.buildScanId} - ${scan.buildScanUri}\n"
}
}
}
Please see the buildScan.buildScanPublished() method for API details.
Obfuscating identifying data
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, by registering obfuscation functions as part of the Build Scan configuration.
The following examples show registering obfuscation functions for the different identifying data.
develocity {
buildScan {
obfuscation {
username { name -> name.reversed() }
}
}
}
develocity {
buildScan {
obfuscation {
username { name -> name.reverse() }
}
}
}
develocity {
buildScan {
obfuscation {
hostname { host -> host.toCharArray().map { character -> Character.getNumericValue(character) }.joinToString("-") }
}
}
}
develocity {
buildScan {
obfuscation {
hostname { host -> host.collect { character -> Character.getNumericValue(character as char) }.join("-") }
}
}
}
develocity {
buildScan {
obfuscation {
ipAddresses { addresses -> addresses.map { _ -> "0.0.0.0" } }
}
}
}
develocity {
buildScan {
obfuscation {
ipAddresses { addresses -> addresses.collect { address -> "0.0.0.0" } }
}
}
}
develocity {
buildScan {
obfuscation {
externalProcessName { processName -> "non-build-process" }
}
}
}
develocity {
buildScan {
obfuscation {
externalProcessName { processName -> 'non-build-process' }
}
}
}
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.
GitHub Actions
The Gradle GitHub Action prominently displays links to the Build Scan for any Gradle build that produces Build Scans, which makes them convenient to access. 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 Gradle build, via environment variables defined in your GitHub Actions workflow. This eases the adoption of Build Scans within the company and allows configuring the Develocity Gradle plugin at the CI level. For more information please read the documentation here.
Viewing test results
The Develocity plugin will capture test execution results and publish them to the Develocity server. After your Build Scan® is ready, you can view and analyze the results.
Any test framework that is supported by Gradle’s Test task and based on JUnit Platform should work with Develocity without requiring any change. Contact us at support.gradle.com if the results are not correctly displayed for the test framework that you are using.
The Test overview page
The Test overview page shows a high level overview of all the tests that were executed as part of the build. The test results are displayed hierarchically: they are grouped by task, test suite and finally test case. Next to each task, test suite and test case, the outcome and the total time are displayed.
Test outcomes
Every task, test suite and test case has an outcome. For a task, the outcome is either SUCCESS
, indicating that the task was successful, FLAKY
, which means that at least one test suite was flaky, or FAILED
, if a test suite has failed.
For test suites, the outcome can be SUCCESS
, meaning that all executed test cases were successful, FAILED
, indicating that at least one test case failed, FLAKY
, meaning that at least one test case was successful only after retry, or SKIPPED
, meaning that the test suite was not executed.
For test cases, the outcome can be SKIPPED
, meaning that the test case was not executed, SUCCESS
, meaning that the test case was successful, FAILED
indicating that the test case was failed, or FLAKY
, meaning that the test case was successful only after retry.
Test timings
On a task, the total time corresponds to the total amount of wall clock time the task took to execute.
On a test suite, the total time corresponds to the total amount of wall clock time the test suite took to execute.
On a test case, the total time corresponds to the total amount of wall clock time the test case took to execute. Clicking on a test task will open the details for this test task, which will display the results of the test suites which ran as part of this test task.
Test task details page
The Test task details page displays the results of the test suites which ran as part of the selected test task.
At the top of the page, it also shows relevant configuration values, and performance statistics. Clicking on a test suite will open the details for this test suite, which will display the results of the test cases which ran as part of this test suite.
Test suite details page
The Test suite details page displays the results of the test cases which ran as part of the selected test suite.
Errors that may have happened during the setup or cleanup phase of the test suite execution are reported in this page.
The suite’s overall outcome is broken down into Class setup/cleanup and Test execution outcomes. Class setup/cleanup tracks whether a failure occurred in the suite’s setup / teardown callbacks, and Test execution whether it was a test case that caused the test suite to fail.
At the bottom of the page, the test cases that were executed as part of this test suite are listed, along with the time and outcome of each execution. A test case may be run more than once in case of retries.
Clicking on a test case will open the details for this test case, which will display the results of the executions of this test case.
Test case details page
The Test case details page displays the results of the executions of the selected test case.
The total time and outcome of each execution of the selected test case are displayed on the page. If an execution failed with an exception, then the exception is displayed under the corresponding execution.
Using Build Caching
The Develocity Gradle plugin provides a build cache connector that can be used to leverage the build cache provided by Develocity. Gradle’s out-of-the-box support for generic HTTP build cache servers is also compatible with the build cache provided by Develocity, and can be used when the Develocity specific connector can not be used.
The Develocity specific connector should be preferred, and can be used whenever all of the following conditions are met:
-
You are using Gradle version >= 6.0
-
You are using Develocity Build Cache Nodes of version >= 13
Using the Develocity connector
(Gradle 6+)
Users of Gradle’s configuration cache feature must use version 7.5.1 of Gradle or later when using the Develocity build cache connector. Earlier versions of Gradle will fail with an error message stating “Could not create service of type BuildCacheController”. |
The Develocity build cache connector can be used by registering the connector with Gradle and configuring it:
develocity {
server.set("https://develocity.mycompany.com")
}
buildCache {
remote(develocity.buildCache) {
// configure
}
}
develocity {
server = "https://develocity.mycompany.com"
}
buildCache {
remote(develocity.buildCache) {
// configure
}
}
The buildCache {}
method is provided by Gradle, with the develocity.buildCache
method being provided by the Develocity configuration.
Without further configuration, the build will now attempt to read entries from the built-in build cache of the specified Develocity server. The connector of type DevelocityBuildCache can be configured inside the configuration block.
Credentials
If an access key has been configured for the specified Develocity server (see Authenticating), it will be used. Otherwise, requests will be sent anonymously.
Develocity also allows build caches to be configured with username and password credentials separate to access-key-based access control. To connect with a username and password credential, use the usernameAndPassword()
method. The username and password will be used instead of any configured access key.
develocity {
server.set("https://develocity.mycompany.com")
}
buildCache {
remote(develocity.buildCache) {
usernameAndPassword("user", "pass")
}
}
develocity {
server = "https://develocity.mycompany.com"
}
buildCache {
remote(develocity.buildCache) {
usernameAndPassword("user", "pass")
}
}
Writing to the build cache
By default, Gradle will only attempt to read from the build cache. To also write to the build cache, the push
property of the connector must be configured to true
.
develocity {
server.set("https://develocity.mycompany.com")
}
buildCache {
remote(develocity.buildCache) {
isPush = true
}
}
develocity {
server = "https://develocity.mycompany.com"
}
buildCache {
remote(develocity.buildCache) {
push = true
}
}
The write attempt may be rejected due to insufficient permissions depending on the Develocity server’s access control settings.
Using Expect-Continue
The Develocity 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.
develocity {
server.set("https://develocity.mycompany.com")
}
buildCache {
remote(develocity.buildCache) {
useExpectContinue = true
}
}
develocity {
server = "https://develocity.mycompany.com"
}
buildCache {
remote(develocity.buildCache) {
useExpectContinue = true
}
}
Using a non-built-in cache
Develocity provides a built-in build cache, but can also leverage separately deployed build cache nodes for geographical distribution and horizontal scaling. If you are using such a non-built-in node, you must configure its address with the build cache connector.
develocity {
server.set("https://develocity.mycompany.com")
}
buildCache {
remote(develocity.buildCache) {
server = "https://develocity-cache-1.mycompany.com"
}
}
develocity {
server = "https://develocity.mycompany.com"
}
buildCache {
remote(develocity.buildCache) {
server = "https://develocity-cache-1.mycompany.com"
}
}
Note that the server address should be specified without any request path component.
If using access-key-based authentication, the given build cache server must be of version 13 or later and be connected with the Develocity server specified by the develocity {}
extension.
Similar to the Develocity server configuration, the remote Build Cache server configuration also provides an
settings.gradle.kts
settings.gradle
|
This is a convenient workaround during the initial evaluation, but it is a serious security issue and should not be used in production. |
Using Gradle’s built-in HTTP connector
Gradle’s out-of-the-box support for generic HTTP build cache servers is also compatible with the build cache provided by Develocity, and can be used when the Develocity specific connector can not be used.
develocity {
server.set("https://develocity.mycompany.com")
}
buildCache {
remote(HttpBuildCache::class) {
url = uri("https://develocity.mycompany.com/cache/")
}
}
develocity {
server = "https://develocity.mycompany.com"
}
buildCache {
remote(HttpBuildCache) {
url = 'https://develocity.mycompany.com/cache/'
}
}
When using this connector, access-key-based access control cannot be used. Instead, username and password based access control must be used which is also supported by the Develocity build cache and can be configured by administrators.
Using Predictive Test Selection
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. |
Using Test Distribution
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 Test Retry
When test retry is enabled, any failed tests are retried after all the tests have been executed. The process repeats with tests that continue to fail until the maximum specified number of retries has been attempted, or there are no more failing tests.
By default, the test task does not fail when all failed tests pass after a retry. This setting can be changed so that tests that pass on retry cause the task to fail.
Tests that initially fail but pass on retry are considered “flaky” by Develocity. For information on how to detect flaky tests with test retry, please consult the Develocity Flaky Test Detection Guide.
Configuration
Test retry is not enabled by default. It can be enabled and configured via the retry
extension added to each Test
task by the plugin.
tasks.test {
develocity.testRetry {
maxRetries.set(3) (1)
maxFailures.set(20) (2)
failOnPassedAfterRetry.set(true)(3)
}
}
tasks.named('test', Test) {
develocity.testRetry {
maxRetries = 3 (1)
maxFailures = 20 (2)
failOnPassedAfterRetry = true (3)
}
}
1 | The maximum number of times to retry an individual test. |
2 | The maximum number of test failures allowed before retrying is disabled for the current test run. |
3 | Whether tests that initially fail and then pass on retry should fail the task. |
See the retry configuration API reference.
Retrying only some tests
By default, all tests are eligible for retrying. The filter
component of the test retry extension can be used to control which tests should be retried and which should not.
The decision to retry a test or not is based on the tests reported class name, regardless of the name of the test case or method. The annotations present or not on this class can also be used as the criteria.
tasks.test {
develocity.testRetry {
maxRetries.set(3)
filter {
// filter by qualified class name (* matches zero or more of any character)
includeClasses.add("*IntegrationTest")
excludeClasses.add("*DatabaseTest")
// filter by class level annotations
// Note: @Inherited annotations are respected
includeAnnotationClasses.add("*Retryable")
excludeAnnotationClasses.add("*NonRetryable")
}
}
}
tasks.named('test', Test) {
develocity.testRetry {
maxRetries = 3
filter {
// filter by qualified class name (* matches zero or more of any character)
includeClasses.add("*IntegrationTest")
excludeClasses.add("*DatabaseTest")
// filter by class level annotations
// Note: @Inherited annotations are respected
includeAnnotationClasses.add("*Retryable")
excludeAnnotationClasses.add("*NonRetryable")
}
}
}
Retrying on class-level
By default, individual tests are retried. The classRetry
component of the test retry extension can be used to control which test classes must be retried as a whole unit. To retry a class as a whole, the class must also satisfy the configured filter.
tasks.test {
develocity.testRetry {
maxRetries.set(3)
classRetry {
// configure by qualified class name (* matches zero or more of any character)
includeClasses.add("*StepWiseIntegrationTest")
// configure by class level annotations
// Note: @Inherited annotations are respected
includeAnnotationClasses.add("*ClassRetry")
}
}
}
tasks.named('test', Test) {
develocity.testRetry {
maxRetries.set(3)
classRetry {
// configure by qualified class name (* matches zero or more of any character)
includeClasses.add("*StepWiseIntegrationTest")
// configure by class level annotations
// Note: @Inherited annotations are respected
includeAnnotationClasses.add("*ClassRetry")
}
}
}
You can also use the ClassRetry annotation from the develocity-testing-annotations project without any additional configuration other than the dependency. |
Retrying only for CI builds
You may find that local developer builds do not benefit much from retry behaviour, particularly when those tests are invoked via your IDE. In that case we recommend enabling retry only for CI builds.
val isCiServer = System.getenv().containsKey("CI")
tasks.test {
develocity.testRetry {
if (isCiServer) { (1)
maxRetries.set(3)
maxFailures.set(20)
failOnPassedAfterRetry.set(true)
}
}
}
boolean isCiServer = System.getenv().containsKey("CI")
tasks.named('test', Test) {
develocity.testRetry {
if (isCiServer) {
maxRetries = 3
maxFailures = 20
failOnPassedAfterRetry = true
}
}
}
1 | Only configure retrying tests, when running on CI |
Migrating from Test Retry Gradle plugin
Prior to version 3.12 of this plugin, enabling test retries required the org.gradle.test-retry
plugin. It is recommended that Develocity users adopt the Develocity plugin’s retry functionality for ensured future compatibility and easier adoption of future Develocity specific features.
This plugin offers effectively the same API as the org.gradle.test-retry
plugin, making migrating simple:
-
Builds using Groovy build scripts need to just remove reference to the
org.gradle.test-retry
plugin. -
Builds using Kotlin DSL build scripts need to remove reference to the
org.gradle.test-retry
plugin and add an import ofcom.gradle.enterprise.gradleplugin.testretry.retry
.
If you cannot easily remove the org.gradle.test-retry
plugin from your build, you can disable the test retry functionality provided by the Gradle Enterprise Gradle plugin by setting the system property develocity.testretry.enabled
to false
.
The system property can be specified in the user’s or build’s gradle.properties
file (i.e. ~/.gradle/gradle.properties
).
systemProp.develocity.testretry.enabled=false
See the Build Environment chapter of the Gradle User Manual for more information on specifying system properties.
Upgrading to Gradle 6
Starting with Gradle 6, the Develocity plugin needs to be applied to the settings file of the build rather than the root project.
To upgrade, first locate where the plugin is being applied and remove it. This is likely to be in the root build.gradle
or build.gradle.kts
file, and will look similar to the following:
plugins {
id("com.gradle.develocity").version("3.18.2")
}
plugins {
id "com.gradle.develocity" version "3.18.2"
}
Then, add the following to the settings.gradle
or settings.gradle.kts
file for the build:
plugins {
id("com.gradle.develocity") version("3.18.2")
}
plugins {
id "com.gradle.develocity" version "3.18.2"
}
Any buildScan {}
configuration should be enclosed in a develocity {}
block, or be moved to the settings file inside a develocity {}
block. Please see the Gradle 6.x section above for more information.
develocity {
server.set("https://develocity.mycompany.com")
buildScan {
// tags and other settings
}
}
develocity {
server = "https://develocity.mycompany.com"
buildScan {
// tags and other settings
}
}
Gradle 4.x and earlier
Gradle versions earlier than 5.0 are not compatible with the Develocity Gradle plugin. Please refer to the (Legacy) Gradle Enterprise Gradle Plugin User Manual for information on using the “Build Scan” plugin with Gradle 4.x and earlier.
Troubleshooting
Failed background Build Scan uploads
When using background Build Scan uploading (default behaviour, 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 ~/.gradle/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 ~/.gradle/build-scan-data/<<plugin-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
Appendix A: API reference
Please see the API reference for more details about programmatic configuration of the Develocity Gradle plugin.
The Common Custom User Data Gradle Plugin provided by Gradle Inc. provides an example. This plugin can be applied directly to your project, or can serve as a template project for your own plugin implementation.
Appendix B: Captured information
The Develocity Gradle plugin 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 tasks, plugins, dependencies, names and results of tests 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 Gradle plugin and transmitted in a Build Scan.
-
Environment
-
User home (system property
'user.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 tasks, switches)
-
Build console output
-
Build failure exception messages and stacktraces
-
Project names and structure
-
Build Cache configuration
-
Background Build Scan publication
-
Gradle Daemon operational data (e.g. start time, build count)
-
Gradle lifecycle callbacks
-
File system watching
-
Configuration cache
-
Access
Build scans published to a Develocity installation are viewable by all users that can reach the server. 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: Release history
Please refer to the (Legacy) Gradle Enterprise Gradle Plugin User Manual for the release history prior to version 3.17. |
3.18.2
-
[NEW] Test Retry: Add a
failOnSkippedAfterRetry
property to control whether the test task should fail if a failed test got skipped on retry -
[FIX] Build Scan: Resource usage capturing fails silently when the build uses an incompatible JNA version
Compatible with scans.gradle.com and Develocity 2024.2 or later.
When upgrading from the Gradle Enterprise Gradle plugin, refer to the Migrating to the Develocity plugin section.
3.18.1
-
[NEW] Build Cache: Increase parallel remote build cache operation limit
-
[FIX] Build Scan: Resource usage capturing causes excessive logging on Linux when udev is absent
-
[FIX] Build Scan: Display name extraction for Java commands with multiple -jar arguments fails when resource usage capturing is enabled
Compatible with scans.gradle.com and Develocity 2024.2 or later.
When upgrading from the Gradle Enterprise Gradle plugin, refer to the Migrating to the Develocity plugin section.
3.18
-
[NEW] Build Scan: Resource usage observability in Build Scan
-
[NEW] Build Scan: Configuration cache miss reason is captured
Compatible with scans.gradle.com and Develocity 2024.2 or later.
When upgrading from the Gradle Enterprise Gradle plugin, refer to the Migrating to the Develocity plugin section.
3.17.6
-
[FIX] Test Retry: Retry TestNG tests with dependencies when using JUnit TestNG engine
-
[FIX] Test Retry: Retry failures in TestNG lifecycle methods when using JUnit TestNG engine
Compatible with scans.gradle.com and Develocity 2024.1 or later.
When upgrading from the Gradle Enterprise Gradle plugin, refer to the Migrating to the Develocity plugin section.
3.17.5
-
[NEW] Build Scan: Capture timestamped version of unique Maven snapshot dependencies
-
[FIX] Predictive Test Selection: Tests may be retried in different JVM when only using Predictive Test Selection
-
[FIX] Test Distribution: When a remote executor disconnects unexpectedly, the plugin might generate invalid executor events in the Build Scan event stream
-
[FIX] Test Distribution: Proxy configuration evaluation may fail in a multi-module project
Compatible with scans.gradle.com and Develocity 2024.1 or later.
When upgrading from the Gradle Enterprise Gradle plugin, refer to the Migrating to the Develocity plugin section.
3.17.4
-
[FIX] Test Distribution/Predictive Test Selection: Test acceleration uses wrong protocol when communicating with a proxy
Compatible with scans.gradle.com and Develocity 2024.1 or later.
When upgrading from the Gradle Enterprise Gradle plugin, refer to the Migrating to the Develocity plugin section.
3.17.3
-
[NEW] Show the origin of the deprecated Gradle Enterprise API usage on demand
-
[NEW] Test Distribution/Predictive Test Selection: Test acceleration requests respect proxy settings
-
[FIX] Test Distribution: Remote execution is sometimes not properly terminated
Compatible with scans.gradle.com and Develocity 2024.1 or later.
When upgrading from the Gradle Enterprise Gradle plugin, refer to the Migrating to the Develocity plugin section.
3.17.2
-
[NEW] Build Scan: Capturing problems are only logged when the Build Scan is published or dumped
-
[FIX] Build may fail if both Gradle Enterprise and Develocity plugins are applied
-
[FIX] Predictive Test Selection: Deprecation warnings are shown for the "mode" and "profile" properties, although the properties are not set by the user
-
[FIX] Test Distribution: Improve resiliency against connection issues
Compatible with scans.gradle.com and Develocity 2024.1 or later.
When upgrading from the Gradle Enterprise Gradle plugin, refer to the Migrating to the Develocity plugin section.
3.17.1
-
[NEW] Support muting Gradle Enterprise deprecation warnings coming from transitive dependencies
-
[FIX] Build Scan: Task for provisioning access key fails if the Develocity server is overwritten
Compatible with scans.gradle.com and Develocity 2024.1 or later.
When upgrading from the Gradle Enterprise Gradle plugin, refer to the Migrating to the Develocity plugin section.
3.17
-
[NEW] Test Distribution/Predictive Test Selection: Test Distribution and Predictive Test Selection are compatible with Gradle’s Isolated Projects
-
[NEW] Rename plugin from Gradle Enterprise to Develocity, along with new configuration DSLs, system properties, and APIs
-
[NEW] Build Scan: Insights into Gradle’s configuration caching - origin build navigation, entry size, and failure
-
[NEW] Build Scan: Develocity reliably detects when Gradle disables the remote build cache due to failures
-
[NEW] Build Scan: Develocity displays avoidance savings and a link to the origin Build Scan for all up-to-date Gradle artifact transform executions
-
[NEW] Test Distribution: Add support for debugging tests executed remotely on Test Distribution agents
-
[NEW] Test Distribution: Add support for relational operators in build requirements
-
[FIX] Build Scan: Cancelling a Gradle build may result in an incomplete Build Scan
-
[FIX] Build cache cannot be used when publishing a Build Scan® to scans.gradle.com
-
[FIX] Predictive Test Selection: Gradle displays a "no test executed" deprecation warning when no tests are selected on Gradle 8.3 and later
-
[FIX] Test Distribution: Running test tasks is incompatible with IntelliJ’s "Run with coverage" feature
-
[FIX] Test Distribution: Builds may succeed despite unsuccessful retries of location-restricted tests
Compatible with scans.gradle.com and Develocity 2024.1 or later.
When upgrading from the Gradle Enterprise Gradle plugin, refer to the Migrating to the Develocity plugin section.
Appendix D: Compatibility with Gradle Build Tool and Develocity
Compatibility between versions of Gradle, Develocity, and the Develocity Gradle plugin can be found here.
Appendix E: Verifying the signature of the plugin jar
The plugin jar is published to plugins.gradle.org alongside its signature. The public key is published to https://keys.openpgp.org. You can verify the signature as follows:
$ curl -OL https://plugins.gradle.org/m2/com/gradle/develocity-gradle-plugin/3.18.2/develocity-gradle-plugin-3.18.2.jar && \
curl -OL https://plugins.gradle.org/m2/com/gradle/develocity-gradle-plugin/3.18.2/develocity-gradle-plugin-3.18.2.jar.asc && \
gpg --keyserver keys.openpgp.org --recv-key 7B79ADD11F8A779FE90FD3D0893A028475557671 && \
gpg --verify develocity-gradle-plugin-3.18.2.jar.asc develocity-gradle-plugin-3.18.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.