Skip to content

Commit 351dc07

Browse files
Merge remote-tracking branch 'private/main-30-06' into feature/s3-kms-key
2 parents 543dabc + acdccae commit 351dc07

File tree

70 files changed

+1144
-496
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1144
-496
lines changed

.github/workflows/stale.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
stale:
2323
runs-on: ubuntu-24.04
2424
steps:
25-
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008
25+
- uses: actions/stale@65d1d4804d3060875fff9f9fa8a49e27f71ce7f0
2626
with:
2727
days-before-close: 5
2828
days-before-stale: 30

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ request adding CHANGELOG notes for breaking (!) changes and possibly other secti
3939

4040
### Changes
4141

42+
- `client.region` is no longer considered a "credential" property (related to Iceberg REST Catalog API).
43+
4244
### Deprecations
4345

4446
### Fixes

build-logic/src/main/kotlin/polaris-reproducible.gradle.kts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,15 @@
2222
tasks.withType<AbstractArchiveTask>().configureEach {
2323
isPreserveFileTimestamps = false
2424
isReproducibleFileOrder = true
25+
26+
dirPermissions { unix("755") }
27+
filePermissions {
28+
// do not force the "execute" bit in case the file _is_ executable
29+
user.read = true
30+
user.write = true
31+
group.read = true
32+
group.write = false
33+
other.read = true
34+
other.write = false
35+
}
2536
}

build-logic/src/main/kotlin/publishing/configurePom.kt

Lines changed: 20 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import org.gradle.api.Project
2424
import org.gradle.api.Task
2525
import org.gradle.api.artifacts.component.ModuleComponentSelector
2626
import org.gradle.api.provider.Provider
27-
import org.gradle.api.publish.maven.MavenPom
2827
import org.gradle.api.publish.maven.MavenPublication
2928
import org.gradle.internal.extensions.stdlib.capitalized
3029

@@ -36,21 +35,22 @@ import org.gradle.internal.extensions.stdlib.capitalized
3635
* consumable by Maven.
3736
*
3837
* The root project generates the parent pom, containing all the necessary elements to pass Sonatype
39-
* validation and some more information like `<developers>` and `<contributors>`. Most of the
40-
* information is taken from publicly consumable Apache project information from
41-
* `https://projects.apache.org/json/projects/<project-name>>.json`. `<developers>` contains all
42-
* (P)PMC members and committers from that project info JSON, ordered by real name. `<contributors>`
43-
* is taken from GitHub's
44-
* `https://api.github.com/repos/apache/<project-name>/contributors?per_page=1000` endpoint to give
45-
* all contributors credit, ordered by number of contributions (as returned by that endpoint).
38+
* validation. Most of the information is taken from publicly consumable Apache project information
39+
* from `https://projects.apache.org/json/projects/<project-name>.json`. Changes to the Apache
40+
* project metadata, including podling information, will break the reproducibility of the build.
41+
*
42+
* Developer and contributor elements are intentionally *not* included in the POM. Such information
43+
* is not considered stable (enough) to satisfy reproducible build requirements. The generated POM
44+
* must be exactly the same when built by a release manager and by someone else to verify the built
45+
* artifact(s).
4646
*/
4747
internal fun configurePom(project: Project, mavenPublication: MavenPublication, task: Task) =
4848
mavenPublication.run {
4949
val e = project.extensions.getByType(PublishingHelperExtension::class.java)
5050

5151
pom {
5252
if (project != project.rootProject) {
53-
// Add the license to every pom to make it easier for downstream project to retrieve the
53+
// Add the license to every pom to make it easier for downstream projects to retrieve the
5454
// license.
5555
licenses {
5656
license {
@@ -75,7 +75,7 @@ internal fun configurePom(project: Project, mavenPublication: MavenPublication,
7575
task.doFirst {
7676
mavenPom.run {
7777
val asfName = e.asfProjectId.get()
78-
val projectPeople = fetchProjectPeople(asfName)
78+
val projectInfo = fetchProjectInformation(asfName)
7979

8080
organization {
8181
name.set("The Apache Software Foundation")
@@ -84,15 +84,15 @@ internal fun configurePom(project: Project, mavenPublication: MavenPublication,
8484
licenses {
8585
license {
8686
name.set("Apache-2.0") // SPDX identifier
87-
url.set(projectPeople.licenseUrl)
87+
url.set(projectInfo.licenseUrl)
8888
}
8989
}
9090
mailingLists {
9191
e.mailingLists.get().forEach { ml ->
9292
mailingList {
9393
name.set("${ml.capitalized()} Mailing List")
9494
subscribe.set("$ml-subscribe@$asfName.apache.org")
95-
unsubscribe.set("$ml-ubsubscribe@$asfName.apache.org")
95+
unsubscribe.set("$ml-unsubscribe@$asfName.apache.org")
9696
post.set("$ml@$asfName.apache.org")
9797
archive.set("https://lists.apache.org/list.html?$ml@$asfName.apache.org")
9898
}
@@ -104,7 +104,7 @@ internal fun configurePom(project: Project, mavenPublication: MavenPublication,
104104
e.overrideScm.orElse(
105105
githubRepoName
106106
.map { r -> "https://github.com/apache/$r" }
107-
.orElse(projectPeople.repository)
107+
.orElse(projectInfo.repository)
108108
)
109109

110110
scm {
@@ -115,59 +115,28 @@ internal fun configurePom(project: Project, mavenPublication: MavenPublication,
115115
val version = project.version.toString()
116116
if (!version.endsWith("-SNAPSHOT")) {
117117
val tagPrefix: String =
118-
e.overrideTagPrefix.orElse("apache-${projectPeople.apacheId}").get()
118+
e.overrideTagPrefix.orElse("apache-${projectInfo.apacheId}").get()
119119
tag.set("$tagPrefix-$version")
120120
}
121121
}
122122
issueManagement {
123123
val issuesUrl: Provider<String> =
124-
codeRepo.map { r -> "$r/issues" }.orElse(projectPeople.bugDatabase)
124+
codeRepo.map { r -> "$r/issues" }.orElse(projectInfo.bugDatabase)
125125
url.set(e.overrideIssueManagement.orElse(issuesUrl))
126126
}
127127

128-
name.set(e.overrideName.orElse("Apache ${projectPeople.name}"))
129-
description.set(e.overrideDescription.orElse(projectPeople.description))
130-
url.set(e.overrideProjectUrl.orElse(projectPeople.website))
131-
inceptionYear.set(projectPeople.inceptionYear.toString())
132-
133-
developers {
134-
projectPeople.people.forEach { person ->
135-
developer {
136-
this.id.set(person.apacheId)
137-
this.name.set(person.name)
138-
this.organization.set("Apache Software Foundation")
139-
this.email.set("${person.apacheId}@apache.org")
140-
this.roles.addAll(person.roles)
141-
}
142-
}
143-
}
128+
name.set(e.overrideName.orElse("Apache ${projectInfo.name}"))
129+
description.set(e.overrideDescription.orElse(projectInfo.description))
130+
url.set(e.overrideProjectUrl.orElse(projectInfo.website))
131+
inceptionYear.set(projectInfo.inceptionYear.toString())
144132

145-
addContributorsToPom(mavenPom, githubRepoName.get(), "Apache ${projectPeople.name}")
133+
developers { developer { url.set("https://$asfName.apache.org/community/") } }
146134
}
147135
}
148136
}
149137
}
150138
}
151139

152-
/** Adds contributors as returned by GitHub, in descending `contributions` order. */
153-
fun addContributorsToPom(mavenPom: MavenPom, asfName: String, asfProjectName: String) =
154-
mavenPom.run {
155-
contributors {
156-
val contributors: List<Map<String, Any>> =
157-
parseJson("https://api.github.com/repos/apache/$asfName/contributors?per_page=1000")
158-
contributors
159-
.filter { contributor -> contributor["type"] == "User" }
160-
.forEach { contributor ->
161-
contributor {
162-
name.set(contributor["login"] as String)
163-
url.set(contributor["url"] as String)
164-
organization.set("$asfProjectName, GitHub contributors")
165-
organizationUrl.set("https://github.com/apache/$asfName")
166-
}
167-
}
168-
}
169-
}
170-
171140
/**
172141
* Scans the generated `pom.xml` for `<dependencies>` in `<dependencyManagement>` that do not have a
173142
* `<version>` and adds one, if possible. Maven kinda requires `<version>` tags there, even if the

build-logic/src/main/kotlin/publishing/rootProject.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ internal fun configureOnRootProject(project: Project) =
5555
"archive",
5656
"--prefix=${e.baseName.get()}/",
5757
"--format=tar.gz",
58+
// use a fixed mtime for reproducible tarballs, using the same timestamp as jars do
59+
"--mtime=1980-02-01 00:00:00",
5860
"--output=${e.sourceTarball.get().asFile.relativeTo(projectDir)}",
5961
"HEAD",
6062
)

build-logic/src/main/kotlin/publishing/util.kt

Lines changed: 32 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -99,36 +99,26 @@ internal fun <T : Any> parseJson(urlStr: String): T {
9999

100100
/** Retrieves the project name, for example `Polaris` using the lower-case project ID. */
101101
internal fun fetchAsfProjectName(apacheId: String): String {
102-
val projectsAll: Map<String, Map<String, Any>> =
103-
parseJson("https://whimsy.apache.org/public/public_ldap_projects.json")
104-
val projects = unsafeCast<Map<String, Map<String, Any>>>(projectsAll["projects"])
105-
val project =
106-
projects[apacheId]
107-
?: throw IllegalArgumentException(
108-
"No project '$apacheId' found in https://whimsy.apache.org/public/public_ldap_projects.json"
109-
)
102+
val project = projectMap(apacheId)
110103
val isPodlingCurrent = project.containsKey("podling") && project["podling"] == "current"
111104
if (isPodlingCurrent) {
112-
val podlingsAll: Map<String, Map<String, Any>> =
113-
parseJson("https://whimsy.apache.org/public/public_podlings.json")
114-
val podlings = unsafeCast<Map<String, Map<String, Any>>>(podlingsAll["podling"])
115-
val podling =
116-
podlings[apacheId]
117-
?: throw IllegalArgumentException(
118-
"No podling '$apacheId' found in https://whimsy.apache.org/public/public_podlings.json"
119-
)
105+
val podling = podlingMap(apacheId)
120106
return podling["name"] as String
121107
} else {
122108
// top-level-project
123-
val committeesAll: Map<String, Map<String, Any>> =
124-
parseJson("https://whimsy.apache.org/public/committee-info.json")
125-
val committees = unsafeCast<Map<String, Map<String, Any>>>(committeesAll["committees"])
126-
val committee = unsafeCast<Map<String, Any>>(committees[apacheId])
109+
val committee = projectCommitteeMap(apacheId)
127110
return committee["display_name"] as String
128111
}
129112
}
130113

131-
internal fun fetchProjectPeople(apacheId: String): ProjectPeople {
114+
internal fun projectCommitteeMap(apacheId: String): Map<String, Any> {
115+
val committeesAll: Map<String, Map<String, Any>> =
116+
parseJson("https://whimsy.apache.org/public/committee-info.json")
117+
val committees = unsafeCast<Map<String, Map<String, Any>>>(committeesAll["committees"])
118+
return unsafeCast(committees[apacheId])
119+
}
120+
121+
internal fun projectMap(apacheId: String): Map<String, Any> {
132122
val projectsAll: Map<String, Map<String, Any>> =
133123
parseJson("https://whimsy.apache.org/public/public_ldap_projects.json")
134124
val projects = unsafeCast<Map<String, Map<String, Any>>>(projectsAll["projects"])
@@ -137,19 +127,26 @@ internal fun fetchProjectPeople(apacheId: String): ProjectPeople {
137127
?: throw IllegalArgumentException(
138128
"No project '$apacheId' found in https://whimsy.apache.org/public/public_ldap_projects.json"
139129
)
140-
val isPodlingCurrent = project.containsKey("podling") && project["podling"] == "current"
130+
return project
131+
}
141132

142-
val inceptionYear = (project["createTimestamp"] as String).subSequence(0, 4).toString().toInt()
133+
internal fun podlingMap(apacheId: String): Map<String, Any> {
134+
val podlingsAll: Map<String, Map<String, Any>> =
135+
parseJson("https://whimsy.apache.org/public/public_podlings.json")
136+
val podlings = unsafeCast<Map<String, Map<String, Any>>>(podlingsAll["podling"])
137+
val podling =
138+
podlings[apacheId]
139+
?: throw IllegalArgumentException(
140+
"No podling '$apacheId' found in https://whimsy.apache.org/public/public_podlings.json"
141+
)
142+
return podling
143+
}
143144

144-
// Committers
145-
val peopleProjectRoles: MutableMap<String, MutableList<String>> = mutableMapOf()
146-
val members = unsafeCast(project["members"]) as List<String>
147-
members.forEach { member -> peopleProjectRoles.put(member, mutableListOf("Committer")) }
145+
internal fun fetchProjectInformation(apacheId: String): ProjectInformation {
146+
val project = projectMap(apacheId)
147+
val isPodlingCurrent = project.containsKey("podling") && project["podling"] == "current"
148148

149-
// (P)PMC Members
150-
val pmcRoleName = if (isPodlingCurrent) "PPMC member" else "PMC member"
151-
val owners = unsafeCast(project["owners"]) as List<String>
152-
owners.forEach { member -> peopleProjectRoles[member]!!.add(pmcRoleName) }
149+
val inceptionYear = (project["createTimestamp"] as String).subSequence(0, 4).toString().toInt()
153150

154151
val projectName: String
155152
val description: String
@@ -158,14 +155,7 @@ internal fun fetchProjectPeople(apacheId: String): ProjectPeople {
158155
val licenseUrl: String
159156
val bugDatabase: String
160157
if (isPodlingCurrent) {
161-
val podlingsAll: Map<String, Map<String, Any>> =
162-
parseJson("https://whimsy.apache.org/public/public_podlings.json")
163-
val podlings = unsafeCast<Map<String, Map<String, Any>>>(podlingsAll["podling"])
164-
val podling =
165-
podlings[apacheId]
166-
?: throw IllegalArgumentException(
167-
"No podling '$apacheId' found in https://whimsy.apache.org/public/public_podlings.json"
168-
)
158+
val podling = podlingMap(apacheId)
169159
projectName = podling["name"] as String
170160
description = podling["description"] as String
171161
val podlingStatus = unsafeCast(podling["podlingStatus"]) as Map<String, Any>
@@ -174,12 +164,6 @@ internal fun fetchProjectPeople(apacheId: String): ProjectPeople {
174164
repository = "https://github.com/apache/$apacheId.git"
175165
bugDatabase = "https://github.com/apache/$apacheId/issues"
176166
licenseUrl = "https://www.apache.org/licenses/LICENSE-2.0.txt"
177-
178-
val champion = podling["champion"] as String
179-
peopleProjectRoles[champion]!!.add("Champion")
180-
181-
val mentors = unsafeCast(podling["mentors"]) as List<String>
182-
mentors.forEach { member -> peopleProjectRoles[member]!!.add("Mentor") }
183167
} else {
184168
// top-level-project
185169
val tlpPrj: Map<String, Any> =
@@ -189,33 +173,12 @@ internal fun fetchProjectPeople(apacheId: String): ProjectPeople {
189173
bugDatabase = tlpPrj["bug-database"] as String
190174
licenseUrl = tlpPrj["license"] as String
191175

192-
val committeesAll: Map<String, Map<String, Any>> =
193-
parseJson("https://whimsy.apache.org/public/committee-info.json")
194-
val committees = unsafeCast<Map<String, Map<String, Any>>>(committeesAll["committees"])
195-
val committee = unsafeCast<Map<String, Any>>(committees[apacheId])
196-
val pmcChair = unsafeCast<Map<String, Map<String, Any>>>(committee["chair"])
176+
val committee = projectCommitteeMap(apacheId)
197177
projectName = committee["display_name"] as String
198178
description = committee["description"] as String
199-
pmcChair.keys.forEach { chair -> peopleProjectRoles[chair]!!.add("PMC Chair") }
200179
}
201180

202-
val peopleNames: Map<String, Map<String, Any>> =
203-
parseJson("https://whimsy.apache.org/public/public_ldap_people.json")
204-
val people: Map<String, Map<String, Any>> =
205-
unsafeCast(peopleNames["people"]) as Map<String, Map<String, Any>>
206-
val peopleList =
207-
peopleProjectRoles.entries
208-
.map { entry ->
209-
val person =
210-
people[entry.key]
211-
?: throw IllegalStateException(
212-
"No person '${entry.key}' found in https://whimsy.apache.org/public/public_ldap_people.json"
213-
)
214-
ProjectMember(entry.key, person["name"]!! as String, entry.value)
215-
}
216-
.sortedBy { it.name }
217-
218-
return ProjectPeople(
181+
return ProjectInformation(
219182
apacheId,
220183
projectName,
221184
description,
@@ -224,11 +187,10 @@ internal fun fetchProjectPeople(apacheId: String): ProjectPeople {
224187
licenseUrl,
225188
bugDatabase,
226189
inceptionYear,
227-
peopleList,
228190
)
229191
}
230192

231-
internal class ProjectPeople(
193+
internal class ProjectInformation(
232194
val apacheId: String,
233195
val name: String,
234196
val description: String,
@@ -237,7 +199,4 @@ internal class ProjectPeople(
237199
val licenseUrl: String,
238200
val bugDatabase: String,
239201
val inceptionYear: Int,
240-
val people: List<ProjectMember>,
241202
)
242-
243-
internal class ProjectMember(val apacheId: String, val name: String, val roles: List<String>)

0 commit comments

Comments
 (0)