Skip to content

Commit 0183eb8

Browse files
committed
Support publishing to Maven Central
1 parent 6aac058 commit 0183eb8

File tree

8 files changed

+237
-108
lines changed

8 files changed

+237
-108
lines changed

build.gradle.kts

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,51 +11,75 @@ dependencies {
1111
implementation("com.gradle.publish:plugin-publish-plugin:2.0.0")
1212
implementation("com.gradle:common-custom-user-data-gradle-plugin:2.4.0")
1313
implementation("com.gradle:develocity-gradle-plugin:4.2.2")
14+
implementation("com.gradleup.nmcp:nmcp:1.2.0")
1415
implementation("org.asciidoctor:asciidoctor-gradle-jvm:4.0.5")
1516
implementation("org.gradlex:jvm-dependency-conflict-resolution:2.4")
1617
implementation("org.gradlex:reproducible-builds:1.1")
1718
}
1819

20+
dependencies.constraints {
21+
implementation("org.jetbrains:annotations:13.0!!") {
22+
because("This version is enforced by Gradle through the Kotlin plugin")
23+
}
24+
}
25+
1926
// ==== the following can be remove once we update the onventions to '0.7'
2027
group = "org.gradlex"
2128
java { toolchain.languageVersion = JavaLanguageVersion.of(17) }
2229
tasks.checkstyleMain { exclude("buildparameters/**") }
30+
// ====
31+
2332
buildParameters {
24-
pluginId("gradlexbuild.build-parameters")
33+
pluginId("org.gradlex.internal.gradlex-build-parameters")
2534
bool("ci") {
26-
description.set("Whether or not the build is running in a CI environment")
35+
description = "Whether or not the build is running in a CI environment"
2736
fromEnvironment()
28-
defaultValue.set(false)
37+
defaultValue = false
2938
}
3039
group("signing") {
40+
// allow to disable signing for locat testing
41+
bool("disable") {
42+
defaultValue = false
43+
}
3144
// key and passphrase need default values because SigningExtension.useInMemoryPgpKeys does not accept providers
32-
description.set("Details about artifact signing")
45+
description = "Details about artifact signing"
3346
string("key") {
34-
description.set("The ID of the PGP key to use for signing artifacts")
47+
description = "The ID of the PGP key to use for signing artifacts"
3548
fromEnvironment()
36-
defaultValue.set("UNSET")
49+
defaultValue = "UNSET"
3750
}
3851
string("passphrase") {
39-
description.set("The passphrase for the PGP key specified by signing.key")
52+
description = "The passphrase for the PGP key specified by signing.key"
4053
fromEnvironment()
41-
defaultValue.set("UNSET")
54+
defaultValue = "UNSET"
4255
}
4356
}
4457
group("pluginPortal") {
4558
// The publish-plugin reads these values directly from System.env. We model them here
4659
// for completeness and documentation purposes.
47-
description.set("Credentials for publishing to the plugin portal")
60+
description = "Credentials for publishing to the plugin portal"
4861
string("key") {
49-
description.set("The Plugin portal key for publishing the plugin")
62+
description = "The Plugin portal key for publishing the plugin"
5063
fromEnvironment("GRADLE_PUBLISH_KEY")
5164
}
5265
string("secret") {
53-
description.set("The Plugin portal secret for publishing the plugin")
66+
description = "The Plugin portal secret for publishing the plugin"
5467
fromEnvironment("GRADLE_PUBLISH_SECRET")
5568
}
5669
}
70+
71+
group("mavenCentral") {
72+
description = "Credentials for publishing to Maven Central"
73+
string("username") {
74+
description = "The Maven Central username for publishing"
75+
fromEnvironment()
76+
}
77+
string("password") {
78+
description = "The Maven Central password for publishing"
79+
fromEnvironment()
80+
}
81+
}
5782
}
58-
// ====
5983

6084
pluginPublishConventions {
6185
id("${project.group}.internal.gradlex-build-conventions")

src/main/java/org/gradlex/conventions/feature/PluginDefinition.java

Lines changed: 0 additions & 60 deletions
This file was deleted.

src/main/java/org/gradlex/conventions/feature/PluginPublishConventionsExtension.java renamed to src/main/java/org/gradlex/conventions/feature/PublishingConventionsExtension.java

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.gradlex.conventions.feature;
1818

1919
import org.gradle.api.Action;
20+
import org.gradle.api.GradleException;
2021
import org.gradle.api.Project;
2122
import org.gradle.api.provider.Provider;
2223
import org.gradle.api.publish.maven.MavenPomDeveloper;
@@ -25,32 +26,39 @@
2526

2627
import java.util.ArrayList;
2728
import java.util.List;
28-
import java.util.Set;
2929

3030
@NullMarked
31-
public abstract class PluginPublishConventionsExtension extends PluginDefinition {
31+
public abstract class PublishingConventionsExtension {
3232

33-
public static final String NAME = "pluginPublishConventions";
33+
public static final String NAME = "publishingConventions";
3434

3535
private final Project project;
3636
private final GradlePluginDevelopmentExtension gradlePlugin;
37+
private final List<PublishingDefinition> definitions = new ArrayList<>();
3738

3839
List<Action<MavenPomDeveloper>> developers = new ArrayList<>();
3940

40-
public PluginPublishConventionsExtension(
41+
public PublishingConventionsExtension(
4142
Project project,
4243
GradlePluginDevelopmentExtension gradlePlugin
4344
) {
44-
super(project.getName(), gradlePlugin);
4545
this.project = project;
4646
this.gradlePlugin = gradlePlugin;
4747
}
4848

49-
public void additionalPlugin(String id, Action<PluginDefinition> action) {
50-
PluginDefinition plugin = project.getObjects().newInstance(PluginDefinition.class, id, gradlePlugin);
51-
plugin.id(id);
52-
plugin.pluginDefinition.getTags().set(getTags());
53-
action.execute(plugin);
49+
public void pluginPortal(String id, Action<PublishingPluginPortalDefinition> action) {
50+
var definition = project.getObjects().newInstance(
51+
PublishingPluginPortalDefinition.class, id, gradlePlugin, project.getProviders());
52+
definitions.stream().filter(d -> d instanceof PublishingPluginPortalDefinition).findFirst().ifPresent(
53+
d -> definition.getTags().set(((PublishingPluginPortalDefinition) d).getTags()));
54+
action.execute(definition);
55+
definitions.add(definition);
56+
}
57+
58+
public void mavenCentral(Action<PublishingMavenCentralDefinition> action) {
59+
var definition = project.getObjects().newInstance(PublishingMavenCentralDefinition.class);
60+
action.execute(definition);
61+
definitions.add(definition);
5462
}
5563

5664
public void gitHub(String gitHub) {
@@ -66,31 +74,21 @@ public void developer(Action<MavenPomDeveloper> action) {
6674
developers.add(action);
6775
}
6876

69-
public Provider<String> getId() {
70-
return project.getProviders().provider(pluginDefinition::getId);
77+
public Provider<String> getGitHub() {
78+
return gradlePlugin.getVcsUrl();
7179
}
7280

73-
public Provider<String> getImplementationClass() {
74-
return project.getProviders().provider(pluginDefinition::getImplementationClass);
81+
public Provider<String> getWebsite() {
82+
return gradlePlugin.getWebsite();
7583
}
7684

7785
public Provider<String> getDisplayName() {
78-
return project.getProviders().provider(pluginDefinition::getDisplayName);
86+
if (definitions.isEmpty()) { throw new GradleException("No publication defined"); }
87+
return definitions.get(0).getDisplayName();
7988
}
8089

8190
public Provider<String> getDescription() {
82-
return project.getProviders().provider(pluginDefinition::getDescription);
83-
}
84-
85-
public Provider<Set<String>> getTags() {
86-
return pluginDefinition.getTags();
87-
}
88-
89-
public Provider<String> getGitHub() {
90-
return gradlePlugin.getVcsUrl();
91-
}
92-
93-
public Provider<String> getWebsite() {
94-
return gradlePlugin.getWebsite();
91+
if (definitions.isEmpty()) { throw new GradleException("No publication defined"); }
92+
return definitions.get(0).getDescription();
9593
}
9694
}

src/main/java/org/gradlex/conventions/feature/PluginPublishConventionsPlugin.java renamed to src/main/java/org/gradlex/conventions/feature/PublishingConventionsPlugin.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
import buildparameters.BuildParametersExtension;
2020
import buildparameters.GeneratedBuildParametersPlugin;
2121
import com.gradle.publish.PublishPlugin;
22+
import nmcp.NmcpAggregationExtension;
23+
import nmcp.NmcpAggregationPlugin;
24+
import nmcp.NmcpPlugin;
2225
import org.gradle.api.Plugin;
2326
import org.gradle.api.Project;
2427
import org.gradle.api.plugins.JavaPluginExtension;
@@ -32,36 +35,53 @@
3235
import static org.gradle.language.base.plugins.LifecycleBasePlugin.CHECK_TASK_NAME;
3336

3437
@NullMarked
35-
public abstract class PluginPublishConventionsPlugin implements Plugin<Project> {
38+
public abstract class PublishingConventionsPlugin implements Plugin<Project> {
3639
@Override
3740
public void apply(Project project) {
3841
var plugins = project.getPlugins();
3942
var extensions = project.getExtensions();
4043
var tasks = project.getTasks();
44+
var dependencies = project.getDependencies();
4145

4246
plugins.apply(PublishPlugin.class);
47+
plugins.apply(NmcpPlugin.class);
48+
plugins.apply(NmcpAggregationPlugin.class);
4349
plugins.apply(SigningPlugin.class);
4450
plugins.apply(GeneratedBuildParametersPlugin.class);
4551

4652
var java = extensions.getByType(JavaPluginExtension.class);
4753
var gradlePlugin = extensions.getByType(GradlePluginDevelopmentExtension.class);
4854
var publishing = extensions.getByType(PublishingExtension.class);
55+
var nmcpAggregation = extensions.getByType(NmcpAggregationExtension.class);
4956
var signing = extensions.getByType(SigningExtension.class);
5057
var buildParameters = extensions.getByType(BuildParametersExtension.class);
5158
var pluginPublishConventions = extensions.create(
52-
PluginPublishConventionsExtension.NAME, PluginPublishConventionsExtension.class,
59+
PublishingConventionsExtension.NAME, PublishingConventionsExtension.class,
5360
project, gradlePlugin);
5461

5562
tasks.named("publishPlugins", task -> task.dependsOn(CHECK_TASK_NAME));
5663

5764
java.withJavadocJar();
5865
java.withSourcesJar();
5966

60-
signing.useInMemoryPgpKeys(
61-
buildParameters.getSigning().getKey(),
62-
buildParameters.getSigning().getPassphrase()
63-
);
67+
// signing
68+
signing.setRequired(!buildParameters.getSigning().getDisable());
69+
if (signing.isRequired()) {
70+
signing.useInMemoryPgpKeys(
71+
buildParameters.getSigning().getKey(),
72+
buildParameters.getSigning().getPassphrase()
73+
);
74+
}
6475

76+
// Maven Central
77+
dependencies.add("nmcpAggregation", project.project(project.getPath())); // for NmcpAggregationPlugin
78+
nmcpAggregation.centralPortal(central -> {
79+
central.getUsername().set(buildParameters.getMavenCentral().getUsername());
80+
central.getPassword().set(buildParameters.getMavenCentral().getPassword());
81+
central.getPublishingType().set("AUTOMATIC"); // "USER_MANAGED"
82+
});
83+
84+
// Metadata for all publications
6585
publishing.getPublications().withType(MavenPublication.class).configureEach(p -> {
6686
p.getPom().getName().set(pluginPublishConventions.getDisplayName());
6787
p.getPom().getDescription().set(pluginPublishConventions.getDescription());
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright the GradleX team.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.gradlex.conventions.feature;
18+
19+
import org.gradle.api.provider.Provider;
20+
import org.jspecify.annotations.NullMarked;
21+
22+
@NullMarked
23+
public interface PublishingDefinition {
24+
Provider<String> getDisplayName();
25+
26+
Provider<String> getDescription();
27+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright the GradleX team.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.gradlex.conventions.feature;
18+
19+
import org.gradle.api.provider.Property;
20+
import org.jspecify.annotations.NullMarked;
21+
22+
@NullMarked
23+
public abstract class PublishingMavenCentralDefinition implements PublishingDefinition {
24+
25+
public abstract Property<String> getDisplayName();
26+
27+
public abstract Property<String> getDescription();
28+
29+
public void displayName(String displayName) {
30+
getDisplayName().set(displayName);
31+
}
32+
33+
public void description(String description) {
34+
getDescription().set(description);
35+
}
36+
}

0 commit comments

Comments
 (0)