Skip to content

Commit 3b9edcb

Browse files
committed
Apprunner: Ensure Maven publishing works
This change ensures that publishing tasks work correctly, the right `MavenPublications` are being used and no duplicate `MavenPublications` exist. * The Gradle plugin-plugin uses the name `pluginMaven` for the "main" publication. This name is then used instead of the common name `maven`, removing a duplicate (shadowing) publication. * The Maven plugin-plugin uses the name `mavenJava` for the "main" publication. This name is then used instead of the common name `maven`, removing a duplicate (shadowing) publication. * The Gradle plugin-plugin adds another publication for the "plugin marker" artifact, which only consists of a pom.xml. Adding the license and parent information to that pom as well.
1 parent 7f045c8 commit 3b9edcb

File tree

5 files changed

+92
-60
lines changed

5 files changed

+92
-60
lines changed

apprunner/apprunner-build-logic/src/main/kotlin/publishing/PublishingHelperPlugin.kt

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import org.gradle.api.component.SoftwareComponentFactory
2828
import org.gradle.api.publish.PublishingExtension
2929
import org.gradle.api.publish.maven.MavenPublication
3030
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
31+
import org.gradle.api.publish.maven.tasks.GenerateMavenPom
3132
import org.gradle.api.publish.tasks.GenerateModuleMetadata
3233
import org.gradle.api.tasks.SourceSetContainer
3334
import org.gradle.api.tasks.javadoc.Javadoc
@@ -94,6 +95,17 @@ constructor(private val softwareComponentFactory: SoftwareComponentFactory) : Pl
9495
configureOnRootProject(project)
9596
}
9697

98+
// The Gradle plugin-plugin adds another publication for the Gradle plugin marker artifact,
99+
// which is needed to resolve Gradle plugins by their ID. It uses the name `pluginMaven` for
100+
// the "main" `MavenPublication`, but that publication is created _after_ this code runs,
101+
// if it does not already exist.
102+
// The Maven plugin-plugin uses the name `mavenJava` for the "main" `MavenPublication`, which
103+
// is created _before_ this code runs.
104+
val hasGradlePlugin = plugins.hasPlugin("java-gradle-plugin")
105+
val hasMavenPlugin = plugins.hasPlugin("io.freefair.maven-plugin")
106+
val publicationName =
107+
if (hasGradlePlugin) "pluginMaven" else if (hasMavenPlugin) "mavenJava" else "maven"
108+
97109
if (isSigningEnabled()) {
98110
apply(plugin = "signing")
99111
plugins.withType<SigningPlugin>().configureEach {
@@ -102,7 +114,7 @@ constructor(private val softwareComponentFactory: SoftwareComponentFactory) : Pl
102114
val signingPassword: String? by project
103115
useInMemoryPgpKeys(signingKey, signingPassword)
104116
val publishing = project.extensions.getByType(PublishingExtension::class.java)
105-
afterEvaluate { sign(publishing.publications.getByName("maven")) }
117+
afterEvaluate { publishing.publications.forEach { publication -> sign(publication) } }
106118

107119
if (project.hasProperty("useGpgAgent")) {
108120
useGpgCmd()
@@ -121,7 +133,11 @@ constructor(private val softwareComponentFactory: SoftwareComponentFactory) : Pl
121133
plugins.withType<MavenPublishPlugin>().configureEach {
122134
configure<PublishingExtension> {
123135
publications {
124-
register<MavenPublication>("maven") {
136+
// The maven plugin-plugin has already registered the 'mavenJava' publication.
137+
if (!hasMavenPlugin) {
138+
register<MavenPublication>(publicationName)
139+
}
140+
named<MavenPublication>(publicationName) {
125141
val mavenPublication = this
126142
afterEvaluate {
127143
// This MUST happen in an 'afterEvaluate' to ensure that the Shadow*Plugin has
@@ -139,7 +155,12 @@ constructor(private val softwareComponentFactory: SoftwareComponentFactory) : Pl
139155
}
140156
}
141157
}
142-
from(component)
158+
// The Gradle and Maven plugin-plugins unconditionally add the 'java' component.
159+
// It's illegal to have more than one `SoftwareComponent` in a publication,
160+
// even if it is the same.
161+
if (!hasGradlePlugin && !hasMavenPlugin) {
162+
from(component)
163+
}
143164
}
144165

145166
suppressPomMetadataWarningsFor("testFixturesApiElements")
@@ -167,14 +188,15 @@ constructor(private val softwareComponentFactory: SoftwareComponentFactory) : Pl
167188
artifact(testFixturesJavadocJar)
168189
}
169190

170-
tasks.named("generatePomFileForMavenPublication").configure {
171-
configurePom(project, mavenPublication, this)
191+
// Have to configure all pom's (needed for the Gradle plugin-plugin)
192+
tasks.withType(GenerateMavenPom::class.java).configureEach {
193+
configurePom(project, this)
172194
}
173195
}
174196
}
175197
}
176198
}
177199

178-
addAdditionalJarContent(this)
200+
addAdditionalJarContent(this, publicationName)
179201
}
180202
}

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

Lines changed: 45 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ package publishing
2121

2222
import groovy.util.Node
2323
import org.gradle.api.Project
24-
import org.gradle.api.Task
2524
import org.gradle.api.artifacts.component.ModuleComponentSelector
26-
import org.gradle.api.publish.maven.MavenPublication
25+
import org.gradle.api.publish.maven.tasks.GenerateMavenPom
2726

2827
/**
2928
* Configures the content of the generated `pom.xml` files.
@@ -42,9 +41,9 @@ import org.gradle.api.publish.maven.MavenPublication
4241
* must be exactly the same when built by a release manager and by someone else to verify the built
4342
* artifact(s).
4443
*/
45-
internal fun configurePom(project: Project, mavenPublication: MavenPublication, task: Task) =
46-
mavenPublication.run {
47-
pom {
44+
internal fun configurePom(project: Project, task: GenerateMavenPom) =
45+
task.actions.addFirst {
46+
with(task.pom) {
4847
if (project != project.rootProject) {
4948
// Add the license to every pom to make it easier for downstream projects to retrieve the
5049
// license.
@@ -68,56 +67,54 @@ internal fun configurePom(project: Project, mavenPublication: MavenPublication,
6867
} else {
6968
val mavenPom = this
7069

71-
task.doFirst {
72-
mavenPom.run {
73-
val prj = EffectiveAsfProject.forProject(project)
74-
val asfProjectId = prj.asfProject.apacheId
70+
mavenPom.run {
71+
val prj = EffectiveAsfProject.forProject(project)
72+
val asfProjectId = prj.asfProject.apacheId
7573

76-
organization {
77-
name.set("The Apache Software Foundation")
78-
url.set("https://www.apache.org/")
79-
}
80-
licenses {
81-
license {
82-
name.set("Apache-2.0") // SPDX identifier
83-
url.set(prj.asfProject.licenseUrl)
84-
}
74+
organization {
75+
name.set("The Apache Software Foundation")
76+
url.set("https://www.apache.org/")
77+
}
78+
licenses {
79+
license {
80+
name.set("Apache-2.0") // SPDX identifier
81+
url.set(prj.asfProject.licenseUrl)
8582
}
86-
mailingLists {
87-
prj.publishingHelperExtension.mailingLists
88-
.get()
89-
.map { id -> prj.mailingList(id) }
90-
.forEach { ml ->
91-
mailingList {
92-
name.set(ml.name())
93-
subscribe.set(ml.subscribe())
94-
unsubscribe.set(ml.unsubscribe())
95-
post.set(ml.post())
96-
archive.set(ml.archive())
97-
}
83+
}
84+
mailingLists {
85+
prj.publishingHelperExtension.mailingLists
86+
.get()
87+
.map { id -> prj.mailingList(id) }
88+
.forEach { ml ->
89+
mailingList {
90+
name.set(ml.name())
91+
subscribe.set(ml.subscribe())
92+
unsubscribe.set(ml.unsubscribe())
93+
post.set(ml.post())
94+
archive.set(ml.archive())
9895
}
99-
}
100-
101-
scm {
102-
val codeRepoString: String = prj.codeRepoUrl().get()
103-
connection.set("scm:git:$codeRepoString")
104-
developerConnection.set("scm:git:$codeRepoString")
105-
url.set("$codeRepoString/tree/main")
106-
val version = project.version.toString()
107-
if (!version.endsWith("-SNAPSHOT")) {
108-
val tagPrefix: String = prj.tagPrefix().get()
109-
tag.set("$tagPrefix-$version")
11096
}
97+
}
98+
99+
scm {
100+
val codeRepoString: String = prj.codeRepoUrl().get()
101+
connection.set("scm:git:$codeRepoString")
102+
developerConnection.set("scm:git:$codeRepoString")
103+
url.set("$codeRepoString/tree/main")
104+
val version = project.version.toString()
105+
if (!version.endsWith("-SNAPSHOT")) {
106+
val tagPrefix: String = prj.tagPrefix().get()
107+
tag.set("$tagPrefix-$version")
111108
}
112-
issueManagement { url.set(prj.issueTracker()) }
109+
}
110+
issueManagement { url.set(prj.issueTracker()) }
113111

114-
name.set(prj.fullName())
115-
description.set(prj.description())
116-
url.set(prj.projectUrl())
117-
inceptionYear.set(prj.asfProject.inceptionYear.toString())
112+
name.set(prj.fullName())
113+
description.set(prj.description())
114+
url.set(prj.projectUrl())
115+
inceptionYear.set(prj.asfProject.inceptionYear.toString())
118116

119-
developers { developer { url.set("https://$asfProjectId.apache.org/community/") } }
120-
}
117+
developers { developer { url.set("https://$asfProjectId.apache.org/community/") } }
121118
}
122119
}
123120
}

apprunner/apprunner-build-logic/src/main/kotlin/publishing/maven-utils.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ abstract class GeneratePomProperties : DefaultTask() {
7070
* `META-INF/maven/group-id/artifact-id/`. Also adds the `NOTICE` and `LICENSE` files in `META-INF`,
7171
* which makes it easier for license scanners.
7272
*/
73-
fun addAdditionalJarContent(project: Project): Unit =
73+
fun addAdditionalJarContent(project: Project, mainPublicationName: String): Unit =
7474
project.run {
7575
project.plugins.withType(JavaLibraryPlugin::class.java) {
7676
val generatePomProperties =
@@ -83,7 +83,6 @@ fun addAdditionalJarContent(project: Project): Unit =
8383
rootProject.layout.files("gradle/jar-licenses/LICENSE", "gradle/jar-licenses/NOTICE")
8484
)
8585
inputs.property("GAV", "${project.group}:${project.name}:${project.version}")
86-
dependsOn("generatePomFileForMavenPublication")
8786
if (!project.file("src/main/resources/META-INF/LICENSE").exists()) {
8887
from(rootProject.rootDir).include("gradle/jar-licenses/LICENSE").eachFile {
8988
this.path = "META-INF/$sourceName"
@@ -94,7 +93,12 @@ fun addAdditionalJarContent(project: Project): Unit =
9493
this.path = "META-INF/$sourceName"
9594
}
9695
}
97-
from(tasks.named("generatePomFileForMavenPublication")) {
96+
// The Gradle plugin-plugin add another publication for the Gradle plugin marker artifact,
97+
// which is needed to resolve Gradle plugins by their ID.
98+
// Here we want to add the Maven pom information for the "main" publication to the jar.
99+
val generateMavenPomTask = tasks.named(generatePomTaskName(mainPublicationName))
100+
dependsOn(generateMavenPomTask)
101+
from(generateMavenPomTask) {
98102
include("pom-default.xml")
99103
eachFile { this.path = "META-INF/maven/${project.group}/${project.name}/pom.xml" }
100104
}
@@ -110,3 +114,6 @@ fun addAdditionalJarContent(project: Project): Unit =
110114
}
111115
}
112116
}
117+
118+
fun generatePomTaskName(publicationName: String) =
119+
"generatePomFileFor${publicationName.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }}Publication"

apprunner/gradle-plugin/build.gradle.kts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
*/
1919

2020
plugins {
21-
id("polaris-apprunner-java")
21+
// Order of java-gradle-plugin + polaris-apprunner-java matters!
2222
`java-gradle-plugin`
23+
id("polaris-apprunner-java")
2324
}
2425

2526
dependencies {
@@ -30,7 +31,10 @@ dependencies {
3031
gradlePlugin {
3132
plugins {
3233
register("polaris-apprunner") {
33-
id = "org.apache.polaris.apprunner"
34+
// This ID becomes the Maven group ID of the Gradle plugin marker artifact.
35+
// The artifact ID of the Gradle plugin marker artifact is ID + ".gradle.plugin"
36+
// (the defined plugin marker suffix).
37+
id = project.group.toString()
3438
implementationClass = "org.apache.polaris.apprunner.plugin.PolarisRunnerPlugin"
3539
displayName = "Polaris Runner"
3640
description = "Start and stop a Polaris server for integration testing"

apprunner/settings.gradle.kts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ dependencyResolutionManagement {
6767

6868
gradle.beforeProject {
6969
version = baseVersion
70-
group = "org.apache.polaris.tools.apprunner"
70+
// Note: the Gradle plugin ID is the group ID here. Both should be "aligned",
71+
// so that the plugin ID is within this group.
72+
group = "org.apache.polaris.apprunner"
7173
}
7274

7375
val isCI = System.getenv("CI") != null

0 commit comments

Comments
 (0)