We have a multiproject gradle repository with several subprojects. One of the subprojects is supposed to generate separate testJar and publish it to the local maven repository:
// build a repositories-testJar.jar with test classes for services tests
tasks.register<Jar>("testJar") {
archiveClassifier.set("testJar")
from(sourceSets["test"].output)
}
// the testJar must be built within the build phase
tasks.build {
dependsOn(tasks.withType<Jar>())
}
// needed for publishing plugin to be aware of the testJar
configurations.create("testJar") {
extendsFrom(configurations["testCompile"])
}
artifacts {
add("testJar", tasks.named<Jar>("testJar"))
}
This works and I can see -testJar.jar is generated within the /build/libs.
Then, within the rootProject gradle.kts we set up a publishing extension:
allprojects {
configure<PublishingExtension> {
publications {
create<MavenPublication>(project.name) {
groupId = "foo.bar"
artifactId = project.name.toLowerCase().replace(":", "-")
version = "ci"
from(components["kotlin"])
}
}
repositories {
maven {
url = uri("file://${rootProject.rootDir}/../m2")
}
}
}
}
This also normally works and I can see modules being published in the m2 directory. However the testJar is not published. I couldn't find a way how to attach the testJar artifact to the publication defined in root project.
Solved with addition of:
publishing {
publications {
create<MavenPublication>(project.name + "-" + testArtifact.name) {
groupId = "my.group"
artifactId = project.name.toLowerCase().replace(":", "-")
version = "version"
artifact(testArtifact)
}
}
}
Related
I'd like to publish the output of my custom zip task to a maven repo. My problem is that when I set the artifact of the publication as the zip task, the file that gets zipped is not what gets published. Instead what gets published is the value given to the "from" argument of my custom zip task. How would I make it so that "jar.zip" is the file that is published?
tasks.register('zipJars', Zip) {
archiveFileName = "jar.zip"
destinationDirectory = layout.buildDirectory.dir("${projectDir.parentFile}/DesktopAndroid/jars/zipped")
from fatJarDev
}
publishing {
publications {
apkBuilding(MavenPublication){
artifact zipJars
}
}
repositories {
maven {
name = 'Local'
url = "file://${rootDir}/Repository"
}
}
}```
Ah - are you referring to the name of the file in the maven repo ? you will need to customise it in publication ;
see https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPublication.html
publishing {
publications {
apkBuilding(MavenPublication){
artifact zipJars
artifactId 'zipjars'
}
}
repositories {
maven {
name = 'Local'
url = "file://${rootDir}/Repository"
}
}
}
I am trying to publish obfuscated jars to nexus repo.
I created a task to obfuscate the code using proguard, then a task that copy the obfuscated jars into build folder.
task proguard (type: proguard.gradle.ProGuardTask) {
println("Performing Obfuscation ..")
configuration 'proguard.conf'
subprojects { porject ->
injars "${projectDir}/build/libs/${porject.name}-${rootProject.version}.jar"
outjars "${projectDir}/build/libs/obfuscated/${porject.name}-${rootProject.version}.jar"
}
libraryjars "/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar"
}
task postProguard (){
doFirst{
println("Deleting Non Obfuscated jars")
subprojects { project ->
delete "${projectDir}/build/libs/${project.name}-${rootProject.version}.jar"
}
println("Copying Obfuscated Jars")
subprojects { project ->
copy {
from "${projectDir}/build/libs/obfuscated/"
into "${projectDir}/build/libs/"
include '*.jar'
}
}
}
}
proguard.finalizedBy postProguard
the issue is when I run ./gradlew publish the project gets re-built and the jars gets changed to non obfuscated again.
I tried to change the publishing task but without results.
publishing {
if(new File("${projectDir}/build/libs/obfuscated").exists()){
publications {
maven(MavenPublication) {
artifact "${projectDir}/build/libs/${project.name}-${rootProject.version}.jar"
pom.withXml {
def dependency = asNode().appendNode('dependencies').appendNode('dependency')
dependency.appendNode("groupId", "${project.name}")
dependency.appendNode("artifactId", "${project.name}")
dependency.appendNode("version", "${rootProject.version}")
}
}
}
}
repositories {
maven {
name = 'maven-snapshots'
url = ***
}
}
}
I added a builtBy attribute to the publication here is a working code
publications {
if(new File("${projectDir}/build/libs/obfuscated").exists()){
maven(MavenPublication) {
artifact ("${projectDir}/build/libs/${project.name}-${rootProject.version}.jar"){
builtBy postProguard
}
}
}
}
I have written a gradle task which writes a custom pom to "build/libs/pom.xml"
I want to publish above custom pom.xml , so I defined :
def pomXml = artifacts.add('archives', file("$buildDir/libs/pom.xml")) {
builtBy('writePoms') // writePoms is my custom task to create custom pom.xml
}
publishing {
publications {
maven(MavenPublication) {
artifact pomXml
artifactId "myartifact"
groupId 'com.xyz'
version project.version
}
}
repositories {
// Task for manually publishing the maven image. When CI works, setup CI_TOKEN auth.
maven {
url <url>
name "GitLab"
credentials(HttpHeaderCredentials) {
name = System.getenv("CI_JOB_TOKEN") ? "Job-Token" : "Private-Token"
value = System.getenv("CI_JOB_TOKEN") ? System.getenv("CI_JOB_TOKEN") : gitLabPrivateToken
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
When I run ./gradlew publish it publishes pom from "build/publications/maven/pom-default.xml" instead of "build/libs/pom.xml"
Can someone help how can I achieve it?
I had a similar issue (aggregate build of multiple external repositories with their own build systems and then publishing the results of those builds to a local artifactory).
I was able to effectively replace the generated POM for the "artifacts" publication with the content of an external POM via withXml:
pluginManager.withPlugin("maven-publish") {
extensions.configure(PublishingExtension::class.java) {
publications.register<MavenPublication>("artifacts") {
groupId = "com.example"
artifactId = "external"
version = "1.0.0"
artifact("external.jar")
pom.withXml {
asNode().setValue(XmlParser().parse("some/external/pom.xml").value())
}
}
}
}
This leaves the <xml ...> and <project ...> nodes intact (acceptable for my case).
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.
I need to ignore some dependencies defined in the configuration "configurations.nonDistributable" when using gradles plugin maven-publish to generate pom files, I haven't found a reliable way of doing this, except for manually parsing the XML to remove them. Am I missing something, does gradle allow for an easier way of doing this?
build.gradle example:
configurations{
nonDistributable
}
dependencies {
nonDistributable ('org.seleniumhq.selenium:selenium-java:2.52.0'){
exclude group:'com.google.guava' // included in elasticsearch
}
nonDistributable ('com.assertthat:selenium-shutterbug:0.3') {
transitive = false
}
nonDistributable 'mysql:mysql-connector-java:5.1.40'
nonDistributable fileTree(dir: 'non-distributable-libs', include: '*.jar')
}
// generate subprojects pom
subprojects {
apply plugin: 'maven-publish'
model {
tasks.generatePomFileForMavenJavaPublication {
destination = file("$buildDir/../../$distDir/build/pom/$project.name-pom.xml")
}
}
afterEvaluate { project ->
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
}
}
// generate root project pom
model {
tasks.generatePomFileForMavenJavaPublication {
destination = file("$buildDir/../$distDir/build/pom/$project.name-pom.xml")
}
}
afterEvaluate { project ->
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
}
You can create your own publication pom. It would look something like this:
customMaven(MavenPublication) {
artifactId 'myArtifactId'
pom.withXml {
def dependencies = asNode().appendNode('dependencies')
configurations.specialConfiguration.getResolvedConfiguration().getFirstLevelModuleDependencies().each {
def dependency = dependencies.appendNode('dependency')
dependency.appendNode('groupId', it.moduleGroup)
dependency.appendNode('artifactId', it.moduleName)
dependency.appendNode('version', it.moduleVersion)
}
}
}
Then you can create a special configuration that extends from only those configurations that you want to include.
I am using this to create a special pom that contains all testRuntime dependencies to be used for integration tests separated from the main project.