# Chapter 64. Ivy Publishing (new)

This chapter describes the new incubating Ivy publishing support provided by the “`ivy-publish`” plugin. Eventually this new publishing support will replace publishing via the `Upload` task.

If you are looking for documentation on the original Ivy publishing support using the `Upload` task please see Chapter 51, 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 (normally `ivy.xml`) that describes the artifacts and the dependencies of the artifacts, if any.

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

## 64.1. The “`ivy-publish`” Plugin

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

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`” plugin works with `IvyPublication` publications and `IvyArtifactRepository` repositories.

Example 64.1. Applying the “ivy-publish” plugin

`build.gradle`

    apply plugin: 'ivy-publish'

Applying the “`ivy-publish`” plugin does the following:

- Applies the “`publishing`” plugin
- Establishes a rule to automatically create a `GenerateIvyDescriptor` task for each `IvyPublication` added (see Section 64.2, “Publications”).
- Establishes a rule to automatically create a `PublishToIvyRepository` task for the combination of each `IvyPublication` added (see Section 64.2, “Publications”), with each `IvyArtifactRepository` added (see Section 64.3, “Repositories”).

## 64.2. Publications

If you are not familiar with project artifacts and configurations, you should read the Chapter 51, 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.

For the “`ivy-publish`” plugin to have any effect, a `IvyPublication` must be added to the set of publications. This publication determines which artifacts are actually published as well as the details included in the associated Ivy module descriptor file. A publication can be configured by adding components, customizing artifacts, and by modifying the generated module descriptor file directly.

### 64.2.1. Publishing a Software Component

The simplest way to publish a Gradle project to an Ivy repository is to specify a `SoftwareComponent` to publish. The components presently available for publication are:

Table 64.1. Software Components

Name | Provided By | Artifacts | Dependencies
`java` | Java Plugin | Generated jar file | Dependencies from 'runtime' configuration
`web` | War Plugin | Generated war file | No dependencies

In the following example, artifacts and runtime dependencies are taken from the `java` component, which is added by the `Java Plugin`.

Example 64.2. Publishing a java module to Ivy

`build.gradle`

    publications {
            ivyJava(IvyPublication) {
                from components.java
            }
        }

### 64.2.2. Publishing custom artifacts

It is also possible to explicitly configure artifacts to be included in the publication. Artifacts are commonly supplied as raw files, or as instances of `AbstractArchiveTask` (e.g. Jar, Zip).

For each custom artifact, it is possible to specify the `name`, `extension`, `type`, `classifier` and `conf` values to use for publication. Note that each artifacts must have a unique name/classifier/extension combination.

Configure custom artifacts as follows:

Example 64.3. Publishing additional artifact to Ivy

`build.gradle`

    task sourceJar(type: Jar) {
            from sourceSets.main.java
            classifier "source"
        }
        publishing {
            publications {
                ivy(IvyPublication) {
                    from components.java
                    artifact(sourceJar) {
                        type "source"
                        conf "runtime"
                    }
                }
            }
        }

See `IvyPublication` for more detailed documentation on how artifacts can be customized.

### 64.2.3. Identity values for the published project

The generated Ivy module descriptor file contains an `<info>` tag that identifies the module. The default identity values are derived from the following project properties:

- `organisation` - `Project.getGroup()`
- `module` - `Project.getName()`
- `revision` - `Project.getVersion()`
- `status` - `Project.getStatus()`

Overriding the default identity values is easy: simply specify the `organisation`, `module` or `revision` attributes when configuring the `IvyPublication`.

Example 64.4. customizing the publication identity

`build.gradle`

    publishing {
            publications {
                ivy(IvyPublication) {
                    organisation 'org.gradle.sample'
                    module 'project1-sample'
                    revision '1.1'
                    descriptor.status = 'milestone'

                    from components.java
                }
            }
        }

Certain repositories are not able to handle all supported characters. For example, the ':' character cannot be used as an identifier when publishing to a filesystem-backed repository on Windows.

Gradle will handle any valid Unicode character for organisation, module and revision (as well as artifact name, extension and classifier). The only values that are explicitly prohibited are '`\`', '`/`' and any ISO control character. The supplied values are validated early in publication.

### 64.2.4. Modifying the generated module descriptor

At times, the module descriptor file generated from the project information will need to be tweaked before publishing. The “`ivy-publish`” plugin provides a hook to allow such modification.

Example 64.5. Customizing the module descriptor file

`build.gradle`

    publications {
            ivyCustom(IvyPublication) {
                descriptor.withXml {
                    asNode().info[0].appendNode('description', 'A demonstration of ivy descriptor customization')
                }
            }
        }

In this example we are adding a 'description' element to the generated Ivy dependency descriptor, but this this hook, allows you to modify any aspect of the generated descriptor. For example, you could replace the version range for a dependency with the actual version used to produce the build.

See `IvyModuleDescriptor.withXml()` for the relevant API reference documentation.

It is possible to modify virtually 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.

The identifier (organisation, module, revision) of the published module is an exception; these values cannot be modified in the descriptor using the `withXML` hook.

### 64.2.5. Publishing multiple modules

Sometimes it's useful to publish multiple modules from your Gradle build, without creating a separate Gradle subproject. An example is publishing a separate API and implementation jar for your library. With Gradle this is simple:

Example 64.6. Publishing multiple modules from a single project

`build.gradle`

    task apiJar(type: Jar) {
            baseName "publishing-api"
            from sourceSets.main.output
            exclude '**/impl/**'
        }
        publishing {
            publications {
                impl(IvyPublication) {
                    organisation 'org.gradle.sample.impl'
                    module 'project2-impl'
                    revision '2.3'

                    from components.java
                }
                api(IvyPublication) {
                    organisation 'org.gradle.sample'
                    module 'project2-api'
                    revision '2'
                }
            }
        }

If a project defines multiple publications then Gradle will publish each of these to the defined repositories. Each publication must be given a unique identity as described above.

## 64.3. Repositories

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

Example 64.7. Declaring repositories to publish to

`build.gradle`

    repositories {
            ivy {
                url "$buildDir/repo" // change to point to your repo, e.g. http://my.org/repo
            }
        }

The DSL used to declare repositories for publishing is the same DSL that is used to declare repositories for dependencies (`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.

## 64.4. 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.

The created task is named using the pattern "`publish«NAME OF PUBLICATION»PublicationTo«NAME OF REPOSITORY»Repository`". So in this example a single `PublishToIvyRepository` task is be added, named '`publishIvyJavaPublicationToIvyRepository`'.

Example 64.8. Choosing a particular publication to publish

`build.gradle`

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

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

    publishing {
        publications {
            ivyJava(IvyPublication) {
                from components.java
            }
        }
        repositories {
            ivy {
                url "$buildDir/repo" // change to point to your repo, e.g. http://my.org/repo
            }
        }
    }

Output of `gradle publishIvyJavaPublicationToIvyRepository`

    > gradle publishIvyJavaPublicationToIvyRepository
    :generateDescriptorFileForIvyJavaPublication
    :compileJava UP-TO-DATE
    :processResources UP-TO-DATE
    :classes UP-TO-DATE
    :jar
    :publishIvyJavaPublicationToIvyRepository

    BUILD SUCCESSFUL

    Total time: 1 secs

### 64.4.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.

Example 64.9. Publishing all publications via the “publish” lifecycle task

Output of `gradle publish`

    > gradle publish
    :generateDescriptorFileForIvyJavaPublication
    :compileJava UP-TO-DATE
    :processResources UP-TO-DATE
    :classes UP-TO-DATE
    :jar
    :publishIvyJavaPublicationToIvyRepository
    :publish

    BUILD SUCCESSFUL

    Total time: 1 secs

## 64.5. Generating the Ivy module descriptor file without publishing

At times it is useful to generate the Ivy module descriptor file (normally `ivy.xml`) without publishing your module to an Ivy repository. Since descriptor file generation is performed by a separate task, this is very easy to do.

The “`ivy-publish`” plugin automatically wires in one `GenerateIvyDescriptor` task for each registered `IvyPublication`. This task is given a name based on the name of the publication: "`generateDescriptorFileFor«NAME OF PUBLICATION»Publication`". So in the above example where the publication is named "`ivyJava`", the task will be named "`generateDescriptorFileForIvyJavaPublication`".

You can specify where the generated Ivy file will be located by setting the `destination` property on the generate task. By default this file is generated to `build/publications/«NAME OF PUBLICATION»/ivy.xml`.

Example 64.10. Generating the Ivy module descriptor file

`build.gradle`

    model {
        tasks.generateDescriptorFileForIvyCustomPublication {
            destination = file("$buildDir/generated-ivy.xml")
        }
    }

Output of `gradle generateDescriptorFileForIvyCustomPublication`

    > gradle generateDescriptorFileForIvyCustomPublication
    :generateDescriptorFileForIvyCustomPublication

    BUILD SUCCESSFUL

    Total time: 1 secs

The “`ivy-publish`” plugin leverages some experimental support for late plugin configuration, and the `GenerateIvyDescriptor` task will not be constructed until the publishing extension is configured. The simplest way to ensure that the publishing plugin is configured when you attempt to access the `GenerateIvyDescriptor` task is to place the access inside a `publishing` block, as the above example demonstrates.

The same applies to any attempt to access publication-specific tasks like `PublishToIvyRepository`. These tasks should be referenced from within a `publishing` block.

## 64.6. Complete example

The following example demonstrates publishing with a multi-project build. Each project publishes a java component and a configured additional source artifact. The descriptor file is customized to include the project description for each project.

Example 64.11. Publishing a java module

`build.gradle`

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

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

        repositories {
            mavenCentral()
        }
        task sourceJar(type: Jar) {
            from sourceSets.main.java
            classifier "source"
        }
    }

    project(":project1") {
        description = "The first project"

        dependencies {
           compile 'junit:junit:4.11', project(':project2')
        }
    }

    project(":project2") {
        description = "The second project"

        dependencies {
           compile 'commons-collections:commons-collections:3.1'
        }
    }

    subprojects {
        publishing {
            repositories {
                ivy {
                    url "${rootProject.buildDir}/repo" // change to point to your repo, e.g. http://my.org/repo
                }
            }
            publications {
                ivy(IvyPublication) {
                    from components.java
                    artifact(sourceJar) {
                        type "source"
                        conf "runtime"
                    }
                    descriptor.withXml {
                        asNode().info[0].appendNode('description', description)
                    }
                }
            }
        }
    }

The result is that the following artifacts will be published for each project:

- The Ivy module descriptor file: `ivy-1.0.xml`.
- The primary “jar” artifact for the java component: `project1-1.0.jar`.
- The source “jar” artifact that has been explicitly configured:`project1-1.0-source.jar`.

When `project1` 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 64.12. Example generated ivy.xml

`output-ivy.xml`

    <?xml version="1.0" encoding="UTF-8"?>
    <ivy-module version="2.0">
      <info organisation="org.gradle.sample" module="project1" revision="1.0" status="integration" publication="«PUBLICATION-TIME-STAMP»">
        <description>The first project</description>
      </info>
      <configurations>
        <conf name="default" visibility="public" extends="runtime"/>
        <conf name="runtime" visibility="public"/>
      </configurations>
      <publications>
        <artifact name="project1" type="jar" ext="jar" conf="runtime"/>
        <artifact name="project1" type="source" ext="jar" conf="runtime" m:classifier="source" xmlns:m="http://ant.apache.org/ivy/maven"/>
      </publications>
      <dependencies>
        <dependency org="junit" name="junit" rev="4.11" conf="runtime-&gt;default"/>
        <dependency org="org.gradle.sample" name="project2" rev="1.0" conf="runtime-&gt;default"/>
      </dependencies>
    </ivy-module>

## 64.7. Future features

The “`ivy-publish`” plugin 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 customization of module attributes (`module`, `organisation` etc.)
- Convenient customization of dependencies reported in `module descriptor`.
- Multiple discreet publications per project