(formerly gradle-enterprise-api-kotlin
)
A Kotlin library to access the Develocity API, easy to use from:
val api = DevelocityApi.newInstance()
api.buildsApi.getBuildsFlow(fromInstant = 0, query = "buildStartTime<-1d").forEach {
println(it)
}
How is this different from the official samples?
The official samples are an excellent demo of the API inside a full-fledged Java project.
Among other things, you might not want to maintain an OpenAPI code generation setup.
Even if you do, you'll find it generates less-than-ideal or even failing code depending on your openapi-generator
configuration.
This library fixes those issues in generated code, implements paging, caching and env-based configuration for you, while providing a JAR that's ready-to-use from any project, script or notebook.
Set up once and use the library from any notebook, script or project:
DEVELOCITY_URL
: the URL of your Develocity instanceDEVELOCITY_API_CACHE_ENABLED
(optional, off by default): enables caching for some requests (see caveats)- An access key in one of the supported locations
Supported access key locations
Access key support matches that of official tooling: the Develocity Gradle Plugin and Maven Extension. If you've already provisioned a key for your build to connect to Develocity, there's probably no action needed. Supported locations, in order of precedence:
- a provider function as
Config.accessKey
(see optional setup) - official tooling locations with value in format
host=key
, e.g.DEVELOCITY_ACCESS_KEY='foo.com=my-key'
:DEVELOCITY_ACCESS_KEY
GRADLE_ENTERPRISE_ACCESS_KEY
- File
$GRADLE_USER_HOME/.gradle/develocity/keys.properties
, or~/.gradle/develocity/keys.properties
ifGRADLE_USER_HOME
is not set - File
~/.m2/.develocity/keys.properties
Refer to the Develocity Gradle Plugin User Manual or Maven Extension User Manual for details on these variables and files, including support for keys of multiple hosts.
Add to a Jupyter notebook
%useLatestDescriptors
%use develocity-api-kotlin(version=2024.3.0)
Add to a Kotlin script
@file:DependsOn("com.gabrielfeo:develocity-api-kotlin:2024.3.0")
Add to a Kotlin project
dependencies {
implementation("com.gabrielfeo:develocity-api-kotlin:2024.3.0")
}
The DevelocityApi
interface represents the Develocity REST API. It contains
all the APIs exactly as listed in the REST API Manual:
interface DevelocityApi {
val buildsApi: BuildsApi
val testsApi: TestsApi
val buildCacheApi: BuildCacheApi
val projectsApi: ProjectsApi
val metaApi: MetaApi
val testDistributionApi: TestDistributionApi
val authApi: AuthApi
// ...
}
For example, BuildsApi
contains all endpoints under /api/builds/
:
BuildsApi.getBuilds
:GET /api/builds
BuildsApi.getGradleAttributes
:GET /api/builds/{id}/gradle-attributes
- ...
API methods are generated as suspend functions. For most cases like scripts and notebooks, simply use runBlocking:
runBlocking {
val builds: List<Build> = api.buildsApi.getBuilds(fromInstant = 0, query = "...")
}
HTTP caching is available, which can speed up queries significantly, but is
off by default. Enable by simply setting DEVELOCITY_API_CACHE_ENABLED
to true
. See
CacheConfig
for caveats.
Explore the library's convenience extensions:
com.gabrielfeo.develocity.api.extension
.
By default, the API's most common endpoint, /api/builds
, is paginated. The library provides a
getBuildsFlow
extension to handle paging under-the-hood and yield all builds as you collect
them:
val builds: Flow<Build> = api.buildsApi.getBuildsFlow(fromInstant = 0, query = "...")
builds.collect {
// ...
}
By default, the library keeps some of its resources (like threads) alive until idle, in case they're needed again. This is an optimization of OkHttp. If you're working on a notebook or have a long-living program that fetches builds continuosly, no shutdown is needed.
val api = DevelocityApi.newInstance()
while (true) {
delay(2.minutes)
processNewBuilds(api.buildsApi.getBuildsFlow(query = "..."))
// Don't worry about shutdown
}
In other cases (i.e. fetching some builds and exiting), you might want to call
DevelocityApi.shutdown()
so that the program exits immediately:
val api = DevelocityApi.newInstance()
printMetrics(api.buildsApi.getBuildsFlow(query = "..."))
// Call shutdown if you expect the program to exit now
api.shutdown()
The javadoc of API interfaces and models, such as BuildsApi
and GradleAttributes
,
matches the REST API Manual exactly. Both these classes and Gradle's own manual are generated
from the same OpenAPI spec.
See docs/Logging.md for how to configure logging in projects, scripts, and notebooks.
Creating a custom Config
allows you to change library settings via code instead of
environment variables. It also lets you share resources between the library's OkHttpClient
and
your own. For example:
val config = Config(
develocityUrl = "https://ge.mycompany.com/",
accessKey = { vault.getDevelocityAccessKey() },
clientBuilder = existingClient.newBuilder(),
)
val api = DevelocityApi.newInstance(config)
api.buildsApi.getBuilds(fromInstant = yesterdayMilli)
See the Config
documentation for more.
- Use JDK 8 or 14+ to run, if you want to avoid the "illegal reflective access" warning about Retrofit
- All classes live in these packages. If you need to make small edits to scripts where there's no auto-complete, wildcard imports can be used (in notebooks, they're added automatically):
import com.gabrielfeo.develocity.api.*
import com.gabrielfeo.develocity.api.model.*
import com.gabrielfeo.develocity.api.model.extension.*
If you run into any problems, please open an issue to make it visible to maintainers and other users. Contributions are always welcome, although it's recommended to open an issue first. For general discussions or questions, feel free to reach out to maintainers on the Gradle Community Slack.