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:
- build.gradle
- build.gradle.kts
jarbird { pub {}}
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 variantIn 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:
variant: debugartifactId: simpleaar-staging---variant: releaseartifactId: simpleaar-production---group: jarbirdsamplesversion: 1.0packaging: aar
# ....
Then we may declare the pub
s like this:
- build.gradle
- build.gradle.kts
// variant.name can be "debug" or "release"android.libraryVariants.configureEach { variant -> jarbird { pub(variant.name) { mavenCentral() from(variant) } }}
// variant.name can be "debug" or "release"android.libraryVariants.configureEach { jarbird { pub(name) { mavenCentral() from(this@configureEach) } }}
Then the Jarbird plugin knows the association of a particular pub
and a variant of POM.
#
RepositoriesWe can define one or more repositories for each pub. Each of them is in the form of a function call.
Repository | Meaning |
---|---|
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 settingWe 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
- build.gradle.kts
jarbird { pub { mavenCentral() }}
jarbird { pub { mavenCentral() }}
declare a repository for the pub. On the other hand, the declation :
- build.gradle
- build.gradle.kts
jarbird { mavenCentral() pub { sourceSetNames("main") } pub { sourceSetNames("qa") }}
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.
- build.gradle
- build.gradle.kts
jarbird { mavenCentral()}
jarbird { mavenCentral()}
info
Note that pub
s themselves are not inherited. The pub declared in root project is not available in sub-projects.
#
SigningBy 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 pairsignWithKeyring()
: 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 specificationNormally, 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 projectNormally 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
- build.gradle
- build.gradle.kts
jarbird { pub { from(components.custom) }}
jarbird { pub { from(components["custom"]) }}
See Android section for more details on using components
with Android project.
In case we want to publish two components in single project, we may also specify code to publish by SourceSet
:
- build.gradle
- build.gradle.kts
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 }}
sourceSet { // implicitly the new source set will be at src/altSourceSet1 directory create("altSourceSet1") { } } // implicitly the new source set will be at src/altSourceSet2 directory create("altSourceSet2") { }}
jarbird { pub("pub1") { from(project.sourceSets["altSourceSet1"]) } pub("pub2") { from(project.sourceSets["altSourceSet2"]) }}
Library compilation and document generation will be based on the source set specified in the pub
block.
#
Android AAR projectAndroid 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
- build.gradle.kts
// variant.name can typically be "debug" or "release"android.libraryVariants.configureEach { variant -> jarbird { pub(variant.name) { mavenCentral() from(components[variant]) } }}
// variant.name can be typically "debug" or "release"android.libraryVariants.configureEach { jarbird { pub(name) { mavenCentral() from(components[name]) } }}
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
- build.gradle.kts
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) } }}
plugin { id("io.hkhc.jarbird-android") version "0.7.0" }
// variant.name can be "debug" or "release"android.libraryVariants.configureEach { jarbird { pub(name) { mavenCentral() from(this@configureEach) } }}
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 projectThere 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 pub
s 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 coordinateWhen we publish multiple pub
s in one project, the GAV coordinate of components build with these pub
s 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 versionConsider the jarbird declaration and POM in a project:
- build.gradle
- build.gradle.kts
jarbird { mavenCentral() pub("qa") { from(sourceSets.qa) } pub("release") { from(sourceSets.main) }}
jarbird { mavenCentral() pub("qa") { from(sourceSets.qa) } pub("release") { from(sourceSets.main) }}
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()
:
- build.gradle
- build.gradle.kts
jarbird { mavenCentral() variantWithVersion() pub("qa") { from(sourceSets.qa) } pub("release") { from(sourceSets.main) }}
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 IDSuffixing version with variant may not be the best option for some situations. We may opt to combine variant with artifact ID :
- build.gradle
- build.gradle.kts
jarbird { mavenCentral() variantWithArtifactID() pub("qa") { from(sourceSets.qa) } pub("release") { from(sourceSets.main) }}
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 coordinatesWhen 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:
- build.gradle
- build.gradle.kts
jarbird { mavenCentral() variantInvisible() pub("qa") { from(sourceSets.qa) } pub("release") { from(sourceSets.main) }}
jarbird { mavenCentral() variantInvisible() pub("qa") { from(sourceSets.qa) } pub("release") { from(sourceSets.main) }}
---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 configurationThe 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 :
- build.gradle
- build.gradle.kts
jarbird { mavenCentral() dokkaConfig { dokkaSourceSets.forEach { it.externalDocumentationLink("https://docs.gradle.org/current/javadoc/") } } pub { }}
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.