Gradle - plugin maven-publish: How to publish only specific publication to a repository
Asked Answered
F

3

24

We have two different artifacts that is going to be published to two different maven repositories.

  • "ProjectXMergedWar" should be published to "MyMavenRepo1" (snapshots)
  • "ProjectXJarRelease" should be published to "MyMavenRepo2" (release)
  • "ProjectXMergedWar" should never be published to "MyMavenRepo2" (release)
  • "ProjectXJarRelease" should never be published to "MyMavenRepo1" (snapshots)

We use the plugin maven-publish where you configure a set of publications and reposistories. The plugin then generates tasks for all combinations of publications and repositories (see tasks list at the bottom). Currently the tasks publish and publishRelease is doing what we want, but there are tasks we don't want.

Some solutions might be:

  • Can we remove the unwanted tasks**?
  • Can we configure maven-publish to only generate two publish tasks (the wanted tasks*)?
  • Can we call the correct classes directly (repo.publish(artifact) or something like that)?

I have looked at the source code of PublishToMavenRepository. It seems like the action I want to achive is located in protected void doPublish.

*Wanted tasks:

  • publishProjectXMergedWarPublicationToMyMavenRepo1Repository + generatePom
  • publishProjectXJarReleasePublicationToMyMavenRepo2Repository + generatePom

**Unwanted tasks:

  • publishProjectXMergedWarPublicationToMyMavenRepo2Repository
  • publishProjectXJarReleasePublicationToMyMavenRepo1Repository

Gradle file:

apply plugin: 'maven-publish'
publishing {
    publications {
        ProjectXMergedWar(MavenPublication) {
            artifact mergeWar
            artifactId = 'projectx'
        }
        ProjectXJarRelease(MavenPublication) {
            artifact releaseJar
            artifactId = 'projectx'
        }
    }
    repositories {
        maven {
            name 'MyMavenRepo1'
            url 'http://artifactory/url/our-snapshot-local'
            credentials { (...) }
        }
        maven {
            name 'MyMavenRepo2'
            url 'http://artifactory/url/our-release-local'
            credentials { (...) }
        }
    }
}

task publish(dependsOn: [
    'generatePomFileForProjectXMergedWarPublication',
    'publishProjectXMergedWarPublicationToMyMavenRepo1Repository'
], overwrite: true) {
    // We override the normal publish which would have tried to publish all combinations of defined
    // publications and repositories:
    // - publishProjectXMergedWarPublicationToMyMavenRepo1Repository      (we use this in normal snapshot publish)
    // - publishProjectXMergedWarPublicationToMyMavenRepo2Repository      (not to be used)
    // - publishProjectXJarReleasePublicationToMyMavenRepo1Repository     (not to be used)
    // - publishProjectXJarReleasePublicationToMyMavenRepo2Repository     (we use this one in publishRelease)
}
task publishRelease(dependsOn: [
    'generatePomFileForProjectXJarReleasePublication',
    'publishProjectXJarReleasePublicationToMyMavenRepo2Repository'
])

Output from tasks:

$ ./gradlew tasks

(...)

Publishing tasks
----------------
generatePomFileForProjectXJarReleasePublication - Generates the Maven POM file for publication 'ProjectXJarRelease'.
generatePomFileForProjectXMergedWarPublication - Generates the Maven POM file for publication 'ProjectXMergedWar'.
publishProjectXJarReleasePublicationToMavenLocal - Publishes Maven publication 'ProjectXJarRelease' to the local Maven repository.
publishProjectXJarReleasePublicationToMyMavenRepo1Repository - Publishes Maven publication 'ProjectXJarRelease' to Maven repository 'MyMavenRepo1'.
publishProjectXJarReleasePublicationToMyMavenRepo2Repository - Publishes Maven publication 'ProjectXJarRelease' to Maven repository 'MyMavenRepo2'.
publishProjectXMergedWarPublicationToMavenLocal - Publishes Maven publication 'ProjectXMergedWar' to the local Maven repository.
publishProjectXMergedWarPublicationToMyMavenRepo1Repository - Publishes Maven publication 'ProjectXMergedWar' to Maven repository 'MyMavenRepo1'.
publishProjectXMergedWarPublicationToMyMavenRepo2Repository - Publishes Maven publication 'ProjectXMergedWar' to Maven repository 'MyMavenRepo2'.
publishToMavenLocal - Publishes all Maven publications produced by this project to the local Maven cache.

(...)

Other tasks
-----------
(...)
publish
publishRelease
(...)
Frugivorous answered 29/1, 2014 at 13:59 Comment(0)
H
22

You could disable and hide the "invalid" tasks like so:

apply plugin: 'maven-publish'

publishing {
    repositories {
        maven {
            name 'Dev'
            url 'http://dev/'
            credentials {
                username 'username'
                password 'password'
            }
        }

        maven {
            name 'Prod'
            url 'http://prod/'
            credentials {
                username 'username'
                password 'password'
            }
        }

    }

    publications {
        // This will only be enabled on Dev
        MyDevJar(MavenPublication) {
            artifactId "test"
            version "1.0"
            groupId "org.example"
            artifact file('abc')
            ext.repo = 'Dev'
        }

        // This will only be enabled on prod
        MyJar(MavenPublication) {
            artifactId "test"
            version "1.0"
            groupId "org.example"
            artifact file('abc')
            ext.repo = 'Prod'
        }
    }
}

afterEvaluate {
    tasks.withType(PublishToMavenRepository) { task ->
        if (task.publication.hasProperty('repo') && task.publication.repo != task.repository.name) {
            task.enabled = false
            task.group = null
        }
    }
}
Heartfelt answered 28/4, 2014 at 20:38 Comment(1)
Knut, your answer seem good but for some reason it wasn't working for me anymore, i've added a new post with my solution if you can take a look at.Whitton
S
5

Probably this didn't exist when the question was asked, but the Gradle documentation describes just how to achieve the desired conditional publishing.

Using method tasks.withType() as in the accepted answer, but then using an onlyIf{} block as well.

"Gradle allows you to skip any task you want based on a condition via the Task.onlyIf(org.gradle.api.specs.Spec) method."

So their example uses conditions on the repository name and publication type:

tasks.withType(PublishToMavenRepository) {
    onlyIf {
        (repository == publishing.repositories.external &&
            publication == publishing.publications.binary) ||
        (repository == publishing.repositories.internal &&
            publication == publishing.publications.binaryAndSources)
    }
}
tasks.withType(PublishToMavenLocal) {
    onlyIf {
        publication == publishing.publications.binaryAndSources
    }
}

Where they have defined publications and repositories as follows:

publishing {
    publications {
        binary(MavenPublication) {
            from components.java
        }
        binaryAndSources(MavenPublication) {
            from components.java
            artifact sourcesJar
        }
    }
    repositories {
        // change URLs to point to your repos, e.g. http://my.org/repo
        maven {
            name = 'external'
            url = "$buildDir/repos/external"
        }
        maven {
            name = 'internal'
            url = "$buildDir/repos/internal"
        }
    }
}
Sciamachy answered 20/1, 2019 at 20:3 Comment(0)
W
4

I've just started playing with gradle and it's other plugins and @knut-saua-mathiesen solution was really interresting, however it wasn't working for me.

Inside the 'AfterEvaluate' the task.publication wasn't set to it's correcte value but initialized to 'null'. So i tried a few other things and came up with this solution :

afterEvaluate {                                                                                   
  tasks.withType(PublishToMavenRepository).all { publishTask ->                                   
    publishTask.onlyIf { task ->                                                                  
      if (task.publication.hasProperty('repo') && task.publication.repo != task.repository.name) {
        task.enabled = false                                                                      
        task.group = null                                                                         
        return false                                                                              
      }                                                                                           
      return true                                                                                 
    }                                                                                             
  }                                                                                               
}   
Whitton answered 8/12, 2014 at 17:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.