// Copyright 2017 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

[[publishing_ivy]]
= Ivy Publish Plugin

The Ivy Publish Plugin provides the ability to publish build artifacts in the http://ant.apache.org/ivy/[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 <<declaring_dependencies.adoc#declaring_dependencies,Declaring Dependencies>>) and other tools that understand the Ivy format. You can learn about the fundamentals of publishing in <<publishing_overview.adoc#publishing_overview,Publishing Overview>>.

[[publishing_ivy:usage]]
== Usage

To use the Ivy Publish Plugin, include the following in your build script:

.Applying the Ivy Publish Plugin
====
include::sample[dir="ivy-publish/quickstart/groovy",files="build.gradle[tags=use-plugin]"]
include::sample[dir="ivy-publish/quickstart/kotlin",files="build.gradle.kts[tags=use-plugin]"]
====

The Ivy Publish Plugin uses an extension on the project named `publishing` of type link:{groovyDslPath}/org.gradle.api.publish.PublishingExtension.html[PublishingExtension]. This extension provides a container of named publications and a container of named repositories. The Ivy Publish Plugin works with link:{groovyDslPath}/org.gradle.api.publish.ivy.IvyPublication.html[IvyPublication] publications and link:{groovyDslPath}/org.gradle.api.artifacts.repositories.IvyArtifactRepository.html[IvyArtifactRepository] repositories.

[[publishing_ivy:tasks]]
== Tasks

[[publishing_ivy:descriptor]]
`generateDescriptorFileFor__PubName__Publication` — link:{groovyDslPath}/org.gradle.api.publish.ivy.tasks.GenerateIvyDescriptor.html[GenerateIvyDescriptor]::
Creates an Ivy descriptor file for the publication named _PubName_, populating the known metadata such as project name, project version, and the dependencies. The default location for the descriptor file is _build/publications/$pubName/ivy.xml_.

`publish__PubName__PublicationTo__RepoName__Repository` — link:{groovyDslPath}/org.gradle.api.publish.ivy.tasks.PublishToIvyRepository.html[PublishToIvyRepository]::
Publishes the _PubName_ publication to the repository named _RepoName_. If you have a repository definition without an explicit name, _RepoName_ will be "Ivy".

`publish`::
_Depends on_: All `publish__PubName__PublicationTo__RepoName__Repository` tasks
+
An aggregate task that publishes all defined publications to all defined repositories.

[[publishing_ivy:publications]]
== Publications

This plugin provides <<publishing_overview.adoc#glossary:publication,publications>> of type link:{groovyDslPath}/org.gradle.api.publish.ivy.IvyPublication.html[IvyPublication]. To learn how to define and use publications, see the section on <<publishing_overview.adoc#sec:basic_publishing,basic publishing>>.

There are four main things you can configure in an Ivy publication:

 * A <<publishing_overview.adoc#glossary:component,component>> — via link:{groovyDslPath}/org.gradle.api.publish.ivy.IvyPublication.html#org.gradle.api.publish.ivy.IvyPublication:from(org.gradle.api.component.SoftwareComponent)[IvyPublication.from(org.gradle.api.component.SoftwareComponent)].
 * <<publishing_overview.adoc#sec:publishing_custom_artifacts_to_maven,Custom artifacts>> — via the link:{groovyDslPath}/org.gradle.api.publish.ivy.IvyPublication.html#org.gradle.api.publish.ivy.IvyPublication:artifact(java.lang.Object)[IvyPublication.artifact(java.lang.Object)] method. See link:{groovyDslPath}/org.gradle.api.publish.ivy.IvyArtifact.html[IvyArtifact] for the available configuration options for custom Ivy artifacts.
 * Standard metadata like `module`, `organisation` and `revision`.
 * Other contents of the module descriptor — via link:{groovyDslPath}/org.gradle.api.publish.ivy.IvyPublication.html#org.gradle.api.publish.ivy.IvyPublication:descriptor(org.gradle.api.Action)[IvyPublication.descriptor(org.gradle.api.Action)].

You can see all of these in action in the <<#publishing_ivy:example,complete publishing example>>. The API documentation for `IvyPublication` has additional code samples.

[[sec:identity_values_for_the_published_project]]
=== Identity values for the published project

The generated Ivy module descriptor file contains an `&lt;info&gt;` element that identifies the module. The default identity values are derived from the following:

* `organisation` - link:{groovyDslPath}/org.gradle.api.Project.html#org.gradle.api.Project:group[Project.getGroup()]
* `module` - link:{groovyDslPath}/org.gradle.api.Project.html#org.gradle.api.Project:name[Project.getName()]
* `revision` - link:{groovyDslPath}/org.gradle.api.Project.html#org.gradle.api.Project:version[Project.getVersion()]
* `status` - link:{groovyDslPath}/org.gradle.api.Project.html#org.gradle.api.Project:status[Project.getStatus()]
* `branch` - (not set)

Overriding the default identity values is easy: simply specify the `organisation`, `module` or `revision` properties when configuring the link:{groovyDslPath}/org.gradle.api.publish.ivy.IvyPublication.html[IvyPublication]. `status` and `branch` can be set via the `descriptor` property — see link:{groovyDslPath}/org.gradle.api.publish.ivy.IvyModuleDescriptorSpec.html[IvyModuleDescriptorSpec].

The `descriptor` property can also be used to add additional custom elements as children of the `&lt;info&gt;` element, like so:

.customizing the publication identity
====
include::sample[dir="ivy-publish/customize-identity/groovy",files="build.gradle[tags=customize-identity]"]
include::sample[dir="ivy-publish/customize-identity/kotlin",files="build.gradle.kts[tags=customize-identity]"]
====

[TIP]
====
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 the artifact's `name`, `extension` and `classifier`). The only values that are explicitly prohibited are `\`, `/` and any ISO control character. The supplied values are validated early during publication.

[[sec:modifying_the_generated_module_descriptor]]
=== Customizing 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 DSL for that purpose. Please see link:{groovyDslPath}/org.gradle.api.publish.ivy.IvyModuleDescriptorSpec.html[IvyModuleDescriptorSpec] in the DSL Reference for the complete documentation of available properties and methods.

The following sample shows how to use the most common aspects of the DSL:

.Customizing the module descriptor file
====
include::sample[dir="ivy-publish/descriptor-customization/groovy",files="build.gradle[tags=customize-descriptor]"]
include::sample[dir="ivy-publish/descriptor-customization/kotlin",files="build.gradle.kts[tags=customize-descriptor]"]
====

In this example we are simply adding a 'description' element to the generated Ivy dependency descriptor, but 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.

You can also add arbitrary XML to the descriptor file via link:{groovyDslPath}/org.gradle.api.publish.ivy.IvyModuleDescriptorSpec.html#org.gradle.api.publish.ivy.IvyModuleDescriptorSpec:withXml(org.gradle.api.Action)[IvyModuleDescriptorSpec.withXml(org.gradle.api.Action)], but you can not use it to modify any part of the module identifier (organisation, module, revision).

CAUTION: It is 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.

[[publishing_ivy:resolved_dependencies]]
=== Customizing dependencies versions

By default, the set of dependencies and constraints that are added to the Ivy file will contain the versions _declared_ in the build file.
Sometimes it is desirable to publish the _resolved_ version instead.

Example use cases:

* A project uses dynamic versions for dependencies but prefers exposing the resolved version for a given release to its consumers.
* In combination with <<dependency_locking.adoc,dependency locking>>, you want to publish the locked versions.
* A project leverages the rich versions constraints of Gradle, which have a lossy conversion to Ivy.
Instead of relying on the conversion, it publishes the resolved versions.

This is done by using the `versionMapping` DSL method which allows to configure the link:{javadocPath}/org/gradle/api/publish/VersionMappingStrategy.html[VersionMappingStrategy]:

.Using resolved versions
====
include::sample[dir="ivy-publish/descriptor-customization/groovy",files="build.gradle[tags=versions-resolved]"]
include::sample[dir="ivy-publish/descriptor-customization/kotlin",files="build.gradle.kts[tags=versions-resolved]"]
====

In the example above, Gradle will use the versions resolved on the `runtimeClasspath` for dependencies declared in `api`, which are mapped to the `compile` configuration of Ivy.
Gradle will also use the versions resolved on the `runtimeClasspath` for dependencies declared in `implementation`, which are mapped to the `runtime` configuration of Ivy.
`fromResolutionResult()` indicates that Gradle should use the default classpath of a variant and `runtimeClasspath` is the default classpath of `java-runtime`.

[[publishing_ivy:repositories]]
== Repositories

This plugin provides <<dependency_management_terminology.adoc#sub:terminology_repository,repositories>> of type link:{groovyDslPath}/org.gradle.api.artifacts.repositories.IvyArtifactRepository.html[IvyArtifactRepository]. To learn how to define and use repositories for publishing, see the section on <<publishing_overview.adoc#sec:basic_publishing,basic publishing>>.

Here's a simple example of defining a publishing repository:

.Declaring repositories to publish to
====
include::sample[dir="ivy-publish/quickstart/groovy",files="build.gradle[tags=repositories]"]
include::sample[dir="ivy-publish/quickstart/kotlin",files="build.gradle.kts[tags=repositories]"]
====

The two main things you will want to configure are the repository's:

 * URL (required)
 * Name (optional)

You can define multiple repositories as long as they have unique names within the build script. You may also declare one (and only one) repository without a name. That repository will take on an implicit name of "Ivy".

You can also configure any authentication details that are required to connect to the repository. See link:{groovyDslPath}/org.gradle.api.artifacts.repositories.IvyArtifactRepository.html[IvyArtifactRepository] for more details.


[[publishing_ivy:example]]
== 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.

.Publishing a Java module
====
include::sample[dir="ivy-publish/java-multi-project/groovy",files="build.gradle[tags=all]"]
include::sample[dir="ivy-publish/java-multi-project/kotlin",files="build.gradle.kts[tags=all]"]
====

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:

=== Example: Generated ivy.xml

[source,xml]
.output-ivy.xml
----
include::{samplesPath}/ivy-publish/java-multi-project/output-ivy.xml[]
----

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

