Publishing Android Components
In this tutorial, we are going to publish the Android AAR library to Maven Central.
The sample project is here.
Unlike publishing conventional JAR libraries, we need to take care of the Build Types, Flavors, and Variants of Android library projects.
A variant is a combination of a build type and a flavour, so that it may refer to a combination of source set, resources, etc. For example, a typical Android project may have build types debug
and release
, and flavours for qa
and production
. Then we have four different variants:
qaDebug
qaRelease
productionDebug
productionRelease
(We could ignore some combinations that do not make sense for a particular project, please refer to variantFilter
in Android documentation for details)
Each of the variants creates a different library and can be published (or not to be published) individually. Jarbird plugin supports configure how each of these components is published.
The source code of this tutorial is in the android
directory.
#
pom.yamlThe pom.yaml
file is not that different from conventional JAR publishing. The only difference right now is the packaging
line.
group: jarbirdsamplesartifactId: simpleaarversion: 1.0packaging: aar
licenses: - name: Apache-2.0 dist: repo
developers: - id: demo name: Jarbird Demo email: jarbird.demo@fake-email.com
scm: repoType: github.com repoName: demo/jarbird-samples/android
#
build.gradleWe have a different plugin ID for Android project:
- build.gradle
- build.gradle.kts
plugins { id 'com.android.library' id 'kotlin-android' id 'io.hkhc.jarbird-android' version "0.7.0"}
plugins { id("com.android.library") id("kotlin-android") id("io.hkhc.jarbird-android") version "0.7.0"}
There is no new syntax and functions in the plugin io.hkhc.jarbird-android
. It just has the additional capability to recognize Android LibraryVariant
objects. It does not hurt to use this plugin on conventional JAR projects. Just looks confusing.
The build script of typical Android library projects has an android block to configure the build types and flavours. We add our code after the android
block to specify how they are published, in the Jarbird way.
- build.gradle
- build.gradle.kts
// after android {}android.libraryVariants.configureEach { variant -> jarbird { pub(variant.name) { mavenCentral() from(variant) } }}
// after android {}android.libraryVariants.configureEach { jarbird { pub(name) { mavenCentral() from(this@configureEach) } }}
Note how Kotlin and Groovy differ in getting the proper reference to the from()
method. Because of the configureEach
loop, we created two pub
s, one for each variant, and the results are two sets of artefacts.
There are two things in the jarbird
block that differs from our previous tutorials. First the additional from()
block that we have mentioned. When building conventional JAR libraries, we normally don't need to specify where the source code comes from. The plugin will figure it out by itself. When publishing Android AAR components, we need to tell what to publish by passing the LibraryVariant
reference to the from()
method. Without from()
the publishing will fail.
The other thing to notice is that we provided a name to pub
. It is used to identify them when there are multiple pub
. It could be any string as long as it is unique among pub
s. Conventionally we use the variant name of the Android project. The name helps the Jarbird plugin to link pub to particular variant of POM in pom.yaml
.
Normally Android library has at least two build types, debug
and release
.
#
Run ItExecuting ./gradlew jbPublishToMavenLocal
we get two publications:
~/.m2/repository/jarbirdsamples/simpleaar/1.0-release
~/.m2/repository/jarbirdsamples/simpleaar/1.0-debug
The artifacts will look like:
ls -1 ~/.m2/repository/jarbirdsamples/simpleaar/1.0-releasesimpleaar-1.0-release-javadoc.jarsimpleaar-1.0-release-javadoc.jar.ascsimpleaar-1.0-release-sources.jarsimpleaar-1.0-release-sources.jar.ascsimpleaar-1.0-release.aarsimpleaar-1.0-release.aar.ascsimpleaar-1.0-release.modulesimpleaar-1.0-release.module.ascsimpleaar-1.0-release.pomsimpleaar-1.0-release.pom.asc
This is the default way to distinguish different publications, that the version is suffixed by the variant. However, we can change that.
#
Variant with artifactIdWe may make the variant part of the artifactId. We add one line to the Jarbird configuration:
- build.gradle
- build.gradle.kts
android.libraryVariants.configureEach { variant -> jarbird { pub(variant.name) { mavenCentral() variantWithArtifactId() from(variant) } }}
android.libraryVariants.configureEach { jarbird { pub(name) { mavenCentral() variantWithArtifactId() from(this@configureEach) } }}
The additional line indicates the artifactId shall be suffixed by the variant. After executing jbPublishToMavenLocal
, we get two publications with directories like this:
~/.m2/repository/jarbirdsamples/simpleaar-release/1.0
~/.m2/repository/jarbirdsamples/simpleaar-debug/1.0
We could have even greater control to the coordinate of components by specifying variant in pom.yaml
#
Variant with POMWe may customize the POM information for each variant in pom.xml
. There are two ways to do so. In this tutorial, we will focus on one method first.
Let's change the pom.yaml
like this:
variant: debugartifactId: simpleaar-staging---variant: releaseartifactId: simpleaar-production---group: jarbirdsamplesversion: 1.0packaging: aar
licenses: - name: Apache-2.0 dist: repo
developers: - id: demo name: Jarbird Demo email: jarbird.demo@fake-email.com
scm: repoType: github.com repoName: demo/jarbird-samples/android
Now our pom.yaml
has three sections, two of them have a variant
attribute. When publishing components, the Jarbird plugin combine the section in pom.yaml
with the variant
attribute and the section without variant
. Therefore effectively we have different pom.yaml
for each of the variants.
Then we add a line to the build.gradle
file.
- build.gradle
- build.gradle.kts
android.libraryVariants.configureEach { variant -> jarbird { pub(variant.name) { mavenCentral() variantInvisible() from(variant) } }}
android.libraryVariants.configureEach { jarbird { pub(name) { mavenCentral() variantInvisible() from(this@configureEach) } }}
The line variantInvisible()
tell Jarbird plugin not to merge the variant name. So the information of components we built is entirely on pom.yaml
.
Executing ./gradlew jbPublishToMavenLocal
and we will get the following in Maven Local repository:
~/.m2/repository/jarbirdsamples/simpleaar-production/1.0
~/.m2/repository/jarbirdsamples/simpleaar-staging/1.0
The artifacts of the release variant look like this:
$ ls -1 ~/.m2/repository/jarbirdsamples/simpleaar-production/1.0simpleaar-production-1.0-javadoc.jarsimpleaar-production-1.0-javadoc.jar.ascsimpleaar-production-1.0-sources.jarsimpleaar-production-1.0-sources.jar.ascsimpleaar-production-1.0.aarsimpleaar-production-1.0.aar.ascsimpleaar-production-1.0.modulesimpleaar-production-1.0.module.ascsimpleaar-production-1.0.pomsimpleaar-production-1.0.pom.asc