[Build] Add support for publishing to maven central (#128659)

This ensures we package an aggregation zip with all artifacts we want to publish to maven central as part of a release.
Running zipAggregation will produce a zip file in the build/nmcp/zip folder. The content of this zip is meant to match the maven artifacts we have currently declared as dra maven artifacts.
This commit is contained in:
Rene Groeschke 2025-06-06 17:35:44 +02:00 committed by GitHub
parent deb793e2aa
commit 342083100b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 530 additions and 190 deletions

View file

@ -17,88 +17,89 @@ buildscript {
}
plugins {
id 'java-gradle-plugin'
id 'java-test-fixtures'
id 'eclipse'
id 'java-gradle-plugin'
id 'java-test-fixtures'
id 'eclipse'
}
group = "org.elasticsearch"
// This project contains Checkstyle rule implementations used by IDEs which use a Java 11 runtime
java {
targetCompatibility = 11
sourceCompatibility = 11
targetCompatibility = 17
sourceCompatibility = 17
}
gradlePlugin {
// We already configure publication and we don't need or want the one that comes
// with the java-gradle-plugin
automatedPublishing = false
plugins {
internalLicenseheaders {
id = 'elasticsearch.internal-licenseheaders'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.precommit.LicenseHeadersPrecommitPlugin'
}
eclipse {
id = 'elasticsearch.eclipse'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.EclipseConventionPlugin'
}
publish {
id = 'elasticsearch.publish'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.PublishPlugin'
}
licensing {
id = 'elasticsearch.licensing'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.LicensingPlugin'
}
buildTools {
id = 'elasticsearch.build-tools'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.BuildToolsConventionsPlugin'
}
versions {
id = 'elasticsearch.versions'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.VersionPropertiesPlugin'
}
formatting {
id = 'elasticsearch.formatting'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.precommit.FormattingPrecommitPlugin'
}
// We already configure publication and we don't need or want the one that comes
// with the java-gradle-plugin
automatedPublishing = false
plugins {
internalLicenseheaders {
id = 'elasticsearch.internal-licenseheaders'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.precommit.LicenseHeadersPrecommitPlugin'
}
eclipse {
id = 'elasticsearch.eclipse'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.EclipseConventionPlugin'
}
publish {
id = 'elasticsearch.publish'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.PublishPlugin'
}
licensing {
id = 'elasticsearch.licensing'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.LicensingPlugin'
}
buildTools {
id = 'elasticsearch.build-tools'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.BuildToolsConventionsPlugin'
}
versions {
id = 'elasticsearch.versions'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.VersionPropertiesPlugin'
}
formatting {
id = 'elasticsearch.formatting'
implementationClass = 'org.elasticsearch.gradle.internal.conventions.precommit.FormattingPrecommitPlugin'
}
}
}
repositories {
mavenCentral()
gradlePluginPortal()
mavenCentral()
gradlePluginPortal()
}
dependencies {
api buildLibs.maven.model
api buildLibs.shadow.plugin
api buildLibs.apache.rat
compileOnly buildLibs.checkstyle
constraints {
api("org.eclipse.platform:org.eclipse.osgi:3.18.300") {
because("Use the same version as we do in spotless gradle plugin at runtime")
}
}
api(buildLibs.spotless.plugin) {
exclude module: "groovy-xml"
api buildLibs.maven.model
api buildLibs.shadow.plugin
api buildLibs.apache.rat
api buildLibs.nmcp
compileOnly buildLibs.checkstyle
constraints {
api("org.eclipse.platform:org.eclipse.osgi:3.18.300") {
because("Use the same version as we do in spotless gradle plugin at runtime")
}
}
api(buildLibs.spotless.plugin) {
exclude module: "groovy-xml"
}
}
project.getPlugins().withType(JavaBasePlugin.class) {
java.getModularity().getInferModulePath().set(false);
eclipse.getClasspath().getFile().whenMerged { classpath ->
/*
* give each source folder a unique corresponding output folder
* outside of the usual `build` folder. We can't put the build
* in the usual build folder because eclipse becomes *very* sad
* if we delete it. Which `gradlew clean` does all the time.
*/
classpath.getEntries().findAll{ s -> s instanceof SourceFolder }.eachWithIndex { s, i ->
s.setOutput("out/eclipse" + i)
}
java.getModularity().getInferModulePath().set(false);
eclipse.getClasspath().getFile().whenMerged { classpath ->
/*
* give each source folder a unique corresponding output folder
* outside of the usual `build` folder. We can't put the build
* in the usual build folder because eclipse becomes *very* sad
* if we delete it. Which `gradlew clean` does all the time.
*/
classpath.getEntries().findAll { s -> s instanceof SourceFolder }.eachWithIndex { s, i ->
s.setOutput("out/eclipse" + i)
}
}
}
tasks.withType(JavaCompile).configureEach {

View file

@ -14,6 +14,8 @@ import groovy.util.Node;
import com.github.jengelman.gradle.plugins.shadow.ShadowExtension;
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin;
import nmcp.NmcpPlugin;
import org.elasticsearch.gradle.internal.conventions.info.GitInfo;
import org.elasticsearch.gradle.internal.conventions.precommit.PomValidationPrecommitPlugin;
import org.elasticsearch.gradle.internal.conventions.util.Util;
@ -27,6 +29,7 @@ import org.gradle.api.plugins.BasePluginExtension;
import org.gradle.api.plugins.ExtensionContainer;
import org.gradle.api.plugins.JavaLibraryPlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.ProviderFactory;
@ -65,6 +68,7 @@ public class PublishPlugin implements Plugin<Project> {
project.getPluginManager().apply(MavenPublishPlugin.class);
project.getPluginManager().apply(PomValidationPrecommitPlugin.class);
project.getPluginManager().apply(LicensingPlugin.class);
project.getPluginManager().apply(NmcpPlugin.class);
configureJavadocJar(project);
configureSourcesJar(project);
configurePomGeneration(project);
@ -82,6 +86,11 @@ public class PublishPlugin implements Plugin<Project> {
publication.from(project.getComponents().getByName("java"));
}
});
project.getPlugins().withType(JavaPlugin.class, plugin -> {
var javaPluginExtension = project.getExtensions().getByType(JavaPluginExtension.class);
javaPluginExtension.withJavadocJar();
javaPluginExtension.withSourcesJar();
});
@SuppressWarnings("unchecked")
var projectLicenses = (MapProperty<String, Provider<String>>) project.getExtensions().getExtraProperties().get("projectLicenses");
publication.getPom().withXml(xml -> {

View file

@ -123,8 +123,6 @@ class BuildPluginFuncTest extends AbstractGradleFuncTest {
then:
result.task(":assemble").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world.jar").exists()
file("build/distributions/hello-world-javadoc.jar").exists()
file("build/distributions/hello-world-sources.jar").exists()
assertValidJar(file("build/distributions/hello-world.jar"))
}
@ -162,7 +160,6 @@ class BuildPluginFuncTest extends AbstractGradleFuncTest {
result.task(":forbiddenPatterns").outcome == TaskOutcome.SUCCESS
result.task(":validateModule").outcome == TaskOutcome.SUCCESS
result.task(":splitPackagesAudit").outcome == TaskOutcome.SUCCESS
result.task(":validateElasticPom").outcome == TaskOutcome.SUCCESS
// disabled but check for being on the task graph
result.task(":forbiddenApisMain").outcome == TaskOutcome.SKIPPED
result.task(":checkstyleMain").outcome == TaskOutcome.SKIPPED

View file

@ -23,9 +23,212 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
configurationCacheCompatible = false
}
def "artifacts and tweaked pom is published"() {
def "project with plugin applied is considered for maven central publication"() {
given:
// required for JarHell to work
subProject(":libs:some-public-lib") << """
plugins {
id 'elasticsearch.java'
id 'elasticsearch.publish'
}
group = 'org.acme'
version = '1.0'
"""
subProject(":libs:some-other-lib") << """
plugins {
id 'elasticsearch.java'
id 'elasticsearch.publish'
}
group = 'org.acme.xpack'
version = '1.0'
"""
subProject(":libs:some-private-lib") << """
plugins {
id 'elasticsearch.java'
}
group = 'org.acme.xpack'
version = '1.0'
"""
buildFile << """
plugins {
id 'com.gradleup.nmcp.aggregation'
}
version = "1.0"
group = 'org.acme'
description = "custom project description"
nmcpAggregation {
centralPortal {
username = 'acme'
password = 'acmepassword'
// publish manually from the portal
publishingType = "USER_MANAGED"
}
// this breaks project isolation but this is broken in elasticsearch build atm anyhow.
publishAllProjectsProbablyBreakingProjectIsolation()
}
"""
when:
def result = gradleRunner(':zipAggregation').build()
then:
result.task(":zipAggregation").outcome == TaskOutcome.SUCCESS
file("build/nmcp/zip/aggregation.zip").exists()
def zip = zip("build/nmcp/zip/aggregation.zip")
zip.files().findAll { it.isDirectory() == false }.collect { it.name }.sort() == [
"org/acme/some-public-lib/1.0/some-public-lib-1.0-javadoc.jar",
"org/acme/some-public-lib/1.0/some-public-lib-1.0-javadoc.jar.md5",
"org/acme/some-public-lib/1.0/some-public-lib-1.0-javadoc.jar.sha1",
"org/acme/some-public-lib/1.0/some-public-lib-1.0-javadoc.jar.sha256",
"org/acme/some-public-lib/1.0/some-public-lib-1.0-javadoc.jar.sha512",
"org/acme/some-public-lib/1.0/some-public-lib-1.0-sources.jar",
"org/acme/some-public-lib/1.0/some-public-lib-1.0-sources.jar.md5",
"org/acme/some-public-lib/1.0/some-public-lib-1.0-sources.jar.sha1",
"org/acme/some-public-lib/1.0/some-public-lib-1.0-sources.jar.sha256",
"org/acme/some-public-lib/1.0/some-public-lib-1.0-sources.jar.sha512",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.jar",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.jar.md5",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.jar.sha1",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.jar.sha256",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.jar.sha512",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.module",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.module.md5",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.module.sha1",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.module.sha256",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.module.sha512",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.pom",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.pom.md5",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.pom.sha1",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.pom.sha256",
"org/acme/some-public-lib/1.0/some-public-lib-1.0.pom.sha512",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0-javadoc.jar",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0-javadoc.jar.md5",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0-javadoc.jar.sha1",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0-javadoc.jar.sha256",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0-javadoc.jar.sha512",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0-sources.jar",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0-sources.jar.md5",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0-sources.jar.sha1",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0-sources.jar.sha256",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0-sources.jar.sha512",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.jar",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.jar.md5",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.jar.sha1",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.jar.sha256",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.jar.sha512",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.module",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.module.md5",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.module.sha1",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.module.sha256",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.module.sha512",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.pom",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.pom.md5",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.pom.sha1",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.pom.sha256",
"org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.pom.sha512"
]
assertXmlEquals(zip.file("org/acme/some-public-lib/1.0/some-public-lib-1.0.pom").read(),"""
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
<!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
<!-- that they should prefer consuming it instead. -->
<!-- do_not_remove: published-with-gradle-metadata -->
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
<artifactId>some-public-lib</artifactId>
<version>1.0</version>
<name>some-public-lib</name>
<description/>
<url>unknown</url>
<scm>
<url>unknown</url>
</scm>
<inceptionYear>2009</inceptionYear>
<licenses>
<license>
<name>Elastic License 2.0</name>
<url>https://raw.githubusercontent.com/elastic/elasticsearch/v1.0/licenses/ELASTIC-LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
<license>
<name>GNU Affero General Public License Version 3</name>
<url>https://raw.githubusercontent.com/elastic/elasticsearch/v1.0/licenses/AGPL-3.0+SSPL-1.0+ELASTIC-LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
<license>
<name>Server Side Public License, v 1</name>
<url>https://www.mongodb.com/licensing/server-side-public-license</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>Elastic</name>
<url>https://www.elastic.co</url>
</developer>
</developers>
</project>
""")
assertXmlEquals(zip.file("org/acme/xpack/some-other-lib/1.0/some-other-lib-1.0.pom").read(),"""
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
<!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
<!-- that they should prefer consuming it instead. -->
<!-- do_not_remove: published-with-gradle-metadata -->
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme.xpack</groupId>
<artifactId>some-other-lib</artifactId>
<version>1.0</version>
<name>some-other-lib</name>
<description/>
<url>unknown</url>
<scm>
<url>unknown</url>
</scm>
<inceptionYear>2009</inceptionYear>
<licenses>
<license>
<name>Elastic License 2.0</name>
<url>https://raw.githubusercontent.com/elastic/elasticsearch/v1.0/licenses/ELASTIC-LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
<license>
<name>GNU Affero General Public License Version 3</name>
<url>https://raw.githubusercontent.com/elastic/elasticsearch/v1.0/licenses/AGPL-3.0+SSPL-1.0+ELASTIC-LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
<license>
<name>Server Side Public License, v 1</name>
<url>https://www.mongodb.com/licensing/server-side-public-license</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>Elastic</name>
<url>https://www.elastic.co</url>
</developer>
</developers>
</project>
""")
}
def "artifacts and tweaked pom is published"() {
given:
buildFile << """
plugins {
id 'elasticsearch.java'
id 'elasticsearch.publish'
@ -36,17 +239,17 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
description = "custom project description"
"""
when:
def result = gradleRunner('assemble').build()
when:
def result = gradleRunner('assemble').build()
then:
result.task(":generatePom").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world-1.0.jar").exists()
file("build/distributions/hello-world-1.0-javadoc.jar").exists()
file("build/distributions/hello-world-1.0-sources.jar").exists()
file("build/distributions/hello-world-1.0.pom").exists()
assertXmlEquals(
file("build/distributions/hello-world-1.0.pom").text, """
then:
result.task(":generatePom").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world-1.0.jar").exists()
file("build/distributions/hello-world-1.0-javadoc.jar").exists()
file("build/distributions/hello-world-1.0-sources.jar").exists()
file("build/distributions/hello-world-1.0.pom").exists()
assertXmlEquals(
file("build/distributions/hello-world-1.0.pom").text, """
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
@ -88,12 +291,12 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
</developer>
</developers>
</project>"""
)
}
)
}
def "hides runtime dependencies and handles shadow dependencies"() {
given:
buildFile << """
def "hides runtime dependencies and handles shadow dependencies"() {
given:
buildFile << """
plugins {
id 'elasticsearch.java'
id 'elasticsearch.publish'
@ -121,18 +324,18 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
description = 'shadowed project'
"""
when:
def result = gradleRunner('assemble', '--stacktrace').build()
when:
def result = gradleRunner('assemble', '--stacktrace').build()
then:
result.task(":generatePom").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world-1.0-original.jar").exists()
file("build/distributions/hello-world-1.0.jar").exists()
file("build/distributions/hello-world-1.0-javadoc.jar").exists()
file("build/distributions/hello-world-1.0-sources.jar").exists()
file("build/distributions/hello-world-1.0.pom").exists()
assertXmlEquals(
file("build/distributions/hello-world-1.0.pom").text, """
then:
result.task(":generatePom").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world-1.0-original.jar").exists()
file("build/distributions/hello-world-1.0.jar").exists()
file("build/distributions/hello-world-1.0-javadoc.jar").exists()
file("build/distributions/hello-world-1.0-sources.jar").exists()
file("build/distributions/hello-world-1.0.pom").exists()
assertXmlEquals(
file("build/distributions/hello-world-1.0.pom").text, """
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
@ -177,14 +380,14 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
</dependency>
</dependencies>
</project>"""
)
}
)
}
def "handles project shadow dependencies"() {
given:
settingsFile << "include ':someLib'"
file('someLib').mkdirs()
buildFile << """
def "handles project shadow dependencies"() {
given:
settingsFile << "include ':someLib'"
file('someLib').mkdirs()
buildFile << """
plugins {
id 'elasticsearch.java'
id 'elasticsearch.publish'
@ -211,18 +414,18 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
description = 'with shadowed dependencies'
"""
when:
def result = gradleRunner(':assemble', '--stacktrace').build()
when:
def result = gradleRunner(':assemble', '--stacktrace').build()
then:
result.task(":generatePom").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world-1.0-original.jar").exists()
file("build/distributions/hello-world-1.0.jar").exists()
file("build/distributions/hello-world-1.0-javadoc.jar").exists()
file("build/distributions/hello-world-1.0-sources.jar").exists()
file("build/distributions/hello-world-1.0.pom").exists()
assertXmlEquals(
file("build/distributions/hello-world-1.0.pom").text, """
then:
result.task(":generatePom").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world-1.0-original.jar").exists()
file("build/distributions/hello-world-1.0.jar").exists()
file("build/distributions/hello-world-1.0-javadoc.jar").exists()
file("build/distributions/hello-world-1.0-sources.jar").exists()
file("build/distributions/hello-world-1.0.pom").exists()
assertXmlEquals(
file("build/distributions/hello-world-1.0.pom").text, """
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
@ -267,16 +470,16 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
</dependency>
</dependencies>
</project>"""
)
}
)
}
def "generates artifacts for shadowed elasticsearch plugin"() {
given:
// we use the esplugin plugin in this test that is not configuration cache compatible yet
configurationCacheCompatible = false
file('license.txt') << "License file"
file('notice.txt') << "Notice file"
buildFile << """
def "generates artifacts for shadowed elasticsearch plugin"() {
given:
// we use the esplugin plugin in this test that is not configuration cache compatible yet
configurationCacheCompatible = false
file('license.txt') << "License file"
file('notice.txt') << "Notice file"
buildFile << """
plugins {
id 'elasticsearch.internal-es-plugin'
id 'elasticsearch.publish'
@ -305,18 +508,18 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
group = 'org.acme'
"""
when:
def result = gradleRunner('assemble', '--stacktrace', '-x', 'generateClusterFeaturesMetadata').build()
when:
def result = gradleRunner('assemble', '--stacktrace', '-x', 'generateClusterFeaturesMetadata').build()
then:
result.task(":generatePom").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world-plugin-1.0-original.jar").exists()
file("build/distributions/hello-world-plugin-1.0.jar").exists()
file("build/distributions/hello-world-plugin-1.0-javadoc.jar").exists()
file("build/distributions/hello-world-plugin-1.0-sources.jar").exists()
file("build/distributions/hello-world-plugin-1.0.pom").exists()
assertXmlEquals(
file("build/distributions/hello-world-plugin-1.0.pom").text, """
then:
result.task(":generatePom").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world-plugin-1.0-original.jar").exists()
file("build/distributions/hello-world-plugin-1.0.jar").exists()
file("build/distributions/hello-world-plugin-1.0-javadoc.jar").exists()
file("build/distributions/hello-world-plugin-1.0-sources.jar").exists()
file("build/distributions/hello-world-plugin-1.0.pom").exists()
assertXmlEquals(
file("build/distributions/hello-world-plugin-1.0.pom").text, """
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
@ -358,16 +561,16 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
</developer>
</developers>
</project>"""
)
}
)
}
def "generates pom for elasticsearch plugin"() {
given:
// we use the esplugin plugin in this test that is not configuration cache compatible yet
configurationCacheCompatible = false
file('license.txt') << "License file"
file('notice.txt') << "Notice file"
buildFile << """
def "generates pom for elasticsearch plugin"() {
given:
// we use the esplugin plugin in this test that is not configuration cache compatible yet
configurationCacheCompatible = false
file('license.txt') << "License file"
file('notice.txt') << "Notice file"
buildFile << """
plugins {
id 'elasticsearch.internal-es-plugin'
id 'elasticsearch.publish'
@ -387,14 +590,14 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
group = 'org.acme'
"""
when:
def result = gradleRunner('generatePom').build()
when:
def result = gradleRunner('generatePom').build()
then:
result.task(":generatePom").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world-plugin-2.0.pom").exists()
assertXmlEquals(
file("build/distributions/hello-world-plugin-2.0.pom").text, """
then:
result.task(":generatePom").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world-plugin-2.0.pom").exists()
assertXmlEquals(
file("build/distributions/hello-world-plugin-2.0.pom").text, """
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
@ -436,14 +639,14 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
</developer>
</developers>
</project>"""
)
}
)
}
def "generated pom can be validated"() {
given:
// scm info only added for internal builds
internalBuild()
buildFile << """
def "generated pom can be validated"() {
given:
// scm info only added for internal builds
internalBuild()
buildFile << """
buildParams.setGitOrigin(project.providers.provider(() -> "https://some-repo.com/repo.git"))
apply plugin:'elasticsearch.java'
apply plugin:'elasticsearch.publish'
@ -455,14 +658,14 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
ext.projectLicenses.set(['The Apache Software License, Version 2.0': project.providers.provider(() -> 'http://www.apache.org/licenses/LICENSE-2.0')])
"""
when:
def result = gradleRunner('generatePom', 'validateElasticPom').build()
when:
def result = gradleRunner('generatePom', 'validateElasticPom').build()
then:
result.task(":generatePom").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world-1.0.pom").exists()
assertXmlEquals(
file("build/distributions/hello-world-1.0.pom").text, """
then:
result.task(":generatePom").outcome == TaskOutcome.SUCCESS
file("build/distributions/hello-world-1.0.pom").exists()
assertXmlEquals(
file("build/distributions/hello-world-1.0.pom").text, """
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
@ -494,30 +697,31 @@ class PublishPluginFuncTest extends AbstractGradleFuncTest {
</developer>
</developers>
</project>"""
)
}
)
}
private boolean assertXmlEquals(String toTest, String expected) {
def diff = DiffBuilder.compare(Input.fromString(expected))
.ignoreWhitespace()
.ignoreComments()
.normalizeWhitespace()
.withTest(Input.fromString(toTest))
.build()
diff.differences.each { difference ->
println difference
}
if (diff.differences.size() > 0) {
println """ given:
private boolean assertXmlEquals(String toTest, String expected) {
def diff = DiffBuilder.compare(Input.fromString(expected))
.ignoreWhitespace()
.ignoreComments()
.normalizeWhitespace()
.withTest(Input.fromString(toTest))
.build()
diff.differences.each { difference ->
println difference
}
if (diff.differences.size() > 0) {
println """ given:
$toTest
"""
println """ expected:
println """ expected:
$expected
"""
}
assert diff.hasDifferences() == false
true
}
assert diff.hasDifferences() == false
true
}
}

View file

@ -9,6 +9,7 @@
package org.elasticsearch.gradle.internal;
import org.elasticsearch.gradle.internal.conventions.LicensingPlugin;
import org.elasticsearch.gradle.internal.info.GlobalBuildInfoPlugin;
import org.elasticsearch.gradle.internal.precommit.InternalPrecommitTasks;
import org.elasticsearch.gradle.internal.snyk.SnykDependencyMonitoringGradlePlugin;
@ -59,9 +60,9 @@ public class BuildPlugin implements Plugin<Project> {
}
project.getPluginManager().apply("elasticsearch.java");
project.getPluginManager().apply("elasticsearch.publish");
project.getPluginManager().apply(ElasticsearchJavadocPlugin.class);
project.getPluginManager().apply(DependenciesInfoPlugin.class);
project.getPluginManager().apply(LicensingPlugin.class);
project.getPluginManager().apply(SnykDependencyMonitoringGradlePlugin.class);
project.getPluginManager().apply(ClusterFeaturesMetadataPlugin.class);
InternalPrecommitTasks.create(project, true);

View file

@ -10,6 +10,7 @@
package org.elasticsearch.gradle.fixtures
import org.apache.commons.io.FileUtils
import org.apache.commons.io.IOUtils
import org.elasticsearch.gradle.internal.test.BuildConfigurationAwareGradleRunner
import org.elasticsearch.gradle.internal.test.InternalAwareGradleRunner
import org.elasticsearch.gradle.internal.test.NormalizeOutputGradleRunner
@ -23,11 +24,14 @@ import spock.lang.Specification
import spock.lang.TempDir
import java.lang.management.ManagementFactory
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.io.File
import java.nio.file.Path
import java.util.jar.JarEntry
import java.util.jar.JarOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import static org.elasticsearch.gradle.internal.test.TestUtils.normalizeString
@ -234,6 +238,64 @@ checkstyle = "com.puppycrawl.tools:checkstyle:10.3"
(it as TestResultExtension.ErrorListener).errorInfo != null }
}
ZipAssertion zip(String relativePath) {
File archiveFile = file(relativePath);
try (ZipFile zipFile = new ZipFile(archiveFile)) {
Map<String, ZipAssertionFile> files = zipFile.entries().collectEntries { ZipEntry entry ->
[(entry.name): new ZipAssertionFile(archiveFile, entry)]
}
return new ZipAssertion(files);
}
}
static class ZipAssertion {
private Map<String, ZipAssertionFile> files = new HashMap<>()
ZipAssertion(Map<String, ZipAssertionFile> files) {
this.files = files;
}
ZipAssertionFile file(String path) {
return this.files.get(path)
}
Collection<ZipAssertionFile> files() {
return files.values()
}
}
static class ZipAssertionFile {
private ZipEntry entry;
private File zipFile;
ZipAssertionFile(File zipFile, ZipEntry entry) {
this.entry = entry
this.zipFile = zipFile
}
boolean exists() {
entry == null
}
String getName() {
return entry.name
}
boolean isDirectory() {
return entry.isDirectory()
}
String read() {
try(ZipFile zipFile1 = new ZipFile(zipFile)) {
def inputStream = zipFile1.getInputStream(entry)
return IOUtils.toString(inputStream, StandardCharsets.UTF_8.name())
} catch (IOException e) {
throw new RuntimeException("Failed to read entry ${entry.name} from zip file ${zipFile.name}", e)
}
}
}
static class ProjectConfigurer {
private File projectDir

View file

@ -48,8 +48,28 @@ plugins {
id 'elasticsearch.internal-testclusters'
id 'elasticsearch.run'
id 'elasticsearch.run-ccs'
id 'elasticsearch.repositories'
id 'elasticsearch.release-tools'
id 'elasticsearch.versions'
id 'com.gradleup.nmcp.aggregation'
}
version = VersionProperties.elasticsearch
/**
* Here we package and aggregation zip file containing all maven artifacts we want to
* publish to maven central.
* The aggregation is done by picking all projects that have the elasticsearch.publish plugin applied,
* indicating the artifact is meant for beeing published to maven central.
* */
nmcpAggregation {
// this breaks project isolation but this is broken in elasticsearch build atm anyhow.
publishAllProjectsProbablyBreakingProjectIsolation()
}
tasks.named('zipAggregation').configure {
dependsOn gradle.includedBuild('build-tools').task(':zipElasticPublication')
from(zipTree(gradle.includedBuild('build-tools').task(':zipElasticPublication').resolveTask().archiveFile.get()))
}
/**
@ -295,7 +315,7 @@ allprojects {
tasks.register('resolveAllDependencies', ResolveAllDependencies) {
def ignoredPrefixes = [DistributionDownloadPlugin.ES_DISTRO_CONFIG_PREFIX, "jdbcDriver"]
configs = project.configurations.matching { config -> ignoredPrefixes.any { config.name.startsWith(it) } == false }
if(project.path == ':') {
if (project.path == ':') {
resolveJavaToolChain = true
// ensure we have best possible caching of bwc builds
@ -320,7 +340,7 @@ allprojects {
}
ext.withReleaseBuild = { Closure config ->
if(buildParams.snapshotBuild == false) {
if (buildParams.snapshotBuild == false) {
config.call()
}
}

View file

@ -17,10 +17,6 @@ java {
group = "${group}.client.test"
// rest client sniffer is licenses under Apache 2.0
projectLicenses.set(['The Apache Software License, Version 2.0': providers.provider(() -> 'http://www.apache.org/licenses/LICENSE-2.0')])
licenseFile.set(layout.getSettingsDirectory().file('licenses/APACHE-LICENSE-2.0.txt').asFile)
dependencies {
api "org.apache.httpcomponents:httpcore:${versions.httpcore}"
api "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"

View file

@ -3,6 +3,7 @@ asm = "9.7.1"
jackson = "2.15.0"
junit5 = "5.12.1"
spock = "2.1-groovy-3.0"
nmcp = "0.1.5"
[libraries]
ant = "org.apache.ant:ant:1.10.12"
@ -36,6 +37,7 @@ junit5-platform-launcher = "org.junit.platform:junit-platform-launcher:1.8.1"
junit5-vintage = { group = "org.junit.vintage", name="junit-vintage-engine", version.ref="junit5" }
maven-model = "org.apache.maven:maven-model:3.6.2"
mockito-core = "org.mockito:mockito-core:1.9.5"
nmcp = { group = "com.gradleup.nmcp", name = "nmcp", version.ref="nmcp" }
nebula-info = "com.netflix.nebula:gradle-info-plugin:11.3.3"
reflections = "org.reflections:reflections:0.9.12"
shadow-plugin = "com.gradleup.shadow:shadow-gradle-plugin:8.3.5"
@ -49,3 +51,4 @@ xmlunit-core = "org.xmlunit:xmlunit-core:2.8.2"
[plugins]
ospackage = { id = "com.netflix.nebula.ospackage-base", version = "11.11.2" }
nmcp-aggregation = { id = "com.gradleup.nmcp.aggregation", version.ref="nmcp" }

View file

@ -873,6 +873,16 @@
</sha256>
</artifact>
</component>
<component group="com.gradleup.gratatouille" name="gratatouille-runtime" version="0.0.8">
<artifact name="gratatouille-runtime-0.0.8.jar">
<sha256 value="03eefe964f5d06b2263a28724e3d3503c0670ea1846c208afa918d86d4d08472" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.gradleup.nmcp" name="nmcp" version="0.1.5">
<artifact name="nmcp-0.1.5.jar">
<sha256 value="9c823adc282e96b206956e4a63cb1552bb2bbcec6010bbb6aa9c3d18ecd3f915" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.gradleup.shadow" name="shadow-gradle-plugin" version="8.3.5">
<artifact name="shadow-gradle-plugin-8.3.5.jar">
<sha256 value="54e08dd20a82775e3317a4725a1a5e4ec8b1b1c0f346de702a49d9ed4815b735" origin="Generated by Gradle"/>
@ -1068,6 +1078,11 @@
<sha256 value="88ac9fd1bb51f82bcc664cc1eb9c225c90dc4389d660231b4cc737bebfe7d0aa" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.squareup.okhttp3" name="logging-interceptor" version="4.12.0">
<artifact name="logging-interceptor-4.12.0.jar">
<sha256 value="f3e8d5f0903c250c2b55d2f47fcfe008e80634385da8385161c7a63aaed0c74c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.squareup.okhttp3" name="okhttp" version="4.12.0">
<artifact name="okhttp-4.12.0.jar">
<sha256 value="b1050081b14bb7a3a7e55a4d3ef01b5dcfabc453b4573a4fc019767191d5f4e0" origin="Generated by Gradle"/>
@ -1088,6 +1103,11 @@
<sha256 value="67543f0736fc422ae927ed0e504b98bc5e269fda0d3500579337cb713da28412" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.squareup.okio" name="okio-jvm" version="3.8.0">
<artifact name="okio-jvm-3.8.0.jar">
<sha256 value="88fb79f6fe1a462acf0a3bd2576ba1525c29f29825efeceec70a747ac1c6fc90" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.sun.activation" name="jakarta.activation" version="1.2.1">
<artifact name="jakarta.activation-1.2.1.jar">
<sha256 value="d84d4ba8b55cdb7fdcbb885e6939386367433f56f5ab8cfdc302a7c3587fa92b" origin="Generated by Gradle"/>
@ -3991,21 +4011,51 @@
<sha256 value="55e989c512b80907799f854309f3bc7782c5b3d13932442d0379d5c472711504" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jetbrains.kotlin" name="kotlin-stdlib" version="2.1.20">
<artifact name="kotlin-stdlib-2.1.20.jar">
<sha256 value="1bcc74e8ce84e2c25eaafde10f1248349cce3062b6e36978cbeec610db1e930a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-common" version="1.9.10">
<artifact name="kotlin-stdlib-common-1.9.10.jar">
<sha256 value="cde3341ba18a2ba262b0b7cf6c55b20c90e8d434e42c9a13e6a3f770db965a88" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk7" version="1.8.21">
<artifact name="kotlin-stdlib-jdk7-1.8.21.jar">
<sha256 value="33d148db0e11debd0d90677d28242bced907f9c77730000fd597867089039d86" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk7" version="1.9.10">
<artifact name="kotlin-stdlib-jdk7-1.9.10.jar">
<sha256 value="ac6361bf9ad1ed382c2103d9712c47cdec166232b4903ed596e8876b0681c9b7" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk8" version="1.8.21">
<artifact name="kotlin-stdlib-jdk8-1.8.21.jar">
<sha256 value="3db752a30074f06ee6c57984aa6f27da44f4d2bbc7f5442651f6988f1cb2b7d7" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk8" version="1.9.10">
<artifact name="kotlin-stdlib-jdk8-1.9.10.jar">
<sha256 value="a4c74d94d64ce1abe53760fe0389dd941f6fc558d0dab35e47c085a11ec80f28" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jetbrains.kotlin" name="kotlin-test" version="2.0.0">
<artifact name="kotlin-test-2.0.0.jar">
<sha256 value="8438cc11769da31cbb4445dfafd12c08cf4015daa387963106f121a85a56864c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jetbrains.kotlinx" name="kotlinx-serialization-core-jvm" version="1.8.1">
<artifact name="kotlinx-serialization-core-jvm-1.8.1.jar">
<sha256 value="3565b6d4d789bf70683c45566944287fc1d8dc75c23d98bd87d01059cc76f2b3" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jetbrains.kotlinx" name="kotlinx-serialization-json-jvm" version="1.8.1">
<artifact name="kotlinx-serialization-json-jvm-1.8.1.jar">
<sha256 value="8769e5647557e3700919c32d508f5c5dad53c5d8234cd10846354fbcff14aa24" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jline" name="jline" version="3.9.0">
<artifact name="jline-3.9.0.jar">
<sha256 value="d2b986fd15d05e0b900faba776c1de9b4dc4a4fcdfeaa12a8ab8fb2b290ed527" origin="Generated by Gradle"/>

View file

@ -11,6 +11,7 @@ import org.elasticsearch.gradle.internal.precommit.CheckForbiddenApisTask
apply plugin: 'elasticsearch.build'
apply plugin: 'elasticsearch.mrjar'
apply plugin: 'elasticsearch.publish'
tasks.named('jar').configure {
// guarding for intellij

View file

@ -3,7 +3,6 @@ plugins {
}
apply plugin: 'elasticsearch.build'
apply plugin: 'elasticsearch.publish'
tasks.named("dependencyLicenses").configure {
mapping from: /asm-.*/, to: 'asm'

View file

@ -3,7 +3,6 @@ plugins {
}
apply plugin: 'elasticsearch.build'
apply plugin: 'elasticsearch.publish'
tasks.named("dependencyLicenses").configure {
mapping from: /asm-.*/, to: 'asm'

View file

@ -8,7 +8,6 @@
*/
apply plugin: 'elasticsearch.build'
apply plugin: 'elasticsearch.publish'
dependencies {
api project(":test:framework")

View file

@ -1,4 +1,5 @@
apply plugin: 'elasticsearch.build'
apply plugin: 'elasticsearch.publish'
apply plugin: 'elasticsearch.internal-yaml-rest-test'
apply plugin: 'elasticsearch.yaml-rest-compat-test'

View file

@ -1,5 +1,5 @@
apply plugin: 'elasticsearch.build'
apply plugin: 'elasticsearch.publish'
base {
archivesName = 'x-pack-template-resources'

View file

@ -6,7 +6,6 @@
*/
apply plugin: 'elasticsearch.internal-es-plugin'
apply plugin: 'elasticsearch.publish'
apply plugin: 'elasticsearch.internal-cluster-test'
esplugin {
name = 'x-pack-identity-provider'

View file

@ -10,7 +10,6 @@ import static org.elasticsearch.gradle.util.PlatformUtils.normalize
apply plugin: 'elasticsearch.internal-es-plugin'
apply plugin: 'elasticsearch.internal-cluster-test'
apply plugin: 'elasticsearch.internal-yaml-rest-test'
apply plugin: 'elasticsearch.publish'
esplugin {
name = 'x-pack-kql'