Publishing Android Library to Bintray
In my previous post about Android library project initialization I wrote how to write our own library or module to support our main application. Look at library dependencies at your gradle script.
compile 'com.android.support:appcompat-v7:25.2.0'
Above code was an example of a Maven library that we includes in our application.
In this post I will talk more about how I publish library to public maven repository such as bintray, maven central, etc so people can start using your library easier with same code format as above code example.
Basically if we want to publish a library in maven repository we need to have several things:
- The artifacts → binary that we want to publish. For example:
jar
(Java library) file,aar
(Android library) file,pods
(iOS library) file. - Group identifier → publisher identifier. Mostly domain name for easier publisher identification. For example:
com.domain.sdk
. - Artifact identifier → library or artifact identifier. Mostly library name for easier library identifier in specific group. For example:
payment-module
. - Version name → to identify revision of library. For example:
1.2.1
.
Above items was minimum things needed to publish and use the library. In Maven it was included on pom.xml
file. The pom.xml file is the core of a project’s configuration in Maven. It includes many information to build and use the library project.
For library user they will just have define the library like this in their gradle script.
compile 'com.domain.sdk:payment-module:1.2.1'
Easy, isn’t it? Of course this maven repository was made to realize above dependencies concept in modern Android or Java development.
There are several optional things to considerate when publishing library.
- External dependencies → if your library needs another library you can includes it by knowing the group identifier, artifact identifier and also the latest version name.
- More project details → project name, description, url, licenses, etc. you can define to explain more about your library project.
So the bare minimum generated pom.xml
file should be like this.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.domain.sdk</groupId>
<artifactId>payment-module</artifactId>
<version>1.2.1</version>
<packaging>aar</packaging>
<dependencies>
<dependency>
<groupId>com.android.support</groupId>
<artifactId>appcompat-v7</artifactId>
<version>25.2.0</version>
</dependency>
</dependencies>
</project>
Note: Above example was basic usage for Android library Maven publication. For more information about Maven concept you can take a look at this reference.
So, now we have grasped the concept behind Android library publication by using Maven. The next step is to know how we can use its concept in our library so we can publish it and people can start using it. If your Android project was already using gradle and you want to publish it to bintray
then this tutorial is relevant to you.
1. Create Bintray Account and Repository
Basically you just need to use maven-publish
plugin provided by gradle to make it easier to publish your library. Also you can use bintray plugin if you’re going to publish it on your own bintray repository. Please make account and repository for bintray if you don’t have it. You can read Creating a New Repository in Bintray article to get started on it.
2. Create Publication Script
After we done the first step then we can start writing publication script in gradle. Below script is an example to publish your library to your bintray repository (credential was obtained in step 1).
apply plugin: 'com.jfrog.bintray'
apply plugin: 'maven-publish'
publishing {
publications {
Production(MavenPublication) {
artifact("$buildDir/outputs/aar/payment-module-release.aar")
groupId 'com.domain.sdk'
artifactId 'payment-module'
version '1.2.1'
//The publication doesn't know about our dependencies, so we have to manually add them to the pom
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
//Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each
configurations.compile.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
}
Sandbox(MavenPublication) {
artifact("$buildDir/outputs/aar/corekit-development-release.aar")
groupId 'com.domain.sdk'
artifactId 'payment-module'
version '1.2.1-SANDBOX'
//The publication doesn't know about our dependencies, so we have to manually add them to the pom
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
//Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each
configurations.compile.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
} }
}
bintray {
// Get Bintray credential from environment variable
user = System.getenv('BINTRAY_USER') // Get bintray User
key = System.getenv('BINTRAY_KEY') // Get bintray Secret Key
configurations = ['archives']
pkg {
repo = 'maven'
name = project.name
userOrg = 'owner-name'
licenses = ['Apache-2.0']
desc = 'Payment module SDK'
websiteUrl = "https://domain.com"
publish = true
}
publications = ['Production', 'Sandbox']
}
By looking at above script, we know that artifact
, groupId
, artifactId
and version
is needed to make a Maven publication. Note that we can make several publications within a library project. For example if our library can have several flavors such as sandbox and production build. We can make two different maven publications with same group and artifact identifier but with different version name. Sandbox one can have -SANDBOX
suffix on its version.
Also in above script you will notice that there are some kind of pom related scripts. Normal implementation of maven-publish
plugin will produce basic pom.xml
without external dependencies needed to build our library so we need to add it manually to generated pom.xml
by detecting our dependencies in our gradle script. So our library dependencies such as compile 'com.android.support:appcompat-v7:25.2.0'
will be added to generated pom.xml
. Users that use our library will also includes our external library without they even write it explicitly in their application gradle script.
Another things that matters when we want to publish the library in bintray was bintray
part. You need to includes your credentials. To make it secure, you can add it by using environment variables. Inside pkg
you can set your project details that will be shown on your bintray page. Also publications
part will define your Maven publication that you want to includes on your bintray repository. In this part I set Sandbox
and Production
in the publications because I want to publish those variants on the bintray. Note that Sandbox
and Production
publications were defined in publishing
→ publications
.
3. Run Gradle Publication Task
After completed previous steps you can start publishing your library by call specific gradle task created for bintray
plugin named bintrayUpload
. Please note that the task was located inside your library module (for my example it’s payment-module
).
> export BINTRAY_USER=YourBintrayUsername
> export BINTRAY_KEY=YourBintraySecretKey
> ./gradlew :clean :payment-module:assembleRelease :payment-module:bintrayUpload
4. Test your Published Library
By completing third step your library now is publicly available on your bintray repository. Please make sure you have added your bintray repository name on your repositories
.
repositories {
maven { url "http://dl.bintray.com/owner-name/maven" }
}
Then on dependencies
we can add our library definition easily.
compile 'com.domain.sdk:payment-module:1.2.1'
Start your gradle sync process and wait for your library be fetched on your project.
Notes:
- If your library have external dependencies defined please make sure their source repository was included on
repositories
too. If you want to use two different flavors in your project you must define the flavors in your gradle script. Example:
sandboxCompile 'com.domain.sdk:payment-module:1.2.1-SANDBOX'
productionCompile 'com.domain.sdk:payment-module:1.2.1'
That’s it from me. Hope it helps you publish your own library so it can be used by other people. Congratulations, you have contributed to community 😃