Publishing SBT projects to Nexus

Posted by Jan Machacek

Find me on:

28-Jan-2012 08:02:00

Specs2 Spring is available on Sonatype OSS and Maven Central! But how did we get there and what should you do to get the hosting, synchronisation to Maven Central and how do you automate the deployment process? Let's tackle one thing at a time:


Sonatype OSS support

The first thing to is to open an issue in Sonatype's JIRA, asking them to set up the Nexus repository for you. Once that's done, you will be able to publish your snapshots and releases to Sonatype; the releases are then synchronised to Maven Central. The first few pages of Sonatype OSS Maven Repository Usage Guide will show you how to get started.

Building and publishing

Now, this is the interesting bit. We are using SBT to build the project and we'd like to be able to run sbt publish to compile, package and publish the project to Sonatype automatically. Before we can do that, we need to configure GPG and SBT plugin that uses GPG to sign the artefacts. The plugin is xsbt-gpg-plugin, which will use GPG to sign the artefacts--properly signed artefacts are the requirement for Maven Central synchronisation. So, with the plugin, your project/plugins.sbt file should contain:

...
resolvers += Resolver.url("scalasbt", /* no new line */
  new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases")) /* no new line */
  (Resolver.ivyStylePatterns)

addSbtPlugin("com.jsuereth" % "xsbt-gpg-plugin" % "0.5")
...

If you do not have GPG, you must also install & configure it for your platform; if you do not have your keys, you must also generate key pair and then publish your public key. I cannot quite show you how to do this on Windows (sorry, get a Mac!). On OS X, you can use GPG Tools. Download and install it; the first thing GPG Tools will prompt you to do is to generate your key, protected by a passphrase. (I recommend that you keep the passphrase very long, as XKCD points out in Figure 1!)

Figure 1. Key strengths

Password Strengths

Before I can release the artefacts in Sonatype OSS releases and in Maven Central, I need to publish my public keys (so that others can verify that the artefacts are intact and that it was I who has produced them). To do that, you can use the GPG Keychain Access (see Figure 2) tool or use the gpg command-line program.

Figure 2. GPG Keychain Access

gpgkeychainaccess

We are programmers, so let's turn to the command line: we need to export a key, but to do that, we need to know its identifier:

$ gpg --list-secret-keys
/Users/janmachacek/.gnupg/secring.gpg
-------------------------------------
sec   2048R/90A468A9 2012-01-30 [expires: 2016-01-30]
uid                  Jan Machacek <jan.machacek@gmail.com>
ssb   2048R/A9ED23D0 2012-01-30

$ gpg --send-keys 90A468A9

Your public key is now uploaded to the default key server (specified in ~/.gnupg/gpg.conf) and it will be distributed to other key servers over the next few minutes. Once that happens, you'll be ready to release your artefacts to Maven Central.

Releasing

Before we'll configure the JAR signing, we must deal with the publish process. We set the publishTo (and several other settings) in build.sbt to use the Sonatype repository like so:

publishTo <<= version { v: String =>
  val nexus = "https://oss.sonatype.org/"
  if (v.trim.endsWith("SNAPSHOT"))
    Some("snapshots" at nexus + "content/repositories/snapshots")
  else
    Some("releases" at nexus + "service/local/staging/deploy/maven2")
}

Before we can publish our SBT-based project, we must ensure that its generated Maven POMs match the strict requirements of Sonatype and Maven Central. So, we must include the following code in your build.sbt:

organization := "org.specs2"

publishMavenStyle := true

publishArtifact in Test := false

pomIncludeRepository := { x => false }

pomExtra := (
  <url>http://www.cakesolutions.org/specs2-spring.html</url>
  <licenses>
    <license>
      <name>BSD-style</name>
      <url>http://www.opensource.org/licenses/bsd-license.php</url>
      <distribution>repo</distribution>
    </license>
  </licenses>
  <scm>
    <url>git@github.com:janm399/specs2-spring.git</url>
    <connection>scm:git:git@github.com:janm399/specs2-spring.git</connection>
  </scm>
  <developers>
    <developer>
      <id>janmachacek</id>
      <name>Jan Machacek</name>
      <url>http://cakesolutions.org</url>
    </developer>
  </developers>
)

Now, before we even attempt to run sbt publish, we need to specify the credentials for the Sonatype repository. But we don't want to do that in the files we push to the VCS! Instead, we'll create file sonatype.sbt, which sets the credentials setting to the Sonatype ones. If you are using SBT version prior to 0.11.x, save this file in ~./sbt; if you are using later version (in my case, 0.11.2 and 0.12.0-M1), put the file in ~./sbt/sbt-version, for example ~./sbt/0.11.2. (Thanks to @channingwalton for the reminder to update!)

credentials += Credentials("Sonatype Nexus Repository Manager",
                           "oss.sonatype.org",
                           "your-sonatype-username",
                           "your-sonatype-password")

The work is done! We've modified

  • ~/.sbt/sbt-version/sonatype.sbt with the Sonatype OSS credentials
  • project/plugins.sbt with the xsbt-gpg-plugin plugin to sign the artefacts
  • build.sbt to include the release settings

Now we can run sbt publish, supply our key phrase go GPG and push the artefacts to Sonatype. If you are publishing snapshot release, then your work is done. If you are publishing a "real" release, keep reading.

Promoting

Once you've published your non-snapshot release, you will need to go to the Sonatype Nexus, login, select the staging repository and close it. (Again, follow the Sonatype Nexus guide for details.) Closing will verify that the Maven POMs are well formed, that the artefacts' signatures are valid. If all is well, your repository will end up in Maven Central within a few hours' time!

Summary

Publishing SBT-based projects to Sonatype and then Maven Central is easy--once you've dealt with the details of the Maven POMs. For complete views of the build.sbt and project/plugins.sbt files, take a look at Specs2 Spring's sources at https://www.github.com/janm399/specs2-spring.

Josh Suereth (http://jsuereth.com/), the maintainer of the xsbt-gpg-plugin SBT plugin maintains a page where he outlines the latest details of the SBT deployment process. Clicky-here to see Josh's instructions.

 

Topics: Sbt

Subscribe to Email Updates