Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import io.ktor.server.response.respondText
import io.ktor.server.routing.routing
import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.Tag
import io.micrometer.prometheusmetrics.PrometheusConfig
import io.micrometer.prometheusmetrics.PrometheusMeterRegistry
import java.time.Duration
Expand Down Expand Up @@ -65,7 +67,12 @@ fun main() {

fun Application.appModule(
buildVersionArtifacts: suspend (ActionCoords, HttpClient) -> VersionArtifacts?,
buildPackageArtifacts: suspend (ActionCoords, String, (Collection<ActionCoords>) -> Unit) -> Map<String, String>,
buildPackageArtifacts: suspend (
ActionCoords,
String,
(Collection<ActionCoords>) -> Unit,
MeterRegistry,
) -> Map<String, String>,
getGithubAuthToken: () -> String,
) {
val httpClient =
Expand All @@ -75,6 +82,7 @@ fun Application.appModule(
val counter =
prometheusRegistry.counter(
"calls_to_github",
listOf(Tag.of("type", "static")),
)
counter.increment()
}
Expand Down Expand Up @@ -106,7 +114,12 @@ private fun buildBindingsCache(
@Suppress("ktlint:standard:function-signature") // Conflict with detekt.
private fun buildMetadataCache(
bindingsCache: LoadingCache<ActionCoords, CachedVersionArtifact>,
buildPackageArtifacts: suspend (ActionCoords, String, (Collection<ActionCoords>) -> Unit) -> Map<String, String>,
buildPackageArtifacts: suspend (
ActionCoords,
String,
(Collection<ActionCoords>) -> Unit,
MeterRegistry,
) -> Map<String, String>,
getGithubAuthToken: () -> String,
): LoadingCache<ActionCoords, CachedMetadataArtifact> =
Caffeine
Expand All @@ -118,6 +131,7 @@ private fun buildMetadataCache(
it,
getGithubAuthToken(),
{ coords -> prefetchBindingArtifacts(coords, bindingsCache) },
prometheusRegistry,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ArtifactRoutesTest :
)
},
// Irrelevant for these tests.
buildPackageArtifacts = { _, _, _ -> emptyMap() },
buildPackageArtifacts = { _, _, _, _ -> emptyMap() },
getGithubAuthToken = { "" },
)
}
Expand All @@ -51,7 +51,7 @@ class ArtifactRoutesTest :
appModule(
buildVersionArtifacts = { _, _ -> null },
// Irrelevant for these tests.
buildPackageArtifacts = { _, _, _ -> emptyMap() },
buildPackageArtifacts = { _, _, _, _ -> emptyMap() },
getGithubAuthToken = { "" },
)
}
Expand All @@ -71,7 +71,7 @@ class ArtifactRoutesTest :
appModule(
buildVersionArtifacts = { _, _ -> error("An internal error occurred!") },
// Irrelevant for these tests.
buildPackageArtifacts = { _, _, _ -> emptyMap() },
buildPackageArtifacts = { _, _, _, _ -> emptyMap() },
getGithubAuthToken = { "" },
)
}
Expand All @@ -98,7 +98,7 @@ class ArtifactRoutesTest :
appModule(
buildVersionArtifacts = mockBuildVersionArtifacts,
// Irrelevant for these tests.
buildPackageArtifacts = { _, _, _ -> emptyMap() },
buildPackageArtifacts = { _, _, _, _ -> emptyMap() },
getGithubAuthToken = { "" },
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import io.ktor.http.HttpStatusCode
import io.ktor.server.testing.testApplication
import io.micrometer.core.instrument.MeterRegistry
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
Expand All @@ -20,7 +21,7 @@ class MetadataRoutesTest :
// Given
application {
appModule(
buildPackageArtifacts = { _, _, _ ->
buildPackageArtifacts = { _, _, _, _ ->
mapOf("maven-metadata.xml" to "Some XML contents")
},
getGithubAuthToken = { "some-token" },
Expand Down Expand Up @@ -48,7 +49,7 @@ class MetadataRoutesTest :
// Given
application {
appModule(
buildPackageArtifacts = { _, _, _ ->
buildPackageArtifacts = { _, _, _, _ ->
emptyMap()
},
getGithubAuthToken = { "some-token" },
Expand All @@ -75,7 +76,7 @@ class MetadataRoutesTest :
// Given
application {
appModule(
buildPackageArtifacts = { _, _, _ ->
buildPackageArtifacts = { _, _, _, _ ->
error("An internal error occurred!")
},
getGithubAuthToken = { "some-token" },
Expand Down Expand Up @@ -106,9 +107,10 @@ class MetadataRoutesTest :
ActionCoords,
String,
(Collection<ActionCoords>) -> Unit,
MeterRegistry?,
) -> Map<String, String>,
>()
every { mockBuildPackageArtifacts(any(), any(), any()) } throws
every { mockBuildPackageArtifacts(any(), any(), any(), any()) } throws
Exception("An internal error occurred!") andThen
mapOf("maven-metadata.xml" to "Some XML contents")
application {
Expand All @@ -135,7 +137,7 @@ class MetadataRoutesTest :
// Then
response2.status shouldBe HttpStatusCode.OK

verify(exactly = 2) { mockBuildPackageArtifacts(any(), any(), any()) }
verify(exactly = 2) { mockBuildPackageArtifacts(any(), any(), any(), any()) }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,24 @@ import io.github.typesafegithub.workflows.actionbindinggenerator.domain.ActionCo
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.SignificantVersion.FULL
import io.github.typesafegithub.workflows.shared.internal.fetchAvailableVersions
import io.github.typesafegithub.workflows.shared.internal.model.Version
import io.micrometer.core.instrument.MeterRegistry
import java.time.format.DateTimeFormatter

private val logger = logger { }

internal suspend fun ActionCoords.buildMavenMetadataFile(
githubAuthToken: String,
meterRegistry: MeterRegistry? = null,
fetchAvailableVersions: suspend (
owner: String,
name: String,
githubAuthToken: String?,
meterRegistry: MeterRegistry?,
) -> Either<String, List<Version>> = ::fetchAvailableVersions,
prefetchBindingArtifacts: (Collection<ActionCoords>) -> Unit = {},
): String? {
val availableVersions =
fetchAvailableVersions(owner, name, githubAuthToken)
fetchAvailableVersions(owner, name, githubAuthToken, meterRegistry)
.getOrElse {
logger.error { it }
emptyList()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package io.github.typesafegithub.workflows.mavenbinding

import io.github.typesafegithub.workflows.actionbindinggenerator.domain.ActionCoords
import io.micrometer.core.instrument.MeterRegistry

suspend fun buildPackageArtifacts(
actionCoords: ActionCoords,
githubAuthToken: String,
prefetchBindingArtifacts: (Collection<ActionCoords>) -> Unit,
meterRegistry: MeterRegistry,
): Map<String, String> {
val mavenMetadata =
actionCoords.buildMavenMetadataFile(
githubAuthToken = githubAuthToken,
prefetchBindingArtifacts = prefetchBindingArtifacts,
meterRegistry = meterRegistry,
) ?: return emptyMap()
return mapOf(
"maven-metadata.xml" to mavenMetadata,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import io.github.typesafegithub.workflows.shared.internal.model.Version
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.nulls.shouldBeNull
import io.kotest.matchers.shouldBe
import io.micrometer.core.instrument.MeterRegistry
import java.time.ZonedDateTime

class MavenMetadataBuildingTest :
Expand All @@ -26,7 +27,8 @@ class MavenMetadataBuildingTest :
String,
String,
String?,
) -> Either<String, List<Version>> = { _, _, _ ->
MeterRegistry?,
) -> Either<String, List<Version>> = { _, _, _, _ ->
listOf(
Version(version = "v3-beta", dateProvider = { ZonedDateTime.parse("2024-07-01T00:00:00Z") }),
Version(version = "v2", dateProvider = { ZonedDateTime.parse("2024-05-01T00:00:00Z") }),
Expand Down Expand Up @@ -70,7 +72,8 @@ class MavenMetadataBuildingTest :
String,
String,
String?,
) -> Either<String, List<Version>> = { _, _, _ ->
MeterRegistry?,
) -> Either<String, List<Version>> = { _, _, _, _ ->
listOf(
Version(version = "v1.1", dateProvider = { ZonedDateTime.parse("2024-03-07T00:00:00Z") }),
Version(version = "v1.1.0", dateProvider = { ZonedDateTime.parse("2024-03-07T00:00:00Z") }),
Expand All @@ -95,7 +98,8 @@ class MavenMetadataBuildingTest :
String,
String,
String?,
) -> Either<String, List<Version>> = { _, _, _ ->
MeterRegistry?,
) -> Either<String, List<Version>> = { _, _, _, _ ->
emptyList<Version>().right()
}

Expand All @@ -115,7 +119,8 @@ class MavenMetadataBuildingTest :
String,
String,
String?,
) -> Either<String, List<Version>> = { owner, name, _ ->
MeterRegistry?,
) -> Either<String, List<Version>> = { owner, name, _, _ ->
listOf(
Version(version = "v3-beta", dateProvider = { ZonedDateTime.parse("2024-07-01T00:00:00Z") }),
Version(version = "v2", dateProvider = { ZonedDateTime.parse("2024-05-01T00:00:00Z") }),
Expand Down
1 change: 1 addition & 0 deletions shared-internal/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies {
// we cannot use a BOM due to limitation in kotlin scripting when resolving the transitive KMM variant dependencies
// note: see https://youtrack.jetbrains.com/issue/KT-67618
api("io.ktor:ktor-client-core:3.3.3")
api("io.micrometer:micrometer-core:1.15.5")
implementation("io.ktor:ktor-client-cio:3.3.3")
implementation("io.ktor:ktor-client-content-negotiation:3.3.3")
implementation("io.ktor:ktor-client-logging:3.3.3")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@ import io.github.oshai.kotlinlogging.KotlinLogging.logger
import io.github.typesafegithub.workflows.shared.internal.model.Version
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.plugins.HttpSend
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.logging.LogLevel.ALL
import io.ktor.client.plugins.logging.Logger
import io.ktor.client.plugins.logging.Logging
import io.ktor.client.plugins.plugin
import io.ktor.client.request.bearerAuth
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import io.ktor.http.isSuccess
import io.ktor.serialization.kotlinx.json.json
import io.micrometer.core.instrument.MeterRegistry
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import java.time.ZonedDateTime
Expand All @@ -26,25 +29,29 @@ suspend fun fetchAvailableVersions(
owner: String,
name: String,
githubAuthToken: String?,
meterRegistry: MeterRegistry? = null,
githubEndpoint: String = "https://api.github.com",
): Either<String, List<Version>> =
either {
buildHttpClient().use { httpClient ->
buildHttpClient(meterRegistry = meterRegistry).use { httpClient ->
return listOf(
apiTagsUrl(githubEndpoint = githubEndpoint, owner = owner, name = name),
apiBranchesUrl(githubEndpoint = githubEndpoint, owner = owner, name = name),
).flatMap { url -> fetchGithubRefs(url, githubAuthToken, httpClient).bind() }
.versions(githubAuthToken)
.versions(githubAuthToken, meterRegistry = meterRegistry)
}
}

private fun List<GithubRef>.versions(githubAuthToken: String?): Either<String, List<Version>> =
private fun List<GithubRef>.versions(
githubAuthToken: String?,
meterRegistry: MeterRegistry?,
): Either<String, List<Version>> =
either {
[email protected] { githubRef ->
val version = githubRef.ref.substringAfterLast("/")
Version(version) {
val response =
buildHttpClient().use { httpClient ->
buildHttpClient(meterRegistry = meterRegistry).use { httpClient ->
httpClient
.get(urlString = githubRef.`object`.url) {
if (githubAuthToken != null) {
Expand Down Expand Up @@ -122,7 +129,7 @@ private data class Person(
val date: String,
)

private fun buildHttpClient() =
private fun buildHttpClient(meterRegistry: MeterRegistry?) =
HttpClient {
val klogger = logger
install(Logging) {
Expand All @@ -141,4 +148,21 @@ private fun buildHttpClient() =
},
)
}
}.apply {
if (meterRegistry != null) {
plugin(HttpSend).intercept { request ->
if (request.url.host == "api.github.com") {
val counter =
meterRegistry.counter(
"calls_to_github",
listOf(
io.micrometer.core.instrument.Tag
.of("type", "api"),
),
)
counter.increment()
}
execute(request)
}
}
}
Loading