0

I have a build.gradle file with an artifact I am publishing, following the guidelines given in the Ivy publishing documentation.

publishing {
    publications {
        ivy(IvyPublication) {
            from components.java
            descriptor.withXml {
                asNode().info[0].appendNode("description", description)
            }
        }
    }
}

I have a separate PublishToIvyRepository task, which I would like to configure so that it goes to a different repository that normal, but uses the same publication as the above code. My initial attempt is this:

task publishToIvyLocal(type: PublishToIvyRepository) {
    repository = mySpecialRepository
    publication = project.publishing.publications[0]
}

However, this doesn't seem to work. If I put it before the publishing {} block above, I get the following error:

Cannot configure the 'publishing' extension after it has been accessed.

I'm guessing that project.publishing.publications[0] isn't the best way to reuse this publication.

How can I reuse an IvyPublication in a custom PublishToIvyRepository task?

Thunderforge
  • 19,637
  • 18
  • 83
  • 130

2 Answers2

2

There is no need to create a PublishToIvyRepository task on your own.

Applying the 'ivy-publish' plugin does the following:

  • [...]
  • Establishes a rule to automatically create a PublishToIvyRepository task for the combination of each IvyPublication added (see Section 35.2, “Publications”), with each IvyArtifactRepository added (see Section 35.3, “Repositories”).

So, simply add your publication with your two repositories and two tasks will be created, one to publish the publication for each repository.

The created task is named publish«PUBNAME»PublicationTo«REPONAME»Repository, which is publishIvyJavaPublicationToIvyRepository for this example.

Some example code:

publishing {
    publications {
        mySpecial(IvyPublication) {
            // configure publication
        }
    }
    repositories {
        ivy {
            name = 'first'
            // configure first repository
        }
        ivy {
            name = 'second'
            // configure second repository
        }
    }
}

This should create the following tasks:

  • publishMySpecialPublicationToFirstRepository
  • publishMySpecialPublicationToSecondRepository

Regarding the repository name:

The name for this repository. A name must be unique amongst a repository set. A default name is provided for the repository if none is provided.

Community
  • 1
  • 1
Lukas Körfer
  • 13,515
  • 7
  • 46
  • 62
  • I had no idea it was even possible. I wish the official documentation did a better job of explaining it. – Thunderforge Jan 23 '18 at 21:07
  • Is there something special you have to do to generate the `publishMySpecialPublicationToFirstRepository` task? It isn't showing up in `gradlew tasks`, but does show up when I have Gradle [print out the connected repositories](https://stackoverflow.com/a/32143438/531762). – Thunderforge Jan 23 '18 at 21:10
  • Did you specify the repository in the project repository handler (`repositories { ... }`) or in the publishing repository handler (`publishing.repositories { ... }`)? – Lukas Körfer Jan 23 '18 at 21:23
  • Ah, that's the problem. I had it in `repositories { ... }`. Now it shows up correctly. – Thunderforge Jan 23 '18 at 21:35
1

Given your code sample I agree with lu.koerfer's answer but in case if you really need a custom publication task you can use project.afterEvaluate to access the publishing container after it has been configured:

project.afterEvaluate
{
    customPublicationTask.publication = project.publishing.publications["ivy"]
    // a publication can be accessed by its name
}
Igor Melnichenko
  • 134
  • 2
  • 13