Publish Scala library project to Maven Central with Sonatype

Functional Ops

(λx.x)eranga
Effectz.AI
6 min readMay 27, 2020

--

Background

Maven Repository is a directory where all the project jars, library jar, plugins or any other project specific artifacts are stored. Maven Central is a public Maven repository which containing over three million software artifacts, it is one of the world’s largest and oldest archives of software libraries. We can build our artifacts and publish them to Maven Central, then we can simply use them as a library dependency in our sbt/pom projects as like below.

Only very few projects deploy to Maven Central directly. Most small projects these days deploy to Maven Central via the Sonatype Repository. Sonatype offers free OSS repository hosting, which is the most popular way to release libraries to Maven Central. Their service allows you to deploy both snapshot and release binaries of your open source libraries, and sync the releases with Maven Central.

In this post I’m gonna discuss about publishing Scala library project to Maven Central with Sonatype. I’m gonna use some sbt-sonatype, sbt-pgp and sbt-release plugins for it. Following are the steps need to follow. The library project source code which I have used to publish to Maven Central can be found in github. The library project named as Cassper. Cassper is a database schema migration tool for Apache Cassandra. We built it similar to Flyway schema migration tool.

Sonatype account and groupId

First I need to create a groupId for the library projects which I’m gonna publish to Maven Central. The groupId identifies our project uniquely across all projects. In general you or your company will need to own the domain for the groupId you choose. For an example we own a domain rahasak.com, we can use com.rahasak as the groupId. Github users can choose groupId based on the github username. For an example we have github.com/dataoperandz github account. We can use io.github.dataperandz as the groupId. This guide contains more information about the choosing groupId.

To create a groupId first I need to create a Sonatype account(this Sonatype credentials can be used in Sonatype JIRA, Sonatyp Nexus Repository etc). Then need to create a JIRA ticket to claim your groupId. You can do it from here. It asks the groupId you gonna use, project URI, source code URI etc. Then they will look at the JIRA ticket and get back to you with in two days. To prove your ownership of the domain name or github account they will ask some task to do(for an example add a TXT record to your DNS referencing the JIRA ticket or create a new public git repository with a given name in your github). After proving the ownership of domain/github account the ticket will be closed and you’ll be told that you now can publish into your groupId. Here is the JIRA ticket we have created to claim our groupId io.github.dataoperandz. You can find more information about the Sonatype groupId configuration from their official documentation in here.

Configure SBT plugins

To release the Scala library artifact to Maven Central with Sonatype I’m gonna use sbt-sonatype and sbt-pgp plugins. sbt-sonatype plugin use to publish the project to the Maven Central repository through the REST API of Sonatype Nexus. In order to publish the artifacts to Maven Central we need to signed them with PGP, to that we can use sbt-pgp plugin. Add these plugins into project/plugins.sbt file.

Next, I need to define my Sonatype credentials in the global sbt settings (in $HOME/.sbt/(sbt-version 0.13 or 1.0)/sonatype.sbt file). To protect your password, never commit this file to your SCM. When publishing the artifact with sbt, sbt-sonatype can pick them up from the $HOME/.sbt/(sbt-version 0.13 or 1.0)/sonatype.sbt file. I’m using sbt 1.0, so I have created file $HOME/.sbt/1.0/sonatype.sbt with following content.

Configure build.sbt

After that I need to define the version, groupId, SCM information, developer information, Sonatype repository settings etc in the build.sbt file. Following is the build.sbt file I have used.

Configure PGP keys

Next thing is to generate PGP key pair to sign the artifact(to sign the artifact we need to generate a PGP key pair). We can create a key pair with gnupg in MacOS or we can use sbt-pgp plugin for it. After generating key pair we need to publish the public key for key server. There are a few key servers around the internet and every few hours they synchronize with each other so eventually all keys will be on all servers. Sonatype and Maven/Ivy clients will validate the signature on the artifact with your public key to make sure it is exactly what you have published. Following is the way to do that with sbt-pgp plugin.

Publish artifact to Sonatype

Now we can publish our library artifacts to Sonatype. If we use SNAPHOT version, the artifacts will be published to Sonatype SNAPHOT repository. Otherwise artifacts will be published to Sonatype STAGING repository. Following is the way to publish the artifact.

Once we published the artifacts, we can goto Sonatype Nexus Repository and browse the artifacts we have published.

Publish to Maven Central

Once published the artifact to Sonatype staging repository, your artifact components are stored in a separate, temporary repository, that is private to your projects members. In order to get these components published(e.g to Maven Central) you will have to release them. Typically this process is done manually via the Sonatype Nexus Repository web UI. But it is also possible to trigger the actions from the command line as well. You can find more information about the steps to release the artifact via nexus repository web UI from the official document. Following is the way to trigger the release via command line.

Automate release

In above release process we have to manually do all the release steps(e.g git committing, git tagging, sonatype stage release, sonatype release etc). We can automate these steps by using sbt-release plugin. It provides a customizable release process that we can add to our project. Following is the way to automate release process with sbt-release plugin.

First we need to add the sbt-release plugin into projects/plugins.sbt file. Following is my plugins.sbt file content.

The version of the project need to be moved to version.sbt file(version needs to be in a separate file because it’s updated during the release process.)

Then in build.sbt file we can define the release steps. Following is the release steps I have defined for my project.

Now we can run the sbt release command and executes all the release steps defined in the build.sbt file. It will asks current version, next version of the project. When executing publishedSigned it will prompt for a password of the pgp key. When release process completed it will push the changes to the remote git. Before executing sbt-release command we need to commit the uncommitted changes git(working directory must be clean before execute sbt-release). Otherwise release will fail. Following are the main steps of sbt-release console log.

Use published library

Once released the artifact, it will take two/three hours to publish the artifact to Maven Central. Once artifact published I can use it on other Scala application as the library dependency. Following is the way I have used the published library in another Scala project(in build.sbt file). To find the dependency you that need to put on build.sbt, you can browse to Maven Repository web UI and search the library name. Then it shows the available version of the library and their dependency information.

Publish artifact to local repository

Before releasing our artifacts to Sonatype/Maven Central we need to test our artifacts in development/local environment. For that we can release the artifact locally and test them. Following is the way to publish the artifact into local maven repository. Once published it will goes to local maven repository on ~/.m2/repository directory. Then we can add the dependency into another project(as shown above) and test the library.

Reference

  1. http://caryrobbins.com/dev/sbt-publishing/
  2. https://leonard.io/blog/2017/01/an-in-depth-guide-to-deploying-to-maven-central/
  3. https://engineering.iterable.com/publishing-an-open-source-scala-library/
  4. http://gruchalski.com/scala/publish-to-maven-central-via-sonatype-with-sbt.html
  5. https://alexn.org/blog/2017/08/16/automatic-releases-sbt-travis.html
  6. https://central.sonatype.org/pages/ossrh-guide.html

--

--