Publishing an open source Scala library

At Iterable we use open source libraries a lot in our Scala code. Typically we use libraries hosted on Maven Central, so adding the dependency in sbt is as simple as:

libraryDependencies += "com.example" %% "mylibrary" % "1.0.0"

But how do you publish your library for other people to consume in this way? The process is not entirely straightforward, so we decided to document the process in a blog post.

But first, why is this useful? We’ve found releasing our own libraries to be helpful for a variety of purposes, including:

  • Releasing utility libraries for other developers to use, for example https://github.com/Iterable/play-formnolia.
  • Forking libraries that are not being actively mainitained and have issues that are hard to work around. Releasing a new version allows other developers to benefit from your changes, and allows us to simply upgrade the library version to fix the issue.
  • Temporarily releasing fixed versions of libraries while waiting for a patch to be reviewed upstream, or while waiting for a stable release containing the fix.

    In all of these cases we could obviously keep the code private and release to a private repository, but there’s no real benefit to doing that if the library itself is not core to our business. By releasing to Maven Central we make it as easy as possible for both our developers and outside developers to benefit from our work.

    Cross building

Scala major versions are not backwards compatible, so if you’re publishing a Scala library, you’ll typically want to build it with multiple Scala versions. To do that, add the following to build.sbt:

scalaVersion := "2.12.8"
crossScalaVersions := Seq(scalaVersion.value, "2.11.12")

scalaVersion is the default Scala version. crossScalaVersions contains all the versions you wish to build with. Running a command with a + like +test will run it on all Scala versions. You can also use ++$SCALA_VERSION test to run on a specific Scala version. For example, you can create multiple jobs on Travis CI for different Scala versions:

language: scala
scala:
  - 2.12.8
  - 2.11.12
script:
  - sbt ++$TRAVIS_SCALA_VERSION compile test publishLocal

Usually, you’ll want to release a library to a few Scala versions, depending on which libraries your dependencies support. For example, if your library depends on Akka, you’d typically want to release for the versions of Scala your Akka version supports.

Note: when you release your artifact, the version will be appended to the artifact name followed by an underscore, like mylibrary_2.12. In sbt, "com.example" %% "mylibrary" % "1.0.0" is equivalent to "com.example" % s"mylibrary_$ScalaVersion" % "1.0.0".

Getting a Sonatype account

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. Sign up for an account and follow their guide to get an account for your domain. This requires opening a JIRA ticket at https://issues.sonatype.org/. For example, this is the one to create the com.iterable group ID: https://issues.sonatype.org/browse/OSSRH-25181. In general you or your company will need to own the domain for the group ID you choose. If you’re a github user, you can use something like com.github.yourusername.

Setting up your PGP key

You’ll need to have a PGP key to sign your releases. If you already have one, you can use that one, or you can create a separate key just for publishing.

You can create a new key with gpg by following these steps:
1. Generate a key with gpg --gen-key. If you want to create a shared key for publishing, consider using something like “$yourcompany bot” or “$projectname bot” as the name. Use your own email address for the email.
2. Then export with gpg --armor --export $ID where $ID is the identifier for that key as given in the gpg output.
3. Next, visit https://pgp.mit.edu/ and paste the output of that command. Make sure your key is between the lines -----BEGIN PGP PUBLIC KEY BLOCK----- and -----END PGP PUBLIC KEY BLOCK-----, and click “Submit this key to the keyserver!”.

Releasing through sbt

Once you’ve gotten this far, you can choose among a few different sbt plugins depending on how you want to perform releases. One strategy is to automate this completely through CI, using a plugin like https://github.com/olafurpg/sbt-ci-release. Under this method, simply pushing a tag will trigger a release for the tagged version in Travis CI. Alternatively, you can opt for an explicit release process using only the sbt-sonatype plugin and optionally the sbt-release plugin. Once you understand the different pieces, you can customize the process to what works best for your team.

Publishing to Sonatype

To publish to Sonatype, you’ll need to add the sbt-sonatype plugin:

addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "2.3")
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.2")

Next, you’ll want to define your Sonatype credentials somewhere. sbt-sonatype can pick them up from SONATYPE_USERNAME and SONATYPE_PASSWORD or you can set them globally in $HOME/.sbt/(sbt-version 0.13 or 1.0)/sonatype.sbt:

credentials += Credentials(
  "Sonatype Nexus Repository Manager",
  "oss.sonatype.org",
  "(Sonatype user name)",
  "(Sonatype password)"
)

Every person (or bot) who publishes will need to have this set up, and their Sonatype account will need to have access to the group ID you want to publish to.

At this point, you’ll want to make sure you have the relevant information in build.sbt so sbt-sonatype can include the required information in your POM file. It should look something like this:

inThisBuild(
  organization := "com.example",
  organizationName := "My Company"
  licenses += ("Apache-2.0", new URL("https://www.apache.org/licenses/LICENSE-2.0.txt")),
  homepage in ThisBuild := Some(url("https://github.com/example/example")),
  scmInfo in ThisBuild := Some(
    ScmInfo(url("https://github.com/example/example"), "scm:git@github.com:example/example.git")
  ),
  developers in ThisBuild := List(
    Developer("exampledeveloper", "Example Developer", "example@example.com", new URL("https://github.com/exampledeveloper"))
  ),
  publishTo := sonatypePublishTo.value
)

Note that inThisBuild defines the settings scoped to ThisBuild, which will apply to all submodules as well.

Make sure you have a version setting defined as well. This is often defined in version.sbt but for now can be in your build.sbt along with the other settings:

version in ThisBuild := "0.0.1-SNAPSHOT"

Next, run the +publishSigned command. Since this is a SNAPSHOT version, this will publish to a snapshots repository at https://oss.sonatype.org/content/repositories/snapshots/. You’ll have to enter your PGP passphrase. It should look like this:

[info] Loading global plugins from /Users/greg/.sbt/1.0/plugins
[info] Loading settings from plugins.sbt ...
[info] Loading project definition from /Users/greg/projects/play-formnolia/project
[info] Loading settings from version.sbt,build.sbt ...
[info] Set current project to play-formnolia (in build file:/Users/greg/projects/play-formnolia/)
[success] Total time: 3 s, completed Sep 7, 2018 5:35:52 PM
[info] Setting Scala version to 2.11.12 on 1 projects.
[info] Reapplying settings...
[info] Set current project to play-formnolia (in build file:/Users/greg/projects/play-formnolia/)
[info] Packaging /Users/greg/projects/play-formnolia/target/scala-2.11/play-formnolia_2.11-0.0.2-SNAPSHOT-sources.jar ...
[info] Done packaging.
[info] Wrote /Users/greg/projects/play-formnolia/target/scala-2.11/play-formnolia_2.11-0.0.2-SNAPSHOT.pom
[info] Writing Ivy file /Users/greg/projects/play-formnolia/target/scala-2.11/resolution-cache/com.iterable/play-formnolia_2.11/0.0.2-SNAPSHOT/resolved.xml.xml
[info] Packaging /Users/greg/projects/play-formnolia/target/scala-2.11/play-formnolia_2.11-0.0.2-SNAPSHOT-javadoc.jar ...
[info] Done packaging.
[info] Packaging /Users/greg/projects/play-formnolia/target/scala-2.11/play-formnolia_2.11-0.0.2-SNAPSHOT.jar ...
[info] Done packaging.
Please enter PGP passphrase (or ENTER to abort): *********************
[info]  published play-formnolia_2.11 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.11/0.0.2-SNAPSHOT/play-formnolia_2.11-0.0.2-SNAPSHOT.pom.asc
[info]  published play-formnolia_2.11 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.11/0.0.2-SNAPSHOT/play-formnolia_2.11-0.0.2-SNAPSHOT-javadoc.jar.asc
[info]  published play-formnolia_2.11 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.11/0.0.2-SNAPSHOT/play-formnolia_2.11-0.0.2-SNAPSHOT.pom
[info]  published play-formnolia_2.11 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.11/0.0.2-SNAPSHOT/play-formnolia_2.11-0.0.2-SNAPSHOT.jar.asc
[info]  published play-formnolia_2.11 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.11/0.0.2-SNAPSHOT/play-formnolia_2.11-0.0.2-SNAPSHOT-sources.jar.asc
[info]  published play-formnolia_2.11 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.11/0.0.2-SNAPSHOT/play-formnolia_2.11-0.0.2-SNAPSHOT.jar
[info]  published play-formnolia_2.11 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.11/0.0.2-SNAPSHOT/play-formnolia_2.11-0.0.2-SNAPSHOT-sources.jar
[info]  published play-formnolia_2.11 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.11/0.0.2-SNAPSHOT/play-formnolia_2.11-0.0.2-SNAPSHOT-javadoc.jar
[success] Total time: 434 s, completed Sep 7, 2018 5:43:06 PM
[success] Total time: 0 s, completed Sep 7, 2018 5:43:07 PM
[info] Setting Scala version to 2.12.8 on 1 projects.
[info] Reapplying settings...
[info] Set current project to play-formnolia (in build file:/Users/greg/projects/play-formnolia/)
[info] Packaging /Users/greg/projects/play-formnolia/target/scala-2.12/play-formnolia_2.12-0.0.2-SNAPSHOT-sources.jar ...
[info] Done packaging.
[info] Writing Ivy file /Users/greg/projects/play-formnolia/target/scala-2.12/resolution-cache/com.iterable/play-formnolia_2.12/0.0.2-SNAPSHOT/resolved.xml.xml
[info] Wrote /Users/greg/projects/play-formnolia/target/scala-2.12/play-formnolia_2.12-0.0.2-SNAPSHOT.pom
[info] Main Scala API documentation to /Users/greg/projects/play-formnolia/target/scala-2.12/api...
[info] Packaging /Users/greg/projects/play-formnolia/target/scala-2.12/play-formnolia_2.12-0.0.2-SNAPSHOT.jar ...
[info] Done packaging.
model contains 5 documentable templates
[info] Main Scala API documentation successful.
[info] Packaging /Users/greg/projects/play-formnolia/target/scala-2.12/play-formnolia_2.12-0.0.2-SNAPSHOT-javadoc.jar ...
[info] Done packaging.
[info]  published play-formnolia_2.12 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.12/0.0.2-SNAPSHOT/play-formnolia_2.12-0.0.2-SNAPSHOT.pom.asc
[info]  published play-formnolia_2.12 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.12/0.0.2-SNAPSHOT/play-formnolia_2.12-0.0.2-SNAPSHOT-javadoc.jar.asc
[info]  published play-formnolia_2.12 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.12/0.0.2-SNAPSHOT/play-formnolia_2.12-0.0.2-SNAPSHOT.pom
[info]  published play-formnolia_2.12 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.12/0.0.2-SNAPSHOT/play-formnolia_2.12-0.0.2-SNAPSHOT.jar.asc
[info]  published play-formnolia_2.12 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.12/0.0.2-SNAPSHOT/play-formnolia_2.12-0.0.2-SNAPSHOT-sources.jar.asc
[info]  published play-formnolia_2.12 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.12/0.0.2-SNAPSHOT/play-formnolia_2.12-0.0.2-SNAPSHOT.jar
[info]  published play-formnolia_2.12 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.12/0.0.2-SNAPSHOT/play-formnolia_2.12-0.0.2-SNAPSHOT-sources.jar
[info]  published play-formnolia_2.12 to https://oss.sonatype.org/content/repositories/snapshots/com/iterable/play-formnolia_2.12/0.0.2-SNAPSHOT/play-formnolia_2.12-0.0.2-SNAPSHOT-javadoc.jar
[success] Total time: 14 s, completed Sep 7, 2018 5:43:20 PM
[success] Total time: 0 s, completed Sep 7, 2018 5:43:20 PM
[info] Reapplying settings...
[info] Set current project to play-formnolia (in build file:/Users/greg/projects/play-formnolia/)
[success] Total time: 1 s, completed Sep 7, 2018 5:43:21 PM

At this point you can test out your snapshot version:

libraryDependencies += "com.example" %% "mylibrary" % "1.0.0-SNAPSHOT"

Note that you can also test out a version from your local Maven repository using sbt publishLocal, then reference it from another project on your machine, as described above.

Snapshots are great for testing, but not great for using in production. You’ll want to have a stable production release to depend on in your app or library.

To publish a real production release, you’d set the version key to something like 1.0.0 (no SNAPSHOT). Your release will be published to a staging repository. You’ll be able to when you log into https://oss.sonatype.org/ and go to “Staging Repositories”. You’ll see a repository named after your group ID (in our case something like comiterable-1234). You can release the staging repo from that UI, or you can use sbt sonatypeReleaseAll to release from sbt.

This is really all you need to do to do releases. If you prefer to manage your release versions solely using git tags, you can use the sbt-dynver plugin to automatically compute a version.

Next we’ll talk about sbt-release, a way to define a more sophisticated set of steps for a release.

Using your published release

Once your staging repository is closed, it usually takes 15 minutes or so for Sonatype to sync to Maven Central. If you want to use it immediately you can add the Sonatype releases repository:

resolvers += Resolver.sonatypeRepo("releases")

If you have a SNAPSHOT release, you’ll need to add:

resolvers += Resolver.sonatypeRepo("snapshots")

Using sbt-release

Sometimes you want a step-by-step interactive process for doing releases to make sure you don’t forget anything. sbt-release is a popular solution to this problem. To set it up, add to plugins.sbt:

addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.9")

Then make sure your version is defined in version.sbt in your project root. This needs to be in a separate file because it’s updated during the release process:

version in ThisBuild := "0.0.1-SNAPSHOT"

Then add the following information to build.sbt (in addition to the information you added above):

import ReleaseTransformations._

releaseCrossBuild := true
releaseProcess := Seq[ReleaseStep](
  checkSnapshotDependencies,
  inquireVersions,
  runClean,
  runTest,
  setReleaseVersion,
  commitReleaseVersion,
  releaseStepCommandAndRemaining("+publishSigned"),
  setNextVersion,
  commitNextVersion,
  releaseStepCommand("sonatypeReleaseAll"),
  pushChanges
)

This defines a set of steps for doing a release:
1. Check that there are no SNAPSHOT dependencies. In other words, all dependencies should point to a stable release, not a snapshot.
2. Ask the user for current and next version.
3. Run clean.
4. Run test.
5. Set the release version in version.sbt.
6. Commit the release version.
7. Tag the release in git (by default this will be something like v1.2.3).
8. Run the +publishSigned command to publish for all crossScalaVersions
9. Set the next version in version.sbt.
10. Commit the release version.
11. Finally, push the changes to the remote git repository.

At this point, you can run the sbt release command anytime you want to create a new release. The whole process looks something like this:

[info] Loading global plugins from /Users/greg/.sbt/1.0/plugins
[info] Updating ProjectRef(uri("file:/Users/greg/.sbt/1.0/plugins/"), "global-plugins")...
[info] Done updating.
[info] Loading settings for project swagger-play-build from plugins.sbt ...
[info] Loading project definition from /Users/greg/projects/swagger-play/project
[info] Loading settings for project swagger-play from version.sbt,build.sbt ...
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] Starting release process off commit: 28516f7e7e4976641dcc01fc9dbe264d44181be4
[info] Checking remote [origin] ...
[info] Setting scala version to 2.12.8
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] Setting scala version to 2.11.12
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] Setting scala version to 2.12.8
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
Release version [1.0.0] : 1.0.0-M2
Next version [1.0.0-SNAPSHOT] :
[success] Total time: 0 s, completed Sep 7, 2018 10:54:07 PM
[info] Setting scala version to 2.12.8
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] Compiling 8 Scala sources and 1 Java source to /Users/greg/projects/swagger-play/target/scala-2.12/classes ...
[info] /Users/greg/projects/swagger-play/src/main/java/play/modules/swagger/PlayReader.java: /Users/greg/projects/swagger-play/src/main/java/play/modules/swagger/PlayReader.java uses or overrides a deprecated API.
[info] /Users/greg/projects/swagger-play/src/main/java/play/modules/swagger/PlayReader.java: Recompile with -Xlint:deprecation for details.
[info] Done compiling.
[info] Compiling 12 Scala sources and 2 Java sources to /Users/greg/projects/swagger-play/target/scala-2.12/test-classes ...
[info] Done compiling.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
[info] PlayDelegatedApiScannerSpec
[info] route parsing should
[info]   + separate delegated paths correctly
[info] Total for specification PlayDelegatedApiScannerSpec
[info] Finished in 624 ms
[info] 1 example, 3 expectations, 0 failure, 0 error
[info] PlayApiScannerSpec
[info] PlayApiScanner should
[info]   + identify correct API classes based on router and API annotations
[info] Total for specification PlayApiScannerSpec
[info] Finished in 74 ms
[info] 1 example, 0 failure, 0 error
[info] PlayApiListingCacheSpec
[info] ApiListingCache should
[info]   + load all API specs
[info] Total for specification PlayApiListingCacheSpec
[info] Finished in 534 ms
[info] 1 example, 3 expectations, 0 failure, 0 error
[info] EBeanModelTest
[info] ModelConverters should
[info]   + not parse an EBean
[info] Total for specification EBeanModelTest
[info] Finished in 53 ms
[info] 1 example, 0 failure, 0 error
[info] Passed: Total 4, Failed 0, Errors 0, Passed 4
[success] Total time: 14 s, completed Sep 7, 2018 10:54:21 PM
[info] Setting scala version to 2.11.12
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] Compiling 8 Scala sources and 1 Java source to /Users/greg/projects/swagger-play/target/scala-2.11/classes ...
[info] /Users/greg/projects/swagger-play/src/main/java/play/modules/swagger/PlayReader.java: /Users/greg/projects/swagger-play/src/main/java/play/modules/swagger/PlayReader.java uses or overrides a deprecated API.
[info] /Users/greg/projects/swagger-play/src/main/java/play/modules/swagger/PlayReader.java: Recompile with -Xlint:deprecation for details.
[info] Done compiling.
[info] Compiling 12 Scala sources and 2 Java sources to /Users/greg/projects/swagger-play/target/scala-2.11/test-classes ...
[info] Done compiling.
[info] PlayDelegatedApiScannerSpec
[info] route parsing should
[info]   + separate delegated paths correctly
[info] Total for specification PlayDelegatedApiScannerSpec
[info] Finished in 480 ms
[info] 1 example, 3 expectations, 0 failure, 0 error
[info] PlayApiScannerSpec
[info] PlayApiScanner should
[info]   + identify correct API classes based on router and API annotations
[info] Total for specification PlayApiScannerSpec
[info] Finished in 108 ms
[info] 1 example, 0 failure, 0 error
[info] PlayApiListingCacheSpec
[info] ApiListingCache should
[info]   + load all API specs
[info] Total for specification PlayApiListingCacheSpec
[info] Finished in 669 ms
[info] 1 example, 3 expectations, 0 failure, 0 error
[info] EBeanModelTest
[info] ModelConverters should
[info]   + not parse an EBean
[info] Total for specification EBeanModelTest
[info] Finished in 39 ms
[info] 1 example, 0 failure, 0 error
[info] Passed: Total 4, Failed 0, Errors 0, Passed 4
[success] Total time: 16 s, completed Sep 7, 2018 10:54:38 PM
[info] Setting scala version to 2.12.8
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] Setting version to '1.0.0-M2'.
[info] Reapplying settings...
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] [master 79141af] Setting version to 1.0.0-M2
[info]  1 file changed, 1 insertion(+), 1 deletion(-)
[info] Reapplying settings...
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] Reapplying settings...
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] Setting Scala version to 2.11.12 on 1 projects.
[info] Reapplying settings...
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] Packaging /Users/greg/projects/swagger-play/target/scala-2.11/swagger-play_2.11-1.0.0-M2-sources.jar ...
[info] Done packaging.
[info] Wrote /Users/greg/projects/swagger-play/target/scala-2.11/swagger-play_2.11-1.0.0-M2.pom
[info] Writing Ivy file /Users/greg/projects/swagger-play/target/scala-2.11/resolution-cache/com.iterable/swagger-play_2.11/1.0.0-M2/resolved.xml.xml
[info] Main Scala API documentation to /Users/greg/projects/swagger-play/target/scala-2.11/api...
[info] Packaging /Users/greg/projects/swagger-play/target/scala-2.11/swagger-play_2.11-1.0.0-M2.jar ...
[info] Done packaging.
model contains 21 documentable templates
[info] Main Scala API documentation successful.
[info] Packaging /Users/greg/projects/swagger-play/target/scala-2.11/swagger-play_2.11-1.0.0-M2-javadoc.jar ...
[info] Done packaging.
[info] Main Scala API documentation successful.
[info] Packaging /Users/greg/projects/swagger-play/target/scala-2.11/swagger-play_2.11-1.0.0-M2-javadoc.jar ...
[info] Done packaging.
Please enter PGP passphrase (or ENTER to abort): ************
[info]  published swagger-play_2.11 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.11/1.0.0-M2/swagger-play_2.11-1.0.0-M2.pom.asc
[info]  published swagger-play_2.11 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.11/1.0.0-M2/swagger-play_2.11-1.0.0-M2-sources.jar
[info]  published swagger-play_2.11 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.11/1.0.0-M2/swagger-play_2.11-1.0.0-M2-javadoc.jar.asc
[info]  published swagger-play_2.11 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.11/1.0.0-M2/swagger-play_2.11-1.0.0-M2-sources.jar.asc
[info]  published swagger-play_2.11 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.11/1.0.0-M2/swagger-play_2.11-1.0.0-M2.pom
[info]  published swagger-play_2.11 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.11/1.0.0-M2/swagger-play_2.11-1.0.0-M2.jar.asc
[info]  published swagger-play_2.11 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.11/1.0.0-M2/swagger-play_2.11-1.0.0-M2.jar
[info]  published swagger-play_2.11 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.11/1.0.0-M2/swagger-play_2.11-1.0.0-M2-javadoc.jar
[success] Total time: 34 s, completed Sep 7, 2018 10:55:12 PM
[info] Setting Scala version to 2.12.8 on 1 projects.
[info] Reapplying settings...
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] Writing Ivy file /Users/greg/projects/swagger-play/target/scala-2.12/resolution-cache/com.iterable/swagger-play_2.12/1.0.0-M2/resolved.xml.xml
[info] Wrote /Users/greg/projects/swagger-play/target/scala-2.12/swagger-play_2.12-1.0.0-M2.pom
[info] Packaging /Users/greg/projects/swagger-play/target/scala-2.12/swagger-play_2.12-1.0.0-M2-sources.jar ...
[info] Done packaging.
[info] Main Scala API documentation to /Users/greg/projects/swagger-play/target/scala-2.12/api...
[info] Packaging /Users/greg/projects/swagger-play/target/scala-2.12/swagger-play_2.12-1.0.0-M2.jar ...
[info] Done packaging.
model contains 21 documentable templates
[info] Main Scala API documentation successful.
[info] Packaging /Users/greg/projects/swagger-play/target/scala-2.12/swagger-play_2.12-1.0.0-M2-javadoc.jar ...
[info] Done packaging.
[info]  published swagger-play_2.12 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.12/1.0.0-M2/swagger-play_2.12-1.0.0-M2.pom.asc
[info]  published swagger-play_2.12 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.12/1.0.0-M2/swagger-play_2.12-1.0.0-M2-sources.jar
[info]  published swagger-play_2.12 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.12/1.0.0-M2/swagger-play_2.12-1.0.0-M2-javadoc.jar.asc
[info]  published swagger-play_2.12 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.12/1.0.0-M2/swagger-play_2.12-1.0.0-M2-sources.jar.asc
[info]  published swagger-play_2.12 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.12/1.0.0-M2/swagger-play_2.12-1.0.0-M2.pom
[info]  published swagger-play_2.12 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.12/1.0.0-M2/swagger-play_2.12-1.0.0-M2.jar.asc
[info]  published swagger-play_2.12 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.12/1.0.0-M2/swagger-play_2.12-1.0.0-M2.jar
[info]  published swagger-play_2.12 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/iterable/swagger-play_2.12/1.0.0-M2/swagger-play_2.12-1.0.0-M2-javadoc.jar
[success] Total time: 13 s, completed Sep 7, 2018 10:55:25 PM
[info] Reapplying settings...
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] Setting version to '1.0.0-SNAPSHOT'.
[info] Reapplying settings...
[info] Set current project to swagger-play (in build file:/Users/greg/projects/swagger-play/)
[info] [master c3574b7] Setting version to 1.0.0-SNAPSHOT
[info]  1 file changed, 1 insertion(+), 1 deletion(-)
[info] Nexus repository URL: https://oss.sonatype.org/service/local
[info] sonatypeProfileName = com.iterable
[info] Reading staging repository profiles...
[info] Reading staging profiles...
[info] Closing staging repository [comiterable-1031] status:open, profile:com.iterable(1b034a65193672) description: Implicitly created (auto staging).
[info] Activity open started:2018-09-07T22:54:56.622Z, stopped:2018-09-07T22:55:03.357Z
[info] repositoryCreated: id:comiterable-1031, user:gmethvin, ip:4.7.100.50
[info] Activity close started:2018-09-07T22:55:35.886Z, stopped:
[info]   Evaluate: id:5e9e8e6f8d20a3, rule:sources-staging
[info]   Evaluate: sources-staging
[info]     Passed: sources-staging
[info]   Evaluate: checksum-staging
[info]     Passed: checksum-staging
[info]   Evaluate: signature-staging
[info]     Passed: signature-staging
[info]   Evaluate: javadoc-staging
[info]     Passed: javadoc-staging
[info]   Evaluate: no-traversal-paths-in-archive-file
[info]     Passed: no-traversal-paths-in-archive-file
[info]   Evaluate: pom-staging
[info]     Passed: pom-staging
[info]     Passed: id:5e9e8e6f8d20a3
[info]      email: to:greg.methvin@gmail.com
[info] repositoryClosed: id:comiterable-1031
[info] Closed successfully
[info] Promoting staging repository [comiterable-1031] status:closed, profile:com.iterable(1b034a65193672) description: Implicitly created (auto staging).
[info] Activity release started:2018-09-07T22:56:11.792Z, stopped:
[info]   Evaluate: id:nx-internal-ruleset, rule:RepositoryWritePolicy
[info]   Evaluate: RepositoryWritePolicy
[info]     Passed: RepositoryWritePolicy
[info]     Passed: id:nx-internal-ruleset
[info]  copyItems: source:comiterable-1031, target:releases
[info]      email: to:greg.methvin@gmail.com
[info] repositoryReleased: id:comiterable-1031, target:releases
[info] Promoted successfully
[info] Dropping staging repository [comiterable-1031] status:released, profile:com.iterable(1b034a65193672) description: Implicitly created (auto staging).
[info] Dropped successfully: comiterable-1031
Push changes to the remote repository (y/n)? [y]
[info] To github.com:Iterable/swagger-play.git
[info]    28516f7..c3574b7  master -> master
[info] To github.com:Iterable/swagger-play.git
[info]  * [new tag]         v1.0.0-M2 -> v1.0.0-M2

If this all worked, congratulate yourself on your new release process!

Posted in Frameworks

Greg Methvin

Greg Methvin works on data infrastructure at Iterable. Previously he worked at several other startups, founded a fintech startup, and was the tech lead for the Play Framework. He has been an active open source contributor for many years, particularly in the Scala community.

More posts by Greg Methvin