Chapter 58. Ivy Publishing (new)

This chapter describes the new incubating Ivy publishing support introduced in Gradle 1.3. If you are looking for documentation on the “traditional” Ivy publishing support please see Chapter 45, Publishing artifacts.

This chapter describes how to publish build artifacts in the Apache Ivy format, usually to a repository for consumption by other builds or projects. What is published is one or more artifacts created by the build, and an Ivy module descriptor that describes the artifacts and the dependencies of the artifacts, if any.

A published Ivy module can be consumed by Gradle (see Chapter 44, Dependency Management) and other tools that understand the Ivy format.

58.2. The “ivy-publish” Plugin

The ability to publish in the Ivy format is provided by the “ivy-publish” plugin.

Example 58.1. Applying the “ivy-publish” plugin

build.gradle

apply plugin: 'ivy-publish'

This plugin does the following:

The “publishing” plugin creates an extension on the project named “publishing” of type PublishingExtension. This extension provides a container of named publications and a container of named repositories. The “ivy-publish” works with IvyPublication publications and IvyArtifactRepository repositories.

58.3. Publications

If you are not familiar with project artifacts and configurations, you should read the Chapter 45, Publishing artifacts that introduces these concepts. This chapter also describes “publishing artifacts” using a different mechanism than what is described in this chapter. The publishing functionality described here will eventually supersede that functionality.

Publication objects describe the structure/configuration of a publication to be created. Publications are published to repositories via tasks, and the configuration of the publication object determines exactly what is published. All of the publications of a project are defined in the PublishingExtension.getPublications() container. Each publication has a unique name within the project.

At this time, it is not possible to create arbitrary publication objects. When the “ivy-publish” plugin is applied it creates a single publication named “ivy”. This publication will publish all of artifacts of all of the project's visible configurations, and any configurations that they extend from.

Example 58.2. A build to publish

build.gradle

apply plugin: 'java'
apply plugin: 'ivy-publish'

version = '1.0'
group = 'org.gradle.test'

dependencies {
   compile 'junit:junit:4.8.2', project(':subproject')
}

repositories {
    mavenCentral()
}

task sourceJar(type: Jar) {
    baseName = 'ivypublishSource'
    from sourceSets.main.java
    classifier = 'src'
}

artifacts {
    archives sourceJar
}

publishing {
    publications {
        ivy {
            descriptor {
                withXml {
                    asNode().dependencies.dependency.find { it.@org == "junit" }.@rev = "4.10"
                }
            }
        }
    }
}

The “publishing.publications.ivy” publication that was added to the “publishing.publications” container of the project will be configured to publish two artifacts:

  • The primary “jar” artifact automatically created by the “java” plugin (see Chapter 23, The Java Plugin)
  • The source “jar” artifact that has been explicitly configured in this build

When this publication is published, the module descriptor (i.e. the ivy.xml file) that is produced will look like…

Note that the «PUBLICATION-TIME-STAMP» in this example Ivy module descriptor will be the timestamp of when the descriptor was generated.

Example 58.3. Example generated ivy.xml

output-ivy.xml

<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0">
  <info organisation="org.gradle.test" module="ivypublish" revision="1.0" status="integration" publication="«PUBLICATION-TIME-STAMP»"/>
  <configurations>
    <conf name="archives" visibility="public" description="Configuration for archive artifacts."/>
    <conf name="compile" visibility="private" description="Classpath for compiling the main sources."/>
    <conf name="default" visibility="public" description="Configuration for default artifacts." extends="runtime"/>
    <conf name="runtime" visibility="private" description="Classpath for running the compiled main classes." extends="compile"/>
    <conf name="testCompile" visibility="private" description="Classpath for compiling the test sources." extends="compile"/>
    <conf name="testRuntime" visibility="private" description="Classpath for running the compiled test classes." extends="runtime,testCompile"/>
  </configurations>
  <publications>
    <artifact name="ivypublish" type="jar" ext="jar" conf="archives,runtime"/>
    <artifact name="ivypublishSource" type="jar" ext="jar" conf="archives" m:classifier="src" xmlns:m="http://ant.apache.org/ivy/maven"/>
  </publications>
  <dependencies>
    <dependency org="junit" name="junit" rev="4.10" conf="compile-&gt;default"/>
    <dependency org="ivypublish" name="subproject" rev="unspecified" conf="compile-&gt;default"/>
  </dependencies>
</ivy-module>

The attributes of the <info> tag identify the module. These values are derived from the following project properties:

Note that you can set the value of these project properties in your build script, with the exception of name.

58.3.1. Modifying the published module descriptor

Notice that the junit dependency that appears in the descriptor above is different to what was actually used in the project. This is because of the descriptor modification that was declared.

Example 58.4. Modifying the Ivy descriptor

build.gradle

publishing {
    publications {
        ivy {
            descriptor {
                withXml {
                    asNode().dependencies.dependency.find { it.@org == "junit" }.@rev = "4.10"
                }
            }
        }
    }
}

It is possible to modify any aspect of the created descriptor should you need to. This means that it is also possible to modify the descriptor in such a way that it is no longer a valid Ivy module descriptor, so care must be taken when using this feature.

See IvyModuleDescriptor.withXml() for the relevant API reference documentation on descriptor modification.

58.4. Repositories

Publications are published to repositories. The repositories to publish to are defined by the PublishingExtension.getRepositories() container.

Example 58.5. Declaring repositories to publish to

build.gradle

publishing {
    repositories {
        ivy {
            url "http://mycompany.com/repo" // change to point to your repo
            credentials {
                username "user1"
                password "secret"
            }
        }
    }
}

The DSL used to declare repositories to publish to is the same DSL that is used to declare repositories to consume dependencies from, RepositoryHandler. However, in the context of Ivy publication only the repositories created by the ivy() methods can be used as publication destinations. You cannot publish an IvyPublication to a Maven repository for example.

58.5. Performing a publish

The “ivy-publish” plugin automatically creates a PublishToIvyRepository task for each IvyPublication and IvyArtifactRepository combination in the publishing.publications and publishing.repositories containers respectively.

In the example we have been working with so far, given that the publication that the “ivy-publish” plugin creates is named “ivy” and that the default name for repositories created using the ivy() methods of the publishing.repositories container is also “ivy”, a publish task will be created with the name “publishIvyPublicationToIvyRepository”. The naming pattern is “publish«NAME OF PUBLICATION»PublicationTo«NAME OF REPOSITORY»Repository”.

Executing this task will build all of the artifacts to be published, and transfer them to the repository.

Output of gradle publishIvyPublicationToIvyRepository

:subproject:compileJava
:subproject:processResources UP-TO-DATE
:subproject:classes
:subproject:jar
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:sourceJar
:publishIvyPublicationToIvyRepository

BUILD SUCCESSFUL

Total time: 1 sec

58.5.1. The “publish” lifecycle task

The “publish” plugin (that the “ivy-publish” plugin implicitly applies) adds a lifecycle task that can be used to publish all publications to all applicable repositories named “publish”.

In more concrete terms, executing this task will execute all PublishToIvyRepository tasks in the project. This is usually the most convenient way to perform a publish.

Output of gradle publish

:subproject:compileJava
:subproject:processResources UP-TO-DATE
:subproject:classes
:subproject:jar
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:sourceJar
:publishIvyPublicationToIvyRepository
:publish

BUILD SUCCESSFUL

Total time: 1 sec

58.6. Future features

The “ivy-publish” functionality as described above is incomplete, as the feature is still incubating. Over the coming Gradle releases, the functionality will be expanded to include (but not limited to):

  • Convenient customisation of module attributes (module, organisation etc.)
  • Fine grained control of which artifacts are published
  • Multiple discreet publications per project