Last active
July 9, 2025 14:19
-
-
Save gabrielfeo/8560e38e2469758cd168252975172e4e to your computer and use it in GitHub Desktop.
Get time of last published build scan by user from a Develocity instance. Prefer the "*-specific-users.main.kts" variant if your usernames are known beforehand or are predictable (e.g. derived from the user's work email address), as it'll be much faster.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env kotlin | |
/* | |
This script demonstrates how to retrieve the last published build time for each user | |
provided via stdin, using the Develocity REST API to fetch build information. | |
(https://docs.gradle.com/develocity/api-manual/) | |
DISCLAIMER: develocity-api-kotlin is a third-party library, not an official Gradle product. | |
(https://github.com/gabrielfeo/develocity-api-kotlin) | |
To run it, install the Kotlin compiler CLI (e.g. brew install kotlin) and set variables: | |
export DEVELOCITY_API_URL="https://develocity.example.com/api/" | |
export DEVELOCITY_API_TOKEN="your_access_key_here" | |
The "API token" must be a Develocity access key from a user with API permission. It should | |
not be prefixed with the hostname, key only. | |
USAGE: | |
cat users.txt | ./last-publish-by-user-specific-users.main.kts | |
*/ | |
@file:DependsOn("com.gabrielfeo:develocity-api-kotlin:2024.3.0") | |
import com.gabrielfeo.develocity.api.* | |
import com.gabrielfeo.develocity.api.model.* | |
import com.gabrielfeo.develocity.api.extension.* | |
import kotlinx.coroutines.* | |
import kotlinx.coroutines.flow.* | |
import java.time.* | |
import java.util.Scanner | |
import kotlin.system.exitProcess | |
val api = DevelocityApi.newInstance() | |
suspend fun getLastPublishedBuildOrNull(user: String): Build? = | |
api.buildsApi.getBuilds(query = "user:$user", reverse = true, maxBuilds = 1) | |
.singleOrNull() | |
suspend fun printForPredefinedUsers(users: Sequence<String>) { | |
val buildsByUser = users.associateWith { getLastPublishedBuildOrNull(it) } | |
buildsByUser.forEach { (user, lastBuild) -> | |
val date = lastBuild?.availableAt?.let(Instant::ofEpochMilli).toString() | |
println("%-30s | %-30s | %s".format(user, date, lastBuild?.id)) | |
} | |
} | |
fun main() = runBlocking { | |
if (args.any() || System.`in`.available() <= 0) { | |
System.err.println("USAGE: cat users.txt | ./last-publish-by-user-specific-users.main.kts") | |
exitProcess(1) | |
} | |
val users = generateSequence { readlnOrNull() }.filter { it.isNotBlank() } | |
printForPredefinedUsers(users) | |
api.shutdown() | |
} | |
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env kotlin | |
/* | |
This script demonstrates how to retrieve the last published build time for each unique | |
user in the past given <days>, using the Develocity REST API to fetch build information. | |
This may take a while depending on the volume of builds in your Develocity instance. | |
Prefer the other script which fetches just the last build for each user, if your usernames | |
are known beforehand. | |
(https://docs.gradle.com/develocity/api-manual/) | |
DISCLAIMER: develocity-api-kotlin is a third-party library, not an official Gradle product. | |
(https://github.com/gabrielfeo/develocity-api-kotlin) | |
To run it, install the Kotlin compiler CLI (e.g. brew install kotlin) and set variables: | |
export DEVELOCITY_API_URL="https://develocity.example.com/api/" | |
export DEVELOCITY_API_TOKEN="your_access_key_here" | |
The "API token" must be a Develocity access key from a user with API permission. It should | |
not be prefixed with the hostname, key only. | |
USAGE: | |
./last-publish-by-user.main.kts <days> | |
*/ | |
@file:DependsOn("com.gabrielfeo:develocity-api-kotlin:2024.3.0") | |
import com.gabrielfeo.develocity.api.* | |
import com.gabrielfeo.develocity.api.model.* | |
import com.gabrielfeo.develocity.api.extension.* | |
import kotlinx.coroutines.* | |
import kotlinx.coroutines.flow.* | |
import java.time.* | |
import kotlin.system.exitProcess | |
val api = DevelocityApi.newInstance() | |
fun getAllBuildsOfPastDays(days: Int): Flow<Build> = | |
api.buildsApi.getBuildsFlow( | |
fromInstant = 0, | |
query = "buildStartTime<-${days}d", | |
// Request details about each build | |
// https://gabrielfeo.github.io/develocity-api-kotlin/library/com.gabrielfeo.develocity.api.model/-gradle-attributes | |
models = listOf(BuildModelName.gradleAttributes), | |
) | |
suspend fun printBuildsForAllUsers(pastDays: Int) { | |
getAllBuildsOfPastDays(pastDays) | |
.toList() | |
.groupBy { it.models?.gradleAttributes?.model?.environment?.username } | |
.mapValues { (_, builds) -> builds.lastOrNull() } | |
.forEach { (user, lastBuild) -> | |
val date = lastBuild?.availableAt?.let(Instant::ofEpochMilli).toString() | |
println("%-30s | %-30s | %s".format(user, date, lastBuild?.id)) | |
} | |
} | |
fun main() = runBlocking { | |
val days = args.singleOrNull()?.toIntOrNull() ?: run { | |
System.err.println("USAGE: ./last-publish-by-user.main.kts <days>") | |
exitProcess(1) | |
} | |
printBuildsForAllUsers(pastDays = days) | |
api.shutdown() | |
} | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment