Giter Site home page Giter Site logo

gabrielfeo / develocity-api-kotlin Goto Github PK

View Code? Open in Web Editor NEW
15.0 3.0 0.0 4.56 MB

A library to use the Develocity API in Kotlin notebooks and more

Home Page: https://gabrielfeo.github.io/develocity-api-kotlin/

License: MIT License

Kotlin 100.00%
gradle gradle-enterprise kotlin openapi-generator jupyter jupyter-notebooks develocity kotlin-notebook kotlin-scripts

develocity-api-kotlin's Introduction

Develocity API Kotlin

Maven Central Javadoc

(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)
}

The library takes care of caching under the hood (opt-in) and provides some convenience extensions.

Setup

Set up environment variables and use the library from any notebook, script or project:

Setup snippets

Add to a Jupyter notebook
%useLatestDescriptors
%use develocity-api-kotlin(version=2024.1.1)
Add to a Kotlin script
@file:DependsOn("com.gabrielfeo:develocity-api-kotlin:2024.1.1")
Add to a Kotlin project
dependencies {
  implementation("com.gabrielfeo:develocity-api-kotlin:2024.1.1")
}

Usage

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/:

Calling the APIs

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 = "...")
}

Caching

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.

Extensions

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 {
  // ...
}

Shutdown

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()

Working samples

Documentation

Javadoc

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.

Optional setup

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(
  apiUrl = "https://ge.mycompany.com/api/",
  apiToken = { vault.getGeApiToken() },
  clientBuilder = existingClient.newBuilder(),
)
val api = DevelocityApi.newInstance(config)
api.buildsApi.getBuilds(fromInstant = yesterdayMilli)

See the Config documentation for more.

More info

  • 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.*

develocity-api-kotlin's People

Contributors

dependabot[bot] avatar gabrielfeo avatar github-actions[bot] avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

develocity-api-kotlin's Issues

Support for Gradle Enterprise 2023.4

Hi,

I recently saw your talk about using the Gradle Enterprise (Develocity) API to extract interesting metrics. I noticed that the library doesn't yet support some of the endpoints that were mentioned in your talk, specifically the ones regarding flaky tests. As those endpoints are out of beta now, I was wondering if you had any plans to add support for Gradle 2023.4.

Cheers!

Use in Linux fails when providing a token via environment variable

Trying to use it in Linux with GRADLE_ENTERPRISE_API_TOKEN fails first due to having no LOGNAME variable:

null
java.lang.NullPointerException
	at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1090)
	at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
	at com.gabrielfeo.gradle.enterprise.api.internal.RealKeychain.get(Keychain.kt:18)
	at com.gabrielfeo.gradle.enterprise.api.Options$GradleEnterpriseInstanceOptions$token$1.invoke(Options.kt:56)
	at com.gabrielfeo.gradle.enterprise.api.Options$GradleEnterpriseInstanceOptions$token$1.invoke(Options.kt:55)
	at com.gabrielfeo.gradle.enterprise.api.internal.OkHttpClientKt.addNetworkInterceptors(OkHttpClient.kt:49)
	at com.gabrielfeo.gradle.enterprise.api.internal.OkHttpClientKt.buildOkHttpClient(OkHttpClient.kt:27)
	at com.gabrielfeo.gradle.enterprise.api.internal.OkHttpClientKt$okHttpClient$2.invoke(OkHttpClient.kt:16)
	at com.gabrielfeo.gradle.enterprise.api.internal.OkHttpClientKt$okHttpClient$2.invoke(OkHttpClient.kt:15)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at com.gabrielfeo.gradle.enterprise.api.internal.OkHttpClientKt.getOkHttpClient(OkHttpClient.kt:15)
	at com.gabrielfeo.gradle.enterprise.api.internal.RetrofitKt$retrofit$2.invoke(Retrofit.kt:15)
	at com.gabrielfeo.gradle.enterprise.api.internal.RetrofitKt$retrofit$2.invoke(Retrofit.kt:12)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at com.gabrielfeo.gradle.enterprise.api.internal.RetrofitKt.getRetrofit(Retrofit.kt:12)
	at com.gabrielfeo.gradle.enterprise.api.ApiKt$gradleEnterpriseApi$2.invoke(Api.kt:11)
	at com.gabrielfeo.gradle.enterprise.api.ApiKt$gradleEnterpriseApi$2.invoke(Api.kt:10)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at com.gabrielfeo.gradle.enterprise.api.ApiKt.getGradleEnterpriseApi(Api.kt:10)

After setting a dummy LOGNAME, it'll still fail because ProcessBuilder throws an IOException for command not found, instead of just setting status to 127:

Cannot run program "security": error=2, No such file or directory
java.io.IOException: Cannot run program "security": error=2, No such file or directory
	at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
	at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
	at com.gabrielfeo.gradle.enterprise.api.internal.RealKeychain.get(Keychain.kt:18)
	at com.gabrielfeo.gradle.enterprise.api.Options$GradleEnterpriseInstanceOptions$token$1.invoke(Options.kt:56)
	at com.gabrielfeo.gradle.enterprise.api.Options$GradleEnterpriseInstanceOptions$token$1.invoke(Options.kt:55)
	at com.gabrielfeo.gradle.enterprise.api.internal.OkHttpClientKt.addNetworkInterceptors(OkHttpClient.kt:49)
	at com.gabrielfeo.gradle.enterprise.api.internal.OkHttpClientKt.buildOkHttpClient(OkHttpClient.kt:27)
	at com.gabrielfeo.gradle.enterprise.api.internal.OkHttpClientKt$okHttpClient$2.invoke(OkHttpClient.kt:16)
	at com.gabrielfeo.gradle.enterprise.api.internal.OkHttpClientKt$okHttpClient$2.invoke(OkHttpClient.kt:15)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at com.gabrielfeo.gradle.enterprise.api.internal.OkHttpClientKt.getOkHttpClient(OkHttpClient.kt:15)
	at com.gabrielfeo.gradle.enterprise.api.internal.RetrofitKt$retrofit$2.invoke(Retrofit.kt:15)
	at com.gabrielfeo.gradle.enterprise.api.internal.RetrofitKt$retrofit$2.invoke(Retrofit.kt:12)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at com.gabrielfeo.gradle.enterprise.api.internal.RetrofitKt.getRetrofit(Retrofit.kt:12)
	at com.gabrielfeo.gradle.enterprise.api.ApiKt$gradleEnterpriseApi$2.invoke(Api.kt:11)
	at com.gabrielfeo.gradle.enterprise.api.ApiKt$gradleEnterpriseApi$2.invoke(Api.kt:10)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at com.gabrielfeo.gradle.enterprise.api.ApiKt.getGradleEnterpriseApi(Api.kt:10)

Rename to Develocity

It was announced that Gradle Enterprise would be renamed to Develocity. Starting with version 2024.1 that was just released, the product itself is using the new name, so this library should as well.

  • Change pom, including repository URL
  • Add relocation pom
  • Change publish workflow to publish relocation pom
  • Replace
    • gradle enterprise
    • gradle-enterprise
    • gradleEnterprise
    • GE
    • gradle_enterprise (env vars)
    • gradle.enterprise (package name)
  • Rename artifact
  • Change environment variables to DEVELOCITY_
  • Fix bad replace: 'develocitytlin'
  • Add library descriptor with new name and imports for Kotlin Jupyter
  • Rename GitHub repository
  • Publish javadoc of last gradle-enterprise version at the fallback GH pages repo, to keep old links working (done)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.