Publishing a Kotlin library to your Bintray repo using Gradle Kotlin DSL

Photo by Henk Mul on Unsplash

If you’re working on an OSS project you will most likely come to a point where you will want to publish your artifacts to a publicly accessible repository (A central Maven repository, for example, if you’re working on a java-based project.) For someone who has never published an artifact to be available to others the process can be somewhat unclear and scarce documentation makes things even more daunting. And if you’re using gradle with kotlin dsl build scripts then chances are documentation will be even sparser.

I am a tester and have been coding for a living for the past couple of years now. Some time ago I’ve gone through the process of publishing my first OSS project, a kotlin library for generating fake data for tests: kotlin-faker. Once you understand the process of publishing your artifacts things become quite simple.

Where to publish?

Photo by Bruno Wolff on Unsplash

At first I was thinking to publish everything directly to Maven Central. This seems like a natural choice since this is the repository that is more commonly used and is directly accessible from most Maven and Gradle builds without the need to specify any additional information such as the url to your custom repo.

However there are some caveats to doing this and I would generally recommend using a custom repository, for example Bintray (which is what I am using myself and will be showing in this article) unless you’re absolutely sure what you’re doing.

First you should be sure about your setup. You can play around with your publishing setup and always undo things in Bintray. Second is that you have complete control over your files and if you’re not sure about the quality of your library and want to test things — this would be a good place to do this. In Maven Central you sort of loose all control after you publish something there.

Note: while you do have the ability to modify your files in your own Bintray repo, you should be careful while doing so as this might break things for people who are already using these artifacts.

After publishing to Bintray and verifying that everything is as you want it to be you can then publish your artifacts to Maven Central directly from Bintray. You can read more about it in their blogpost.

Prerequisites

These are pretty self explanatory and easy to find so I won’t go into much details here and just list what you will need to do.

  • Create a new account (you can also login with your existing github, google or twitter account)
  • Add a new repository (Select the type as ‘Maven’.)
  • Get your API key — go to ‘edit profile’ and you will see the ‘API Key’ tab there.

Gradle build file setup

First we need to add the maven-publish and bintray plugins added to the gradle.build.kts build script file:

plugins {
`maven-publish`
id("com.jfrog.bintray") version "1.8.4"
}

After adding maven-publush plugin you should have a publishing function available, which is used to configure the plugin:

Notice the pom.withXml part. We need to set certain metadata before publishing a library. Maven Central, for example, has some requirements on what metadata needs to be present in the pom.

This can be done as seen in the gist above. Another way is to utilize the DSL that Maven Publish Plugin provides for this purpose:

pom {
name = 'My Library'
description = 'A concise description of my library'
url = 'http://www.example.com/library'
properties = [
myProp: "value",
"prop.with.dots": "anotherValue"
]
licenses {
license {
name = 'The Apache License, Version 2.0'
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id = 'johnd'
name = 'John Doe'
email = 'john.doe@example.com'
}
}
scm {
connection = 'scm:git:git://example.com/my-library.git'
developerConnection = 'scm:git:ssh://example.com/my-library.git'
url = 'http://example.com/my-library/'
}
}

Note: as mentioned by nwillc in the comments, it is not necessary to explicitly specify the pom metadata, therefore the pom {} function can be omitted altogether unless you want to set/modify some things in the generated pom explicitly.

Usually you want to publish javadocs and sources as well. For sources we need to create a task that will generate a jar:

val sourcesJar by tasks.creating(Jar::class) {
archiveClassifier.set("sources")
from(sourceSets.getByName("main").allSource)
}

And add it to the publishing plugin:

publishing {
publications {
create<MavenPublication>("kotlin-faker") {
//groupId, version, etc
artifact(sourcesJar)

// pom, etc
}
}
}

To generate kdocs in kotlin you should use the dokka plugin.

For more info on using Maven Publish Plugin see the official userguide page.

The Bintray plugin takes care of actually uploading artifacts to your repository.

A basic setup would look something like this:

A few things to keep in mind:

  • the repo should match with whatever repository name you specified when creating a new repo on Bintray. I simply named it maven.
  • the user and key were covered in the Prerequisites section of this post. You will need to pass them when uploading the artifacts, i.e. from the command line or from the CI tool.

The rest is pretty much self explanatory.

Publishing to your Bintray repo

I don’t use CI for automated publications yet as Bintray supports only release versions, therefore when I’m ready to upload a new release I just use the command line: $ ./gradlew bintrayUpload -PbintrayUser="my_bintray_username" -PbintrayKey="my_bintray_api_key"

This can also be set up with CI like Travis for example, and you can store your credentials there as well.

Referring to your library

In other to be use the published library as a dependency in a build file we first need to add the repository to the list of repositories:

In gradle it would look like this:

repositories {
maven {
setUrl("https://dl.bintray.com/serpro69/maven/")
}
}

After that the library can be added as a usual dependency:

dependencies {
implementation 'io.github.serpro69:kotlin-faker:0.2'
}

Retrospective

All in all this wasn’t actually that hard. I needed to collect some pieces of missing information here and there and understand what’s happening when you publish an artifact and what are the prerequisites for that. After that the process looks quite straightforward.

Having a personal repository on Bintray where you can actually play around and have control over your files helps a lot. I’m glad I didn’t go with Maven Central straight on.

You can check out the complete build file of my project here. Hopefully it will help you move in the right direction when publishing your artifacts to Bintray.

Searching for the answer to the Ultimate Question by night, tester by calling, serendipitously became a developer by day… Automating all things 24x7.