I want to publish multiple artifacts with different names with gradle and maven-publish - maven

I have a library containing usual classes and those especially for unit tests. So I want to publish two separate artifacts from the same project. My working solution with the maven plugin looks like this:
task jarTest (type: Jar, dependsOn: testClasses) {
from sourceSets.test.output
archiveBaseName.set('foo-test')
description = 'test utilities'
}
artifacts {
archives jarTest
}
uploadArchives {
repositories {
mavenDeployer {
//...
addFilter('foo') {artifact, file ->
artifact.name == 'foo'
}
addFilter('foo-test') {artifact, file ->
artifact.name == 'foo-test'
}
}
}
}
Unfortunately the maven plugin is deprecated and will be removed in Gradle 7. maven-publish is the suggested replacement and I'm looking for a replacement solution.
My current attempt looks like
publishing {
publications {
mavenJava(MavenPublication) {
artifact jar
artifact jarTest
}
}
}
There is the obvious problem that there are two artifacts with the same name.
Setting the name like this does not work:
artifactId = jar.archiveBaseName
this neither:
afterEvaluate {
artifactId = jar.archiveBaseName
}
It's possible to configure the artifact like this
artifact(jar) {
classifier "src"
extension "zip"
}
But there is no property for the name regarding the documentation (https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenArtifact.html).
So I'm looking for sth. like the addFilter from the maven plugin.

Related

Gradle how to publish a gradle-plugin to maven central

Hi I have a java project, which contains a submodule which is a gradle plugin. I want to publish this module to maven central.
I used this two plugins in my build.gradle:
plugins {
id 'java-gradle-plugin'
id 'maven-publish'
}
and my publishing block looks something like:
publishing {
publications {
javaLibrary(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar
artifactId = project.archivesBaseName
pom {
name = artifactId
description = "..."
url =
licenses {
license {
}
}
developers {
...
}
scm {
...
}
issueManagement {
...
}
ciManagement {
...
}
}
}
}
repositories { maven { url = "some local repo" } }
}
I noticed that when I build this module, the generated pom-default.xml is what I expected, but when I run gradle publishToMavenLocal and manually checked the pom.xml file in the .m2 folder, all the metadata like name description licenses are gone!
I also noticed in the .m2 folder there are 2 artifacts that are related to this single plugin, I think it's somewhat related with https://docs.gradle.org/current/userguide/plugins.html#sec:plugin_markers but I don't fully understand the meaning. Both these 2 artifacts' pom are missing the pom metadata as I described above.
Could some gradle expert help me here: how to keep the metadata in the published pom?
You should not need to manually define a MavenPublication for your plugin submodule. The java-gradle-plugin reacts to the application of the maven-publish plugin and automatically configures/creates publications for the plugin artifacts. See this line.
You are correct for the (2) artifacts produced. One is the plugin marker (single pom.xml) and the other is the actual plugin JAR artifact.
As for POM customization, Gradle seemingly provides its own the POM irrespective of any POM customization(s) you have defined: https://github.com/gradle/gradle/issues/17022
Sorry for late answer, but you can do something like this:
afterEvaluate {
tasks.withType(GenerateMavenPom) { task ->
doFirst {
// Update POM here
def pom = task.pom
pom.name = ...
pom.url = ...
pom.description = ...
pom.scm {
...
}
}
}
}
This will catch the pom of the plugin marker artifact as well.

publish groovy doc with gradle

I have a project with about 50% Java code and 50% Groovy that i try to publish to Sonatype ossrh. Publishing snapshots goes well but the docs jar is missing (both when publishing locally and publishing to Sonatype Nexus). I can create the combined groovy/java docs by defining:
groovydoc {
use = true
groovyClasspath = configurations.compile // http://issues.gradle.org/browse/GRADLE-1391
}
task groovydocJar(type: Jar, dependsOn: groovydoc ) {
classifier 'javadoc' // must use javadoc classifier to be able to deploy to Sonatype
from groovydoc.destinationDir
}
and running ./gradlew groovydocJar produces the intended -javadoc.jar without problems.
My issue is that this docs jar is not included the publish task.
I tried the following
publishing {
publications {
maven(MavenPublication) {
from components.java
artifacts {
archives sourcesJar
archives groovydocJar
}
versionMapping {
usage('java-api') {
fromResolutionOf('runtimeClasspath')
}
usage('java-runtime') {
fromResolutionResult()
}
}
pom {
// omitted for brevity
}
}
}
}
... but e.g. `./gradlew publishToMavenLocal` publishes only the classes jar, the pom, a module and the sources jar.
No sign of a javadoc jar. I thought this was the idea of the artifacts section but maybe something is missing.
How can i tell the publishing task to include publishing of the groovydocs jar?
Gradle version is 6.8.3, jvm version is 1.8 and i depend on `compile 'org.codehaus.groovy:groovy-all:3.0.7'`
The complete build script is available here:
https://github.com/perNyfelt/ProjectDeployer/blob/main/build.gradle
I figured it out:
That artifacts.archives way was not working.
The syntax for adding the groovy doc is like this:
publishing {
publications {
maven(MavenPublication) {
from components.java
artifact(groovydocJar) {
classifier = 'javadoc'
}
// etc...
}
}
}

Move publishing configuration to one place in gradle

I have a project which has modules, my goal is to configure publishing after each module is built and after all modules are built, so I could create a zip file with all the jars inside and upload it as well. I do it in subprojects section and in outer section.
publishing {
publications {
mavenJava(MavenPublication) {
//my artifacts here
}
}
repositories {
maven {
url "${artifactoryURL}"
credentials {
username = "${artifactoryUsername}"
password = "${artifactoryPassword}"
}
}
}
}
Is there a way to move repositories configuration to one place, so I could avoid duplication of this configuration?
I guess that you're creating your deployables in a top-level (root, parent) project, that does not have any sources.
Is there a way to move repositories configuration to one place, so I could avoid duplication of this configuration?
Sure. Just use subprojects, allprojects or generic configure, depending on your needs:
allprojects {
id 'maven-publish'
publishing {
repositories {
maven {
url "http://maven.repo"
}
}
}
}
This will configure publishing for all the projects (be aware of that you may not want to publish everything).
For a projects with Java source you can configure publishing like usual:
subprojects {
publishing {
publications {
main(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar
}
}
}
}
And for root project just configure deployments as in your previous question.

How to tie publishing of sources to installing to local Maven repository?

To install sources to local Maven repository, I was taught to write
apply plugin: "maven-publish"
task sourceJar(type: Jar) {
from sourceSets.main.allJava
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourceJar {
classifier "sources"
}
}
}
}
and it copies files as required. Now I wish this work automatically along with install task of maven plugin.
I tried several lines like
install.dependsOn(publishing.publishSources)
or
install.dependsOn(publishSources)
but failed with various errors.
You could use the nebula.source-jar plugin. Or you could at least copy/paste the bolierplate from the readme.
Eg: Eliminates this boilerplate:
tasks.create('sourceJar', Jar) {
dependsOn tasks.classes
from sourceSets.main.allSource
classifier 'sources'
extension 'jar'
group 'build'
}
publishing {
publications {
nebula(MavenPublication) { // if maven-publish is applied
artifact tasks.sourceJar
}
nebulaIvy(IvyPublication) { // if ivy-publish is applied
artifact tasks.sourceJar
}
}
}

Gradle: How to upload custom JAR file to Maven repository

I build a jar file without using Gradle Jar task (I need to be using Ant task for that inside my task). How do I configure uploadArchives to be able to install JAR in specified repository.
I have tried to override default artifact with
uploadArchives {
repositories {
mavenDeployer {
// some Maven configuration
}
}
}
artifacts {
archives file: file('bin/result.jar')
}
but I'm getting an error that there may not be 2 artifacts with the same type and classifier, which means this configuration adds rather that overrides configuration.
You are right, artifacts closure can only add artifacts to the given configuration (see ArtifactHandler API).
You have two options:
1) Add an artifact filter as described here (see ch. 45.6.4.1. "Multiple artifacts per project"). If you use this, try declaring your archives configuration like:
artifacts {
archives file: file('bin/result.jar'), name: 'result', type: 'jar'
}
This way, you something like this in your artifact filter:
addFilter('result') {artifact, file ->
artifact.name == 'result'
}
2) Upload it as a separate maven module. If result.jar is the only jar you are uploading this may be a good solution.
configurations {
resultArchives
}
uploadResultArchives {
repositories {
mavenDeployer {
repository(url: "same/url/here")
}
}
}
artifacts{
resultArchives file: file('bin/result.jar')
}
Hope this helps.

Resources