Publish your SBT project to the Central Repository

Paola Pardo & Eric Ávila

You and your team have been working hard on the very first release of your beloved project. Now it’s time to make it public for the ease of software usage 🚀
In this post, we will be explaining how to publish an sbt project to the Central Repository through Sonatype OSSRH Nexus Manager.

 

First-time preparation for releasing artifacts

Sonatype credentials and GPG keys must be set up before publishing an artifact. These steps have to be done only once and require some human revision.

Sonatype Setup

Sonatype OSSRH (OSS Repository Hosting) provides a repository hosting service for open source project binaries. It uses Maven Repository format and it would allow you to:

  • deploy snapshots
  • stage releases
  • promote releases and sync to the Central Repository

Can I change, delete or modify the published artifacts? → Quick and short answer: No.
Be careful and use -SNAPSHOT suffix on your version to test binaries before moving to a definitive stage.

1. Register to JIRA

There are some configurations that require human interaction (see here why). Sonatype uses JIRA to manage requests, so if you don’t have an account, it’s time to do so.

2. Open a JIRA ticket to solicit the domain

Now you have to create a new ticket requesting the namespace for your packages.
It’s very simple, but here it’s the request we made in case you want some inspiration:

3. Set your domain accordingly

Right after you publish the ticket, you will receive an automatic notification to configure the domain properly.

 

After setting TXT in your domain and editing the status of the ticket, you have to wait for the congratulations message.

Let’s move on to the next step!

 

GPG Setup

In order to sign the artifacts that you want to publish, you will need to create a private/public key pair. Using your tool of choice, create it and upload the public key to a key server when asked, or upload it manually.
I’ll show how to do so on the Linux command line:

1. Generate a GPG key

$> gpg --gen-key

2. List keys to know it’s present in your machine

Once the key pair is generated, we can list them along with any other keys installed:

$> gpg --list-keys
/Users/xxx/.gnupg/pubring.gpg
----------------------------------
pub rsa2048 2012-02-14 [SCEA] [expires: 2028-02-09]
<public-key>
uid [ultimate] Eugene Yokota <eed3si9n@gmail.com>
sub rsa2048 2012-02-14 [SEA] [expires: 2028-02-09]

3. Upload the public key to a server, so you will be able to sign packages and verify them

Since other people need your public key to verify your files, you have to distribute your public key to a key server:
$> gpg --keyserver keyserver.ubuntu.com --send-keys <public-key>
This first key will be set as default for your system, so now the sbt-pgp plugin will be able to use it.

 

 

Releasing an artifact

Now that you are registered in the OSS Sonatype Repository and configured the GPG keys to sign your library, it’s time to prepare your project to compile and produce the corresponding artifacts.

 

1. Prepare build.sbt

Add ‘sbt-sonatype’ and ‘sbt-pgp’ plugins to your project/plugins.sbt  file.

addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.9")
addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2")

In your build.sbt you have to add the reference to the remote Sonatype repository and some settings to accomplish the Maven Central repository requirements.

// Repository for releases on Maven Central using Sonatype
publishTo := sonatypePublishToBundle.value
sonatypeCredentialHost := "s01.oss.sonatype.org"

publishMavenStyle := true
sonatypeProfileName := “io.qbeast” // Your sonatype groupID

// Reference the project OSS repository
import xerial.sbt.Sonatype._
sonatypeProjectHosting := Some(
GitHubHosting(user = “Qbeast-io”, repository = “qbeast-spark”, email = “info@qbeast.io”))

// Metadata referring to licenses, website, and SCM (source code management)
licenses:= Seq(
“APL2” -> url(“https://www.apache.org/licenses/LICENSE-2.0.txt&#8221;))
homepage := Some(url(“https://qbeast.io/&#8221;))
scmInfo := Some(
ScmInfo(
url(“https://github.com/Qbeast-io/qbeast-spark&#8221;),
“scm:git@github.com:Qbeast-io/qbeast-spark.git”))

// Optional: if you want to publish snapshots
// (which cannot be released to the Central Repository)
// You must set the sonatypeRepository in which to upload the artifacts
sonatypeRepository := {
val nexus = "https://s01.oss.sonatype.org/"
if (isSnapshot.value) nexus + "content/repositories/snapshots"
else nexus + "service/local"
}

<!-- (Optional) pomExtra field, where you can reference developers,
among other things. This configuration must be in XML format, like
in the example below, and it will be included in your .pom file. -->
pomExtra :=
<developers>
<developer>
<id>osopardo1</id>
<name>Paola Pardo</name>
<url>https://github.com/osopardo1</url>
</developer>
</developers>

2. Sonatype credentials ~/.sbt/1.0/sonatype.sbt

Apart from the key, you need to set up a credentials file for the Sonatype server. Create a file in $HOME/.sbt/1.0/sonatype.sbt. This file will contain the credentials for Sonatype:

credentials += Credentials("Sonatype Nexus Repository Manager",
"s01.oss.sonatype.org", // all domains registered since February 2021
"(username)",
"(password)")

3. Publish, stage and close

The easiest way is to run the following commands.

sbt clean
sbt publishSigned
sbt sonatypeBundleRelease

Please note that executing the third command is a definitive step and there’s no way back.
The full guide and explanation of what the next commands do can be found here: https://github.com/xerial/sbt-sonatype#publishing-your-artifact. I recommend reading it if it’s your first time doing so, to better understand the process.

 

Let’s explain the commands step by step.

  1. The first command does the cleaning of your target/ directory inside the project.

project-root$> sbt clean

   2. The second command creates all the required artifacts to publish to Maven Central. These files include different JARs (jar, jar+javadoc, jar+sources), a POM file with metadata required for publishing in Maven (qbeast-spark_x.xx-y.y.y.pom), and all the required checksum/CRC files.

project-root$> sbt publishSigned

    3. The third command prepares the Sonatype repository, uploads JARs, and releases them to the public, syncing with the Maven Central repository.

CAUTION. Executing this command is a definitive step and there’s no way back.
project-root$> sbt sonatypeBundleRelease

 

If you want to control each of the steps of sonatypeBundleRelease, you can run:

project-root$> sbt sonatypePrepare
project-root$> sbt sonatypeBundleUpload
project-root$> sbt sonatypeRelease

And finally…

In 10 minutes you will have your package ready for others to download and use it 🔥

Don’t worry if it does not appear on the Maven Central Repository in the following hours, since it takes a little longer to sync. But you can play with it right away!
We hope that you find this post useful 🙌 And don’t hesitate to share your projects with us 😃

 

Want to learn more about SBT?

Book a call with us!