Using Sonatype 

Deploying to sonatype is easy! Just follow these simple steps:

Sonatype setup 

The reference process for configuring and publishing to Sonatype is described in their OSSRH Guide. In short, you need two publicly available URLs:

The OSSRH Guide walks you through the required process of setting up the account with Sonatype. It’s as simple as creating a Sonatype's JIRA account and then a New Project ticket. When creating the account, try to use the same domain in your email address that the project is hosted on. It makes it easier for Sonatype to validate the relationship with the groupId requested in the ticket, but it is not the only method used to confirm the ownership.

Creation of the New Project ticket is as simple as:

After creating your Sonatype account on JIRA, you can log in to the Nexus Repository Manager using the same credentials, although this is not required in the guide, it can be helpful later to check on published artifacts.

Note: Sonatype advises that responding to a New Project ticket might take up to two business days, but in my case it was a few minutes.

SBT setup 

To address Sonatype’s requirements for publishing to the central repository and to simplify the publishing process, you can use two community plugins. The sbt-pgp plugin can sign the files with GPG/PGP and sbt-sonatype can publish to a Sonatype repository.

First - PGP Signatures 

With the PGP key you want to use, you can sign the artifacts you want to publish to the Sonatype repository with the sbt-pgp plugin. Follow the instructions for the plugin and you’ll have PGP signed artifacts in no time.

In short, add the following line to your ~/.sbt/0.13/plugins/gpg.sbt file to enable it globally for SBT projects:

addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0")

Note: The plugin is a jvm-only solution to generate PGP keys and sign artifacts. It can also work with the GPG command line tool.

If you don’t have the PGP keys to sign your code with, one of the ways to achieve that is to install the GNU Privacy Guard and:

PGP Tips’n’tricks 

If the command to generate your key fails, execute the following commands and remove the displayed files:

> show */*:pgpSecretRing
[info] /home/username/.sbt/.gnupg/secring.gpg
> show */*:pgpPublicRing
[info] /home/username/.sbt/.gnupg/pubring.gpg

If your PGP key has not yet been distributed to the keyserver pool, e.g., you’ve just generated it, you’ll need to publish it. You can do so using the sbt-pgp plugin:

pgp-cmd send-key keyname hkp://

Where keyname is the name or email address used when creating the key or hexadecimal identifier for the key.

If you see no output from sbt-pgp then the key name specified was not found.

If it fails to run the SendKey command you can try another server (for example: hkp:// A list of servers can be found at the status page of

Second - Configure Sonatype integration 

The credentials for your Sonatype OSSRH account need to be stored somewhere safe (e.g. NOT in the repository). Common convention is a ~/.sbt/0.13/sonatype.sbt file (e.g. `) with the following:

credentials += Credentials("Sonatype Nexus Repository Manager",
                           "<your username>",
                           "<your password>")

Note: The first two strings must be "Sonatype Nexus Repository Manager" and "" for Ivy to use the credentials.

Now, we want to control what’s available in the pom.xml file. This file describes our project in the maven repository and is used by indexing services for search and discover. This means it’s important that pom.xml should have all information we wish to advertise as well as required info!

First, let’s make sure no repositories show up in the POM file. To publish on maven-central, all required artifacts must also be hosted on maven central. However, sometimes we have optional dependencies for special features. If that’s the case, let’s remove the repositories for optional dependencies in our artifact:

pomIncludeRepository := { _ => false }

To publish to a maven repository, you’ll need to configure a few settings so that the correct metadata is generated. Specifically, the build should provide data for organization, url, license, scm.url, scm.connection and developer keys. For example:

licenses := Seq("BSD-style" -> url(""))

homepage := Some(url(""))

scmInfo := Some(
    "scm:[email protected]:your-account/your-project.git"

developers := List(
    id    = "Your identifier",
    name  = "Your Name",
    email = "[email protected]",
    url   = url("http://your.url")

Maven configuration tips’n’tricks 

The full format of a pom.xml (an end product of the project configuration used by Maven) file is outlined here. You can add more data to it with the pomExtra option in build.sbt.

To ensure the POMs are generated and pushed:

publishMavenStyle := true

Setting repositories to publish to:

publishTo := {
  val nexus = ""
  if (isSnapshot.value)
    Some("snapshots" at nexus + "content/repositories/snapshots")
    Some("releases"  at nexus + "service/local/staging/deploy/maven2")

Not publishing the test artifacts (this is the default):

publishArtifact in Test := false

Third - Publish to the staging repository 

Note: sbt-sonatype is a third-party plugin meaning it is not covered by Lightbend subscription.

To simplify the usage of the Sonatype’s Nexus, add the following line to build.sbt to import the sbt-sonatype plugin to your project:

addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "1.1")

This plugin will facilitate the publishing process, but in short, these are the main steps for publishing the libraries to the repository:

  1. Create a new staging repository: sonatypeOpen "your groupId" "Some staging name"
  2. Sign and publish the library to the staging repository: publishSigned
  3. You can and should check the published artifacts in the Nexus Repository Manager (same login as Sonatype’s Jira account)
  4. Close the staging repository and promote the release to central: sonatypeRelease

After publishing you have to follow the release workflow of Nexus.

Note: the sbt-sonatype plugin can also be used to publish to other non-sonatype repositories

Publishing tips’n’tricks 

Use staged releases to test across large projects of independent releases before pushing the full project.

Note: An error message of PGPException: checksum mismatch at 0 of 20 indicates that you got the passphrase wrong. We have found at least on OS X that there may be issues with characters outside the 7-bit ASCII range (e.g. Umlauts). If you are absolutely sure that you typed the right phrase and the error doesn’t disappear, try changing the passphrase.

Fourth - Integrate with the release process 

Note: sbt-release is a third-party plugin meaning it is not covered by Lightbend subscription.

To automate the publishing approach above with the sbt-release plugin, you should simply add the publishing commands as steps in the releaseProcess task:

ReleaseStep(action = Command.process("sonatypeOpen \"your groupId\" \"Some staging name\"", _)),
ReleaseStep(action = Command.process("publishSigned", _)),
ReleaseStep(action = Command.process("sonatypeRelease", _)),


sbt Reference Manual
    1. Using Sonatype