Skip to main content

pub the Publication

In terms of the Jarbird plugin, "pub" refers to a unit of publication. It usually means publishing a JAR artefact together with related items like source code archive, javadoc archive, POM file, and their signatures. For Gradle plugin publishing, a pub also involves publishing a pseudo component that contains the plugin ID.

A pub also describes the remote repositories it targets. One pub maybe published to one or multiple, heterogenous types of remote repositories.

In build script, we declare a pub in the jarbird block:

jarbird {    pub {}}

This tells the Jarbird plugin that we are going to publish the artefacts built by this project. It will also set up the tasks for archiving source code, generating javadoc and archive it, and signing all of them. It generates tasks to publish all of these to Maven local repository.

So we can run the plugin task by

./gradlew jbPUblishToMavneLocal

or simply

./gradlew jbPublish

which publishes everything to everywhere declared.

pub with variant#

In case there are multiple variants of POM information in pom.yaml, we link the pub with pom.yaml by providing a variant name. For example, in an Android project we have pom.yaml like this:

pom.yaml
variant: debugartifactId: simpleaar-staging---variant: releaseartifactId: simpleaar-production---group: jarbirdsamplesversion: 1.0packaging: aar
# ....

Then we may declare the pubs like this:

build.gradle
// variant.name can be "debug" or "release"android.libraryVariants.configureEach { variant ->     jarbird {        pub(variant.name) {            mavenCentral()            from(variant)        }    }}

Then the Jarbird plugin knows the association of a particular pub and a variant of POM.

Repositories#

We can define one or more repositories for each pub. Each of them is in the form of a function call.

RepositoryMeaning
mavenLocal()Maven local repository. It is included implicitly, so we don't need to specify this explicitly.
mavenCentral()Maven Central
mavenRepo(repo)Custom Maven repository. repo is a string that represents the repository. It is used to match the setting of the repository in gradle.properties
gradlePortal()Gradle Plugin Portal
artifactory(repo)Artifactory repository.repo is a string that representation the repository. It is used to match the setting of a repository in gradle.properties

Extension level setting, pub level setting#

We may customize how a pub is published by adding directives to the pub block or jarbird block. pub inherit all directives declared in the jarbird extension block of the same project and the parent projects.

For example,

build.gradle
jarbird {    pub {        mavenCentral()    }}

declare a repository for the pub. On the other hand, the declation :

build.gradle
jarbird {    mavenCentral()    pub {        sourceSetNames("main")    }    pub {        sourceSetNames("qa")    }}

make mavenCentral() available to both pub in the extension block.

We can even put the directives at the root project so that all sub-projects inherit them.

root project build.gradle
jarbird {    mavenCentral()}
info

Note that pubs themselves are not inherited. The pub declared in root project is not available in sub-projects.

Signing #

By default, the Jarbird plugin attempts to set up artefact signing for each pub. However, no signing is performed for a pub with a version suffixed by `-SNAPSHOT'.

We can disable signing explicitly by using doNotSign() in pub or jarbird block.

Signing needs a key pair. The key pair is generated by GnuPG. Two formats of key stores of GnuPG are available.

  • GnuPG version 2.1 or before use keyring format.
  • GnuPG version 2.2 or after use key box format.

They need different settings in gradle.properties.

We can specify which key format to use by using the following directives:

  • signWithKeybox() : use keybox to access key pair
  • signWithKeyring() : use keyring to access key pair

If we specify one type of key store, and the Jarbird plugin detects that only another type of key store setting is available in gradle.properties, a warning will be shown, and the key store type will be determined by the settings in gradle.properties.

Source set specification#

Normally, Jarbird determines automatically the code to be built as a library. It also tries to figure out the source code directory to build documentation.

JAR project#

Normally we don't need to do anything special in pub {} declaration. Jarbird plugin will look for project.component["java"] for artifacts built and use the JavaPluginConvention class to determine the source sets for documentation.

We may provide alternate component by

root project build.gradle
jarbird {    pub {        from(components.custom)    }}

See Android section for more details on using componentswith Android project.

In case we want to publish two components in single project, we may also specify code to publish by SourceSet:

root project build.gradle
sourceSet {    // implicitly the new source set will be at src/altSourceSet1 directory    altSourceSet1 { }    // implicitly the new source set will be at src/altSourceSet2 directory    altSourceSet2 { }}
jarbird {    pub("pub1") {        from(project.sourceSets.altSourceSet1) // link to sourceSet            }    pub("pub2") {        from(project.sourceSets.altSourceSet2) // link to sourceSet            }}

Library compilation and document generation will be based on the source set specified in the pub block.

Android AAR project#

Android AAR projects come with variants. We have a component instance for each of the variant of the Android project. So the following declaration can succeed.

build.gradle
// variant.name can typically be "debug" or "release"android.libraryVariants.configureEach { variant ->     jarbird {        pub(variant.name) {            mavenCentral()            from(components[variant])        }    }}

However, the source set of Android project is resolved in a different way than the usual JAR project. So it will fail to generate proper documentation.

The proper way to declare pub for an Android project is to use the jarbird-android plugin and provide a LibraryVariant instance to from() method

build.gradle
plugin {    id 'io.hkhc.jarbird-android' version '0.7.0' }
// variant.name can be "debug" or "release"android.libraryVariants.configureEach { variant ->     jarbird {        pub(variant.name) {            mavenCentral()            from(variant)        }    }}

Then source set can be resolved correctly. It works even when our build type/flavour combination of Android project uses multiple source folders to build the project.

Gradle plugin project#

There is no special syntax for pub syntax to publish the Gradle plugin. We can publish multiple Gradle plugins in one project, each of them is specified in a pub block, linked to different variants of pom.yaml.

However, there is one limitation. We can have only one set of meta-information like website, scm information, etc. If there are multiple pubs for Gradle plugin publishing, these pieces of information are picked from the first pub for Gradle plugin publishing. This limitation does not apply to normal JAR projects.

Variant augmented coordinate#

When we publish multiple pubs in one project, the GAV coordinate of components build with these pubs can be blended with the variant, so that we can publish distinguish components to repositories. There are three ways we combine the GAV as specified in pom.yaml with the variant.

Variant with version#

Consider the jarbird declaration and POM in a project:

jarbird {    mavenCentral()    pub("qa") {        from(sourceSets.qa)    }    pub("release") {        from(sourceSets.main)    }}
pom.yaml
group: mygroupartifactId: mylibversion: 1.0

As a result, we publish two components with coordinates:

  • mygroup:mylib:1.0-qa
  • mygroup:mylib:1.0-release

This is the default behaviour. If we prefer it to be stated explicitly, we add variantWithVersion() :

jarbird {    mavenCentral()    variantWithVersion()    pub("qa") {        from(sourceSets.qa)    }    pub("release") {        from(sourceSets.main)    }}

Just like the repositories declaration, it can be in pub block, jarbird block in current project or parent project. and pub get inherited settings from jarbird blocks of the current project and all ancestor projects.

Variant with artefact ID#

Suffixing version with variant may not be the best option for some situations. We may opt to combine variant with artifact ID :

jarbird {    mavenCentral()    variantWithArtifactID()    pub("qa") {        from(sourceSets.qa)    }    pub("release") {        from(sourceSets.main)    }}

Then the components to be published become:

  • mygroup:mylib-qa:1.0
  • mygroup:mylib-release:1.0

Make variant invisible and gain full control of coordinates#

When automatic blending of coordinates are too restrictive and we want to take back full control of it. We may make the variant invisible in coordinates:

jarbird {    mavenCentral()    variantInvisible()    pub("qa") {        from(sourceSets.qa)    }    pub("release") {        from(sourceSets.main)    }}
pom.yaml
---variant: qagroup: mygroup.qaartifactId: mylib.qa---variant: maingroup: mygroup.releaseartifactId: mylib.release---version: 1.0

We use variantInvisible() to disable the automatic blending variant to coordinates. Then we have multiple fragments of pom.yaml to specify the coordinates for each of the variants. Then the result becomes:

  • mygroup.qa:mylib.qa:1.0
  • mygroup.release:mylib.release:1.0

Dokka configuration#

The Jarbird plugin configures the Dokka documentation engine to get proper source code and classpath based on the jarbird block configuration. But sometimes we still want to perform customisation to the Dokka configuration like the title, layout, links to external documentation pages, etc.

We may inject the Dokka configuration in jarbird block. For example, to add hyperlink to the references of the Java standard library :

jarbird {    mavenCentral()    dokkaConfig {        dokkaSourceSets.forEach {            it.externalDocumentationLink("https://docs.gradle.org/current/javadoc/")        }    }    pub { }}

The dokkaConfig block provides a reference to DokkaTask. It has been configured with proper dokkaSourceSets block with classpath and sourceRoot arguments. we can do further customisation in the dokkaConfig block.