auto publish sbt plugin from Travis CI
In this post, we'll try to automate the release of an sbt plugin using Ólafur's olafurpg/sbt-ci-release. The README of sbt-ci-release covers the use case for a library published to Sonatype OSS. Read it thoroughly since this post will skip over the details that do not change for publishing sbt plugins.
Automated release in general is a best practice, but there's one benefit specifically for sbt plugin releases. Using this setup allows multiple people to share the authorization to release an sbt plugin without adding them to Bintray sbt organization. This is useful for plugins maintained at work.
step 1: sbt-ci-release
Remove sbt-release if you're using that. Add sbt-ci-release instead.
addSbtPlugin("org.foundweekends" %% "sbt-bintray" % "0.5.6") addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.3")
Don't forget to remove version.sbt
.
step 2: -SNAPSHOT version
We need to also suppress sbt-dynver a little bit so we get a simpler -SNAPSHOT versions for commits that are not tagged:
ThisBuild / dynverSonatypeSnapshots := true ThisBuild / version := { val orig = (ThisBuild / version).value if (orig.endsWith("-SNAPSHOT")) "2.2.0-SNAPSHOT" else orig }
step 3: recover sbt-bintray settings
We typically use sbt-bintray to publish plugins, so rewire publishTo
back to bintray / publishTo
. Also set publishMavenStyle
to false
.
publishMavenStyle := false, bintrayOrganization := Some("sbt"), bintrayRepository := "sbt-plugin-releases", publishTo := (bintray / publishTo).value,
step 4: remove bintrayReleaseOnPublish overrides
We need to release on publish, so if you have bintrayReleaseOnPublish := false
, in your build.sbt
remove it.
// bintrayReleaseOnPublish := false,
step 5: create a fresh GPG key
Follow the instruction in olafurpg/sbt-ci-release to generate a fresh GPG key.
$ gpg --gen-key gpg (GnuPG/MacGPG2) 2.2.20; Copyright (C) 2020 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Note: Use "gpg --full-generate-key" for a full featured key generation dialog. GnuPG needs to construct a user ID to identify your key. Real name: sbt-avro bot Email address: eed3si9n@gmail.com .... public and secret key created and signed. pub rsa2048 2020-08-07 [SC] [expires: 2022-08-07] 0AC38C6BAD42D5980D8E01A17766C6BECAD5CE7B uid sbt-avro bot <eed3si9n@gmail.com> sub rsa2048 2020-08-07 [E] [expires: 2022-08-07]
Take this down as LONG_ID
:
LONG_ID=0AC38C6BAD42D5980D8E01A17766C6BECAD5CE7B echo $LONG_ID gpg --armor --export $LONG_ID
Submit the public key to http://keyserver.ubuntu.com:11371/.
step 6: Travis CI environment variables
Set up environment variables in the Travis CI setting. Note do NOT limit the access only to master branch since tags are on their own branch.
The following should be made public by toggling "display value in build log":
CI_CLEAN
:clean
CI_RELEASE
:publishSigned
CI_SONATYPE_RELEASE
:version
if sbt-bintray is set to automatically release,bintrayReleaseOnPublish
otherwise
The following should be kept secret (default):
BINTRAY_USER
: Bintray user name.BINTRAY_PASS
: The API key for the Bintray user.PGP_PASSPHRASE
: The randomly generated password you used to create a fresh
GPG key. If the password contains bash special characters, make sure to
escape it by wrapping it in single quotes'my?pa$$word'
, see
Travis Environment Variables.PGP_SECRET
: The base64 encoded secret of your private key that you can
export from the command line like here below
# macOS gpg --armor --export-secret-keys $LONG_ID | base64 | pbcopy # Ubuntu (assuming GNU base64) gpg --armor --export-secret-keys $LONG_ID | base64 -w0 | xclip # Arch gpg --armor --export-secret-keys $LONG_ID | base64 | sed -z 's;\n;;g' | xclip -selection clipboard -i # FreeBSD (assuming BSD base64) gpg --armor --export-secret-keys $LONG_ID | base64 | xclip
step 7: Travis CI YAML
language: scala jdk: openjdk8 stages: - name: test - name: release if: (tag IS present) AND NOT fork jobs: include: # stage="test" if no stage is specified - name: jdk8 jdk: openjdk8 - name: jdk11 jdk: openjdk11 # run ci-release only if previous stages passed - stage: release script: sbt ci-release before_install: - git fetch --tags script: sbt clean test scripted before_cache: - find $HOME/.ivy2/cache -name "ivydata-*.properties" -print -delete - find $HOME/.cache/coursier -name -print -delete - find $HOME/.sbt -name "*.lock" -print -delete cache: directories: - $HOME/.ivy2/cache - $HOME/.cache/coursier - $HOME/.sbt
step 8: tag-based release
When you're ready to publish your plugin, tag the commit and push it.
git tag -a v0.1.0 -m "v0.1.0" git push origin v0.1.0
This should start a release job on Travis CI.
- Login to post comments