Reputation: 3262
I have a multi-module project which supports maven and gradle builds hence it contains pom.xml
files along side with build.gradle
. I'm working on a demo and I would like to show how to build and deploy to nexus the same project using either gradle or maven. That's why I have two different build systems in case you wonder why.
You may see the project structure below.
You may look into the code here.
I've configured the gradle maven-publish plugin in order to publish all modules to my local nexus repository however when I run gradle publish
I hit this error:
Execution failed for task ':publishMavenJavaPublicationToMavenRepository'.
> Failed to publish publication 'mavenJava' to repository 'maven'
> Artifact machinery-config-0.0.1.jar wasn't produced by this build.
The issue is related with having the publishing
section within $rootDir/build.gradle
.
It's confusing, the maven-publish somehow is trying to publish an artifact that doesn't exist machinery-config-0.0.1.jar
, machinery-config
is the name of the rootProject
.
One workaround could be to remove the publishing
section from the rootProject
and duplicate it in the sub-projects. I don't like that approach, since I will end up with a lot of duplicated code.
Could you point me out a better way to use maven-publish within a multi-module project ?
Upvotes: 3
Views: 3672
Reputation: 3262
After some digging I realized that I had two issues:
publishing
section was outside of subprojects
section, then gradle tried to deploy an artifact using rootProject.name
ignoring the included modules.
group
& version
properties were outside subprojects
therefore deployed artifacts had undefined
as version number, e.g machinery-config-core-undefined.jar
In order to fix issue number two, I moved group
& version
into subprojects
section.
My build also produces a BOM artifact, hence I need two publications from components.java
and from components.javaPlatform
, so I wrote this script gradle/ext/publish-common.gradle
which exports two functions, I will use later on both publications to keep code duplication at bay.
def pom(it) {
it.licenses {
license {
name = 'The Apache License, Version 2.0'
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
it.developers {
developer {
id = 'eljaiek'
name = 'Eduardo Eljaiek'
email = '[email protected]'
}
}
it.scm {
connection = 'scm:git:git://github.com/eljaiek/machinery-config.git'
developerConnection = 'scm:git:[email protected]:eljaiek/machinery-config.git'
url = 'https://github.com/eljaiek/machinery-config'
}
}
def nexusRepository(it) {
it.url = version.endsWith('SNAPSHOT') ? project.nexusSnapshotsUrl : project.nexusReleasesUrl
it.credentials {
username project.nexusUser
password project.nexusPasswd
}
}
ext {
pom = this.&pom
nexusRepository = this.&nexusRepository
}
Additionally, I added from components.javaPlatform
publication into machinery-config-dependencies/build.gradle
in order to deploy the BOM artifact:
apply plugin: 'maven-publish'
apply from: "$rootDir/gradle/ext/publish-common.gradle"
publishing {
publications {
mavenBom(MavenPublication) {
from components.javaPlatform
pom { x -> pom(x)}
}
}
repositories {
maven { x -> nexusRepository(x) }
}
}
The apply from: "$rootDir/gradle/ext/publish-common.gradle"
will apply the script I wrote, this is required in order to import pom()
and nexusRepository()
functions into my build script.
To deploy from components.java
artifacts, I added a publishing
section in subprojects
under if (it.name != 'machinery-config-dependencies')
statement into $rootDir/build.gradle
apply plugin: 'ru.vyarus.pom'
apply from: "$rootDir/gradle/ext/publish-common.gradle"
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
pom { x -> pom(x)}
}
}
repositories {
maven { x -> nexusRepository(x) }
}
}
I used Gradle POM plugin instead of maven-publish
. It provides maven's dependencies declaration simplicity and implicitly applies maven-publish plugin.
See the code here
References
Extract common methods from Gradle build script
Upvotes: 1