Gradle Maven Publish Plugin: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(93 intermediate revisions by the same user not shown)
Line 5: Line 5:
=Internal=
=Internal=


* [[Gradle Concepts#Gradle_Maven_Publish_Plugin|Gradle Concepts]]
* [[Gradle_Plugin_Concepts#External_Plugins|Gradle Plugin Concepts | External Plugins]]
* [[Gradle_Artifact_Publishing_Concepts#Publishing_to_a_Maven_Repository|Gradle Artifact Publishing Concepts]]
* [[Gradle_Artifact_Publishing_Concepts#Publishing_to_a_Maven_Repository|Gradle Artifact Publishing Concepts]]


=Overview=
=Overview=


"maven-publish" is an newer alternative to publishing with [[Gradle Maven Plugin#Overview|Maven Plugin]], using "publish" tasks instead of Maven Plugin  "[[Gradle_Maven_Plugin#Overview|Upload]]" tasks. The plugin generates Maven metadata and publishes the generated metadata and the associated artifacts to Maven repositories. The concepts behind publishing with "maven-publish", and the plugin mechanics, are described in the [[#Concepts_and_Plugin_Mechanics|Concepts and Plugin Mechanics]] below. A step by step procedure is available under the [[#Procedure|Procedure]] section.
"maven-publish" is an newer alternative to publishing with [[Gradle Maven Plugin#Overview|Maven Plugin]], using "publish" tasks instead of Maven Plugin  "[[Gradle_Maven_Plugin#Overview|Upload]]" tasks. The plugin generates Maven metadata and publishes the generated metadata and the associated artifacts to Maven repositories. "maven-publish" concepts and publishing mechanics are described in the [[#Concepts_and_Plugin_Mechanics|Concepts and Plugin Mechanics]] below. A step by step procedure is available under the [[#Procedure|Procedure]] section.


The plugin is activated with:
The plugin is activated with:
<syntaxhighlight lang='groovy'>
plugins {
    id 'maven-publish'
}
</syntaxhighlight>
or


<syntaxhighlight lang='groovy'>
<syntaxhighlight lang='groovy'>
Line 22: Line 31:
==Mechanics==
==Mechanics==


The plugin creates an [[Gradle_Concepts#Extension|extension]] of type [https://docs.gradle.org/current/dsl/org.gradle.api.publish.PublishingExtension.html PublishingExtension] named "publishing". The extension provides a [[Gradle_Concepts#Container|container]] of named [[#Publications|publications]] and a [[Gradle_Concepts#Container|container]] of named [[#Repositories|repositories]]. The plugin does not have effect if no Maven publication is added to the publications container. If publications and repositories are present, the plugin processes those configurations and based on their content, creates [[#POM_Generation_Tasks|POM generation tasks]] and [[#Publishing_Tasks|publishing tasks]] that can be used to carry out the publishing action.
The plugin creates an [[Gradle Extensions#Overview|extension]] of type [https://docs.gradle.org/current/dsl/org.gradle.api.publish.PublishingExtension.html PublishingExtension] named "publishing" and makes it available for configuration via the:
<syntaxhighlight lang='groovy'>
publishing {
  ...
}</syntaxhighlight> script block. The extension provides a [[Gradle_Project_and_Build_Script#Publications_Container|container]] of named "[[#Publications|publications]]", which can be configured with the:
<syntaxhighlight lang='groovy'>
publishing {
  publications {
    ...
  }
}</syntaxhighlight> "publications" script block, inside the "publishing" block, and a [[Gradle_Project_and_Build_Script#Publishing_Repository_Container|container]] of named [[#Repositories|repositories]], which can be configured with the: <syntaxhighlight lang='groovy'>
publishing {
  repositories {
    ...
  }
}</syntaxhighlight> "repositories" script block.  


==Publications==
The plugin does not have effect if no Maven publication is added to the "publications" container. If publications and repositories are present, the plugin processes those configurations and based on their content, creates [[#POM_Generation_Tasks|POM generation tasks]] and [[#Publishing_Tasks|publishing tasks]] that can be used to carry out the publishing action.


A Maven Publication is the representation of how Gradle publishes an artifact in Maven format. The Maven Publish plugin publications are defined by the [https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPublication.html MavenPublication] type. They are added to the <tt>publishing.publications</tt> as follows:
Repositories declared in the [[Gradle_Project_and_Build_Script#repositories.7B.7D|repositories{...}]] block of the project's build configuration script have nothing to do with artifact publishing, so they are not published to. Those repositories are only used to resolve dependencies against. The maven-publish plugin will not create a publishing task that involves any of the repositories declared in the build script repositories{...} block.
 
==<span id='Publications'></span>Publication==
 
{{External|https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPublication.html}}
 
A Maven Publication is the representation of how Gradle publishes an artifact in Maven format. Logically, a Maven publication represents a set of files and a POM that get published atomically under a well defined set of coordinates - groupId, artifactId and version. The maven-publish plugin publications are defined by the [https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPublication.html MavenPublication] type. They are added to the <tt>publishing.publications</tt> as follows:


<syntaxhighlight lang='groovy'>
<syntaxhighlight lang='groovy'>
Line 32: Line 62:
   publications {
   publications {
     <publication-name>(MavenPublication) {
     <publication-name>(MavenPublication) {
         from <component>
         from <software-component>
         artifact <task>
         artifact <artifact-generating-task>
         artifact(source, configuration)
         artifact(source, configuration)
         pom(configuration)
         pom(configuration)
Line 41: Line 71:
</syntaxhighlight>
</syntaxhighlight>


The above syntax shows that an artifact can be specified by indicating the [[Gradle_Concepts#Software_Component|software component]] that should be published, or by defining the artifact in-line. If the artifact (or artifacts) are specified in-line, their details can be configured. The generated POM can be configured in-line as well.
The above syntax shows that an artifact can be specified in two ways:
# By indicating the [[Gradle Software Components#Overview|software component]] that should be published. See [[#Software_Component_Publication|Software Component Publication]] below.
# By defining the artifact in-line. If the artifact (or artifacts) are specified in-line, their details can be configured. See [[#Custom_Artifact_Publication|Custom Artifact Publication]] below.
 
The generated POM can be configured in-line as well. See [[#POM_Customization|POM Customization]] below.


Each publication must have an unique name within the project. All the artifacts associated with a publication share the groupID/artifactID/version project coordinates. A publication has a POM and at least one artifact, but it can have several artifacts (or example the class JAR and the source JAR).
Each publication must have an unique name within the project. All the artifacts associated with a publication share the groupId, artifactId and version project coordinates. A publication has a POM and at least one artifact, but it can have several artifacts. A very common example of publications with multiple artifacts is a Java library that publishes the classes JAR and the sources JAR.


===Software Component Publication===
===Software Component Publication===
Line 59: Line 93:
===Custom Artifact Publication===
===Custom Artifact Publication===


Custom artifacts can be included. They can be raw files or archives (JAR, ZIP). For each custom artifact it is possible to specify [[Gradle_Concepts#Artifact_Extension|extension]] and [[Gradle_Concepts#classifier|classifier]] values to use for publications. Only one of the published artifact can have an empty classifier, all other must have unique classifier/extension combinations.
Custom artifacts can be included. They can be raw files or archives (JAR, ZIP). For each custom artifact it is possible to specify [[Gradle_Artifact_Publishing_Concepts#Extension|extension]] and [[Gradle_Artifact_Publishing_Concepts#Classifier|classifier]] values to use for publications. Only one of the published artifact can have an empty classifier, all other must have unique classifier/extension combinations. Note that the extension, classifier, and other attributes can be specified in the <tt>artifact{...}</tt> configuration closure, or in the task that creates the artifact. If specified in both places, the values specified in the <tt>artifact{...}</tt> closure will take precedence.


<syntaxhighlight lang='groovy'>
<syntaxhighlight lang='groovy'>
Line 68: Line 102:
publishing {
publishing {
   publications {
   publications {
       multiart(MavenPublication) {
       multipart(MavenPublication) {
         ...
         ...
         artifact srcJar {
         artifact srcJar {
Line 76: Line 110:
}
}
</syntaxhighlight>
</syntaxhighlight>
==Maven Project Coordinates==
The Maven project coordinates the publication will be generated with are inherited from the project, as follows:
* [[Gradle_Project_and_Build_Script#Project_Name.2C_artifactId|artifactId from Project.getName()]]
* [[Gradle_Project_and_Build_Script#Group.2C_groupId|groupId from Project.getGroup()]]
* [[Gradle_Project_and_Build_Script#Version|version from Project.getVersion()]]
However, they can be overridden in the publication definition, as follows:
<syntaxhighlight lang='groovy'>
publishing {
  publications {
      something(MavenPublication) {
        groupId 'blah'
        artifactId 'blah'
        version '1.11.111'
        ...
      }
}
</syntaxhighlight>
Maven restricts 'groupId' and 'artifactId' to a limited character set ( [A-Za-z0-9_\\-.]+ ) and Gradle enforces this restriction. For 'version' (as well as artifact 'extension' and 'classifier'), Gradle will handle any valid Unicode character. The only Unicode values that are explicitly prohibited are ‘ \ ’, ‘ / ’ and any ISO control character.
===POM Customization===
{{External|https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPom.html#org.gradle.api.publish.maven.MavenPom:withXml(org.gradle.api.Action)}}
Any aspect of the POM can be modified as shown below, with the exception of the project coordinates (groupId, artifactId, and version).
<syntaxhighlight lang='groovy'>
publishing {
  publications {
      something(MavenPublication) {
        ...
        pom.withXml {
                asNode().appendNode('description', 'Something that will be inserted as description')
        }
      }
}
</syntaxhighlight>
Also see [[#Published_Maven_Metadata|Published Maven Metadata]] below.


==Repositories==
==Repositories==


The Maven Publish plugin publications are defined by the [https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.repositories.MavenArtifactRepository.html  MavenArtifactRepository] type.
The maven-publish plugin repositories are defined inside a repositories {...} script block, and the Gradle component that is configured as such is a RepositoryHandler. It is the same logic that manages the top-level build script repositories, but the maven-plugin uses a different instance of that component. More details in: {{Internal|Gradle_Repositories#Repository_Handler|Repository Handler}}
 
Inside the repository handler, the Maven repositories to publish to are defined by the [https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.repositories.MavenArtifactRepository.html  MavenArtifactRepository] type:
 
<syntaxhighlight lang='groovy'>
publishing {
  ...
  repositories {
    //
    // repositories to publish to
    //
    maven {
      url '...'
      credentials {
        username '...'
        password '...'
      }
      authentication {
        basic(BasicAuthentication)
      }
    }
  }
}
</syntaxhighlight>
 
{{Warn|To publish to a specific repository, the repository must be defined in the repositories {...} script block declared inside the publishing {...} script block. Repositories declared in the [[Gradle_Project_and_Build_Script#repositories.7B.7D|repositories{...}]]  script block of the project's build configuration script serve as sources of dependencies and are not published to.}}
 
For details on repository declaration syntax see: {{Internal|Gradle_Repositories#Declaring_Repositories|Gradle Repositories}}


<font color=red>Relationship to pre-declared repositories, how can we use it?</font>
=Tasks=
The plugin adds the following tasks to the project, grouped under the "Publishing" task group:


==POM Generation Tasks==
[[#Publishing_Tasks|Publishing tasks]]:
* [[#The_.22publish.22_Task|<tt><b>publish</b></tt>]] - Publishes all publications produced by this project.
* <tt><b>publishAllPublicationsToMavenRepository</b></tt> - Publishes all Maven publications produced by this project to the maven repository. Mmore than one Maven repositories can be configured, and they will show up as Maven, Maven2, ....
* <tt><b>publishToMavenLocal</b></tt> - Publishes all Maven publications produced by this project to the local Maven cache.
* <tt><b>publish<''artifact-name''>PublicationToMavenRepository</b></tt> - Publishes Maven publication '<''artifact-name''>' to Maven repository 'maven'. More than one Maven repositories can be configured, and they will show up as Maven, Maven2, ....
* <tt><b>publish<''artifact-name''>PublicationToMavenLocal</b></tt> - Publishes Maven publication '<''artifact-name''>' to the local Maven repository.
[[#POM_Generation_Tasks|POM generation tasks]]:
* <tt><b>generateMetadataFileFor<''artifact-name''>Publication</b></tt> - Generates the Gradle metadata file for publication '<''artifact-name''>'.
* <tt><b>generatePomFileFor<''artifact-name''>Publication</b></tt> - Generates the Maven POM file for publication '<''artifact-name''>'.


==Publishing Tasks==
==Publishing Tasks==


The plugin creates publishing tasks, based on declared publications and repositories, for the combination of each publication and repository, and makes them available for use. All publishing tasks are triggered by the overarching "publish" tasks, which publishes all publications produced by the project.
The plugin creates publishing tasks, based on declared publications and repositories, for the combination of each publication and repository, and makes them available for use. '''All''' publishing tasks are triggered by default by the overarching [[#The_.22publish.22_Task|publish]] tasks, which publishes '''all''' publications produced by the project.
 
Under some circumstances, we may want to prevent some of the publishing tasks from being executed: we may want only some of the declared publications to be published only to some of the repositories. A pattern to achieve that is to guard the declaration of the repository or publication with a logical condition inferred from the presence of a boolean system property:
 
<syntaxhighlight lang='groovy'>
publishing {
 
    publications {
 
        if (Boolean.getBoolean('doPublishMyArtifact')) {
 
            myArtifact(MavenPublication) {
              ...
            }
        }
    }
 
    repositories {
 
      // ...
    }
}
</syntaxhighlight>
 
and then invoke Gradle with
 
  gradle ... -DdoPublishMyArtifact=true publish
 
The same technique works for "selective" repository declaration.
 
Other techniques, such as [[Gradle_Object_Instance#StartParameter|detecting the presence of a specific task on command line]], etc. can be applied.
 
==The "publish" Task==
 
The plugin also adds a "publish" task that publishes all publications produced by this project, which probably means executing all generated [[#Publishing_Tasks|publishing tasks]].
==POM Generation Tasks==
See [[#Published_Maven_Metadata|Published Maven Metadata]] below.


=<span id='Publishing_to_a_Maven_Repository'></span>Procedure=
=<span id='Publishing_to_a_Maven_Repository'></span>Procedure=
Line 109: Line 259:
</syntaxhighlight>
</syntaxhighlight>


Declared the target repositories. The example below assumes we want to publish locally into the [[Gradle_Concepts#Local_Maven_repository|local Maven repository]], and also into a remote Maven repository:
The simplest possible configuration for a Java project, that publishes a binary JAR, is:
 
<syntaxhighlight lang='groovy'>
publishing {
  publications {
    main(MavenPublication) {
      from components.java
    }
  }
}
</syntaxhighlight>
 
Declared the target repositories. The example below assumes we want to publish locally into the [[Gradle_Repositories#Local_Maven_Repository|local Maven repository]]. Note that the target repository must be declared in the repositories{...} script block of the publishing {...} script block. From more details see [[#Repositories|Repositories]] section above.
 
<syntaxhighlight lang='groovy'>
publishing {
 
    //
    // ...
    //
 
    repositories {
        mavenLocal()
    }
}
</syntaxhighlight>


<syntaxhighlight lang='groovy'>
<syntaxhighlight lang='groovy'>
Line 121: Line 296:
}
}
</syntaxhighlight>
</syntaxhighlight>
Make sure the project coordinates are specified somewhere. For more details see [[#Maven_Project_Coordinates|Maven Project Coordinates]] above.


Publish:
Publish:


  gradle publish
  gradle publish
=Published Maven Metadata=
The plugin generates and publishes the following Maven metadata file:
* In the artifact's directory (~/.m2/repository/playground/a/a for a groupId='playground.a' and an artifactId='a'), a maven-metadata.xml file with the following content, and the associated md5 and sha1 files:
<syntaxhighlight lang='xml'>
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>playground.a</groupId>
  <artifactId>a</artifactId>
  <versioning>
    <release>1.0</release>
    <versions>
      <version>1.0</version>
    </versions>
    <lastUpdated>20190504000056</lastUpdated>
  </versioning>
</metadata>
</syntaxhighlight>
* In the version directory (~/.m2/repository/playground/a/a/1.0 for a groupId='playground.a', an artifactId='a' and version='1.0'), an a-1.0.pom with the following content, and the assoicated md5 and sha1 files:
<syntaxhighlight lang='xml'>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>playground.a</groupId>
  <artifactId>a</artifactId>
  <version>1.0</version>
</project>
</syntaxhighlight>
If the module being published depends on other module, the dependencies reflect in POM. In the example below, "playground.b:b:1.0" is declared as dependent on "playground.a:a:1.0":
<syntaxhighlight lang='groovy'>
dependencies {
    implementation 'playground.a:a:1.0'
}
</syntaxhighlight>
The corresponding generated POM is:
<syntaxhighlight lang='xml'>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>playground.b</groupId>
  <artifactId>b</artifactId>
  <version>1.0</version>
  <dependencies>
    <dependency>
      <groupId>playground.a</groupId>
      <artifactId>a</artifactId>
      <version>1.0</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</project>
</syntaxhighlight>
Note that "implementation" translates to a "runtime" Maven scope.
Also see [[#POM_Customization|POM Customization]] and [[#POM_Generation_Tasks|POM Generation Tasks]] above.


=Examples=
=Examples=


{{External|https://github.com/NovaOrdis/playground/tree/master/gradle/java-publishing}}
{{External|https://github.com/NovaOrdis/playground/tree/master/gradle/java-publishing}}
{{External|https://github.com/NovaOrdis/playground/tree/master/gradle/java-publishing-multiprojects-multipubs}}

Latest revision as of 21:44, 23 April 2021

External

Internal

Overview

"maven-publish" is an newer alternative to publishing with Maven Plugin, using "publish" tasks instead of Maven Plugin "Upload" tasks. The plugin generates Maven metadata and publishes the generated metadata and the associated artifacts to Maven repositories. "maven-publish" concepts and publishing mechanics are described in the Concepts and Plugin Mechanics below. A step by step procedure is available under the Procedure section.

The plugin is activated with:

plugins {
    id 'maven-publish'
}

or

apply plugin: 'maven-publish'

Concepts and Plugin Mechanics

Mechanics

The plugin creates an extension of type PublishingExtension named "publishing" and makes it available for configuration via the:

publishing {
  ...
}

script block. The extension provides a container of named "publications", which can be configured with the:

publishing {
  publications {
    ...
  }
}

"publications" script block, inside the "publishing" block, and a container of named repositories, which can be configured with the:

publishing {
  repositories {
    ...
  }
}

"repositories" script block.

The plugin does not have effect if no Maven publication is added to the "publications" container. If publications and repositories are present, the plugin processes those configurations and based on their content, creates POM generation tasks and publishing tasks that can be used to carry out the publishing action.

Repositories declared in the repositories{...} block of the project's build configuration script have nothing to do with artifact publishing, so they are not published to. Those repositories are only used to resolve dependencies against. The maven-publish plugin will not create a publishing task that involves any of the repositories declared in the build script repositories{...} block.

Publication

https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPublication.html

A Maven Publication is the representation of how Gradle publishes an artifact in Maven format. Logically, a Maven publication represents a set of files and a POM that get published atomically under a well defined set of coordinates - groupId, artifactId and version. The maven-publish plugin publications are defined by the MavenPublication type. They are added to the publishing.publications as follows:

publishing {
  publications {
    <publication-name>(MavenPublication) {
        from <software-component>
        artifact <artifact-generating-task>
        artifact(source, configuration)
        pom(configuration)
    }
  }
}

The above syntax shows that an artifact can be specified in two ways:

  1. By indicating the software component that should be published. See Software Component Publication below.
  2. By defining the artifact in-line. If the artifact (or artifacts) are specified in-line, their details can be configured. See Custom Artifact Publication below.

The generated POM can be configured in-line as well. See POM Customization below.

Each publication must have an unique name within the project. All the artifacts associated with a publication share the groupId, artifactId and version project coordinates. A publication has a POM and at least one artifact, but it can have several artifacts. A very common example of publications with multiple artifacts is a Java library that publishes the classes JAR and the sources JAR.

Software Component Publication

publishing {
  publications {
    javacomp(MavenPublication) {
        from components.java
    }
  }
}

Custom Artifact Publication

Custom artifacts can be included. They can be raw files or archives (JAR, ZIP). For each custom artifact it is possible to specify extension and classifier values to use for publications. Only one of the published artifact can have an empty classifier, all other must have unique classifier/extension combinations. Note that the extension, classifier, and other attributes can be specified in the artifact{...} configuration closure, or in the task that creates the artifact. If specified in both places, the values specified in the artifact{...} closure will take precedence.

task srcJar(type: Jar) {
    from sourceSets.main.allJava
}

publishing {
  publications {
      multipart(MavenPublication) {
         ...
         artifact srcJar {
             classifier "sources"
         }
      }
}

Maven Project Coordinates

The Maven project coordinates the publication will be generated with are inherited from the project, as follows:

However, they can be overridden in the publication definition, as follows:

publishing {
  publications {
      something(MavenPublication) {
         groupId 'blah'
         artifactId 'blah'
         version '1.11.111'
         ...
      }
}

Maven restricts 'groupId' and 'artifactId' to a limited character set ( [A-Za-z0-9_\\-.]+ ) and Gradle enforces this restriction. For 'version' (as well as artifact 'extension' and 'classifier'), Gradle will handle any valid Unicode character. The only Unicode values that are explicitly prohibited are ‘ \ ’, ‘ / ’ and any ISO control character.

POM Customization

https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPom.html#org.gradle.api.publish.maven.MavenPom:withXml(org.gradle.api.Action)

Any aspect of the POM can be modified as shown below, with the exception of the project coordinates (groupId, artifactId, and version).

publishing {
  publications {
      something(MavenPublication) {
         ...
         pom.withXml {
                asNode().appendNode('description', 'Something that will be inserted as description')
         }
      }
}

Also see Published Maven Metadata below.

Repositories

The maven-publish plugin repositories are defined inside a repositories {...} script block, and the Gradle component that is configured as such is a RepositoryHandler. It is the same logic that manages the top-level build script repositories, but the maven-plugin uses a different instance of that component. More details in:

Repository Handler

Inside the repository handler, the Maven repositories to publish to are defined by the MavenArtifactRepository type:

publishing {
  ...
  repositories {
    //
    // repositories to publish to
    //
    maven {
      url '...'
      credentials {
        username '...'
        password '...'
      }
      authentication {
        basic(BasicAuthentication)
      }
    }
  }
}

To publish to a specific repository, the repository must be defined in the repositories {...} script block declared inside the publishing {...} script block. Repositories declared in the repositories{...} script block of the project's build configuration script serve as sources of dependencies and are not published to.

For details on repository declaration syntax see:

Gradle Repositories

Tasks

The plugin adds the following tasks to the project, grouped under the "Publishing" task group:

Publishing tasks:

  • publish - Publishes all publications produced by this project.
  • publishAllPublicationsToMavenRepository - Publishes all Maven publications produced by this project to the maven repository. Mmore than one Maven repositories can be configured, and they will show up as Maven, Maven2, ....
  • publishToMavenLocal - Publishes all Maven publications produced by this project to the local Maven cache.
  • publish<artifact-name>PublicationToMavenRepository - Publishes Maven publication '<artifact-name>' to Maven repository 'maven'. More than one Maven repositories can be configured, and they will show up as Maven, Maven2, ....
  • publish<artifact-name>PublicationToMavenLocal - Publishes Maven publication '<artifact-name>' to the local Maven repository.

POM generation tasks:

  • generateMetadataFileFor<artifact-name>Publication - Generates the Gradle metadata file for publication '<artifact-name>'.
  • generatePomFileFor<artifact-name>Publication - Generates the Maven POM file for publication '<artifact-name>'.

Publishing Tasks

The plugin creates publishing tasks, based on declared publications and repositories, for the combination of each publication and repository, and makes them available for use. All publishing tasks are triggered by default by the overarching publish tasks, which publishes all publications produced by the project.

Under some circumstances, we may want to prevent some of the publishing tasks from being executed: we may want only some of the declared publications to be published only to some of the repositories. A pattern to achieve that is to guard the declaration of the repository or publication with a logical condition inferred from the presence of a boolean system property:

publishing {

    publications {

        if (Boolean.getBoolean('doPublishMyArtifact')) {

            myArtifact(MavenPublication) {
               ...
            }
        }
    }

    repositories {

       // ...
    }
}

and then invoke Gradle with

 gradle ... -DdoPublishMyArtifact=true publish

The same technique works for "selective" repository declaration.

Other techniques, such as detecting the presence of a specific task on command line, etc. can be applied.

The "publish" Task

The plugin also adds a "publish" task that publishes all publications produced by this project, which probably means executing all generated publishing tasks.

POM Generation Tasks

See Published Maven Metadata below.

Procedure

Activate the plugin:

apply plugin: 'maven-publish'

Declare the publications.

publishing {
  publications {
    myPublicationName(MavenPublication) {
      // Configure the publication here
    }
  }
}

The simplest possible configuration for a Java project, that publishes a binary JAR, is:

publishing {
  publications {
    main(MavenPublication) {
      from components.java
    }
  }
}

Declared the target repositories. The example below assumes we want to publish locally into the local Maven repository. Note that the target repository must be declared in the repositories{...} script block of the publishing {...} script block. From more details see Repositories section above.

publishing {

    //
    // ...
    //

    repositories {
        mavenLocal()
    }
}
repositories {
    maven {
        url "${url}"
        authentication {
            basic(BasicAuthentication)
        }
    }
}

Make sure the project coordinates are specified somewhere. For more details see Maven Project Coordinates above.

Publish:

gradle publish

Published Maven Metadata

The plugin generates and publishes the following Maven metadata file:

  • In the artifact's directory (~/.m2/repository/playground/a/a for a groupId='playground.a' and an artifactId='a'), a maven-metadata.xml file with the following content, and the associated md5 and sha1 files:
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>playground.a</groupId>
  <artifactId>a</artifactId>
  <versioning>
    <release>1.0</release>
    <versions>
      <version>1.0</version>
    </versions>
    <lastUpdated>20190504000056</lastUpdated>
  </versioning>
</metadata>
  • In the version directory (~/.m2/repository/playground/a/a/1.0 for a groupId='playground.a', an artifactId='a' and version='1.0'), an a-1.0.pom with the following content, and the assoicated md5 and sha1 files:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/xsd/maven-4.0.0.xsd" 
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>playground.a</groupId>
  <artifactId>a</artifactId>
  <version>1.0</version>
</project>

If the module being published depends on other module, the dependencies reflect in POM. In the example below, "playground.b:b:1.0" is declared as dependent on "playground.a:a:1.0":

dependencies {
    implementation 'playground.a:a:1.0'
}

The corresponding generated POM is:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/xsd/maven-4.0.0.xsd" 
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>playground.b</groupId>
  <artifactId>b</artifactId>
  <version>1.0</version>
  <dependencies>
    <dependency>
      <groupId>playground.a</groupId>
      <artifactId>a</artifactId>
      <version>1.0</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</project>

Note that "implementation" translates to a "runtime" Maven scope.

Also see POM Customization and POM Generation Tasks above.

Examples

https://github.com/NovaOrdis/playground/tree/master/gradle/java-publishing
https://github.com/NovaOrdis/playground/tree/master/gradle/java-publishing-multiprojects-multipubs