From 70b52db901e6bda8d561db350505da2bdf3d87d5 Mon Sep 17 00:00:00 2001 From: Robert Stupp Date: Thu, 28 Nov 2024 14:41:00 +0100 Subject: [PATCH] Build/CI: more resilient URL fetches (#496) Add up to 4 retries to `parseJson()`, which takes a URL as a string, with a 1 second sleep. Also refactor the return type to be non-`null`. --- .../main/kotlin/publishing/configurePom.kt | 22 ++++++------- .../src/main/kotlin/publishing/util.kt | 33 +++++++++++-------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/build-logic/src/main/kotlin/publishing/configurePom.kt b/build-logic/src/main/kotlin/publishing/configurePom.kt index b1c52e325..f8ef9814f 100644 --- a/build-logic/src/main/kotlin/publishing/configurePom.kt +++ b/build-logic/src/main/kotlin/publishing/configurePom.kt @@ -135,20 +135,18 @@ internal fun configurePom(project: Project, mavenPublication: MavenPublication, fun addContributorsToPom(mavenPom: MavenPom, asfName: String, asfProjectName: String) = mavenPom.run { contributors { - val contributors: List>? = + val contributors: List> = parseJson("https://api.github.com/repos/apache/$asfName/contributors?per_page=1000") - if (contributors != null) { - contributors - .filter { contributor -> contributor["type"] == "User" } - .forEach { contributor -> - contributor { - name.set(contributor["login"] as String) - url.set(contributor["url"] as String) - organization.set("$asfProjectName, GitHub contributors") - organizationUrl.set("https://github.com/apache/$asfName") - } + contributors + .filter { contributor -> contributor["type"] == "User" } + .forEach { contributor -> + contributor { + name.set(contributor["login"] as String) + url.set(contributor["url"] as String) + organization.set("$asfProjectName, GitHub contributors") + organizationUrl.set("https://github.com/apache/$asfName") } - } + } } } diff --git a/build-logic/src/main/kotlin/publishing/util.kt b/build-logic/src/main/kotlin/publishing/util.kt index d25afc45c..e8c827a9e 100644 --- a/build-logic/src/main/kotlin/publishing/util.kt +++ b/build-logic/src/main/kotlin/publishing/util.kt @@ -81,20 +81,27 @@ internal fun unsafeCast(o: Any?): T { @Suppress("UNCHECKED_CAST") return o as T } -internal fun parseJson(url: String): T? { - try { - return unsafeCast(JsonSlurper().parse(URI(url).toURL())) as T - } catch (e: JsonException) { - if (e.cause is FileNotFoundException) { - return null +internal fun parseJson(url: String): T { + var attempt = 0 + while (true) { + try { + return unsafeCast(JsonSlurper().parse(URI(url).toURL())) as T + } catch (e: JsonException) { + if (e.cause is FileNotFoundException) { + throw e + } + if (attempt == 5) { + throw e + } + Thread.sleep(1000L) } - throw e + attempt++ } } internal fun fetchAsfProjectName(apacheId: String): String { val projectsAll: Map> = - parseJson("https://whimsy.apache.org/public/public_ldap_projects.json")!! + parseJson("https://whimsy.apache.org/public/public_ldap_projects.json") val projects = unsafeCast>>(projectsAll["projects"]) val project = projects[apacheId] @@ -106,7 +113,7 @@ internal fun fetchAsfProjectName(apacheId: String): String { internal fun fetchProjectPeople(apacheId: String): ProjectPeople { val projectsAll: Map> = - parseJson("https://whimsy.apache.org/public/public_ldap_projects.json")!! + parseJson("https://whimsy.apache.org/public/public_ldap_projects.json") val projects = unsafeCast>>(projectsAll["projects"]) val project = projects[apacheId] @@ -135,7 +142,7 @@ internal fun fetchProjectPeople(apacheId: String): ProjectPeople { val bugDatabase: String if (isPodlingCurrent) { val podlingsAll: Map> = - parseJson("https://whimsy.apache.org/public/public_podlings.json")!! + parseJson("https://whimsy.apache.org/public/public_podlings.json") val podlings = unsafeCast>>(podlingsAll["podling"]) val podling = podlings[apacheId] @@ -158,14 +165,14 @@ internal fun fetchProjectPeople(apacheId: String): ProjectPeople { mentors.forEach { member -> peopleProjectRoles[member]!!.add("Mentor") } } else { val tlpPrj: Map = - parseJson("https://projects.apache.org/json/projects/$apacheId.json")!! + parseJson("https://projects.apache.org/json/projects/$apacheId.json") website = tlpPrj["homepage"] as String repository = (unsafeCast(tlpPrj["repository"]) as List)[0] bugDatabase = tlpPrj["bug-database"] as String licenseUrl = tlpPrj["license"] as String val committeesAll: Map> = - parseJson("https://whimsy.apache.org/public/committee-info.json")!! + parseJson("https://whimsy.apache.org/public/committee-info.json") val committees = unsafeCast>>(committeesAll["committees"]) val committee = unsafeCast>(committees[apacheId]) val pmcChair = unsafeCast>>(committee["chair"]) @@ -175,7 +182,7 @@ internal fun fetchProjectPeople(apacheId: String): ProjectPeople { } val peopleNames: Map> = - parseJson("https://whimsy.apache.org/public/public_ldap_people.json")!! + parseJson("https://whimsy.apache.org/public/public_ldap_people.json") val people: Map> = unsafeCast(peopleNames["people"]) as Map> val peopleList =