This plugin basically just exists to allow me to more conveniently setup my baseline SBT configuration, which has evolved somewhat over the years, and is also becoming quite unwieldy when solely represented in giter8 format. If you want to use this plugin with a new project, you should probably start from that template.
If you generally agree with my opinions on how projects should be set up, though, then this is probably a really excellent plugin to base on! Between this plugin and my giter8 template, you can get a new Scala project up and running and publishing to Sonatype within about five minutes. As an example, check out this quick screencast:
TLDR, it's really really easy.
Put one of the following into your plugins.sbt
:
// for stock functionality (no publication defaults)
addSbtPlugin("com.codecommit" % "sbt-spiewak" % "<version>")
// publishing to sonatype
addSbtPlugin("com.codecommit" % "sbt-spiewak-sonatype" % "<version>")
Then, in your build.sbt
, make sure you set a value for baseVersion
, organization
, publishGithubUser
and publishFullName
:
ThisBuild / organization := "com.codecommit"
ThisBuild / baseVersion := "0.1"
ThisBuild / publishGithubUser := "djspiewak"
ThisBuild / publishFullName := "Daniel Spiewak"
Or something like that.
If you have a multi-module build and need a subproject to not publish (as is commonly done with the root
project), enable the NoPublishPlugin
. For example:
lazy val root = project
.aggregate(core, sonatype)
.in(file("."))
.settings(name := "root")
.enablePlugins(NoPublishPlugin)
If you would like your releases to be published by your CI process in GitHub Actions, rather than locally, you will probably benefit from the SonatypeCiReleasePlugin
plugin (part of sbt-spiewak-sonatype). This makes some assumptions about your secrets and general build configuration, applies the settings to the sbt-github-actions-generated workflow, and generally takes care of everything for you.
To use, add the following to the root level of your build.sbt:
enablePlugins(SonatypeCiReleasePlugin)
Then, generate the initial GitHub Actions in .github/workflows
with the githubWorkflowGenerate
SBT task (see tasks for sbt-github-actions).
After that, configure the following encrypted secrets within GitHub Actions (go to Settings -> Secrets -> New secret; see GitHub Encrypted Secrets documentation for more detail):
SONATYPE_USERNAME
SONATYPE_PASSWORD
PGP_SECRET
You can obtain the PGP_SECRET
by running gpg --export-secret-keys | base64
. Please make sure that this key is not password protected in the export (GitHub Actions itself will encrypt it).
Once this is done, decide whether you would like snapshots to be published on every master build. By default, releases will only be published on version tags. If you wish to override this, set the following:
ThisBuild / spiewakCiReleaseSnapshots := true
If you do set the above to true
, you should probably also make sure to set your primary branch as below:
ThisBuild / spiewakMainBranches := Seq("main")
You can also simply add additional branches, if you're publishing snapshots on more than one at a time.
With all of these steps out of the way, you should have some nice, reliable, CI-driven releases going forward!
Caveat: If you are publishing snapshots on your primary branch, you will need to be careful to ensure that new tags are fully built on the primary branch before you push the tag to the upstream. The reason for this is the fact that tags are visible to the primary branch builds, meaning that if you push a new commit to master and a tag which points to it, that commit and tag will build and release under the same name simultaneously. The workaround is to push master, wait for the snapshot release to complete, and then push the tag. I'll get around to fixing this someday...
- Baseline plugin setup
- coursier
- sbt-travisci
- sbt-git
- With sensible git versioning settings
- Also with fixed
git-status
stuff
- sbt-header
- Assumes Apache 2.0 license
- sbt-sonatype
- With fixed snapshot publication URLs
- sbt-gpg
- sbt-mima
- Infers previous versions by using git tags
- Automatically runs on
ci
andrelease
- sbt-explicit-dependencies
unusedCompileDependenciesTest
runs onci
- disabled by
NoPublishPlugin
- filters Scala.js and Dotty standard libraries
- Sensibly opinionated scalac settings
- Including
-Ybackend-parallelism
where supported
- Including
- SI-2712 fix across scala versions (dating back to 2.10)
- kind-projector (Scala 2 only)
- better-monadic-for (Scala 2 only)
release
andci
command aliases- Performs sonatype release steps
NowarnCompatPlugin
- Adds support for
@nowarn
to Scala 2.11, 2.12, and 2.13.1 via Silencer. - Adds scala-collection-compat to the classpath for versions that need Silencer. Opt out by configuring
nowarnCompatAnnotationProvider
.
- Adds support for
SonatypeCiReleasePlugin
- Prescriptive defaults for projects which want CI releases
You will need to define the following settings:
ThisBuild / homepage := Some(url("https://github.com/djspiewak/sbt-spiewak"))
ThisBuild / scmInfo := Some(ScmInfo(url("https://github.com/djspiewak/sbt-spiewak"),
"[email protected]:djspiewak/sbt-spiewak.git"))
You may consider overriding any of the following keys, which are hard-coded to defaults that I believe are reasonable:
licenses
(defaults to Apache 2.0)developers
(defaults to just yourself, using thepublishFullName
andpublishGithubUser
)startYear
(defaults to 2020)endYear
(defaults to empty; set this if you want a range of years for your copyright headers)strictSemVer
(defaults totrue
)- When set to
true
, it disallows breaking binary compatibility in any release which does not increment the major component unless the major component is0
(i.e. semantic versioning). Many Scala projects break binary compatibility in minor releases, such as Scala itself. This scheme is sometimes referred to as "scala ver". SettingThisBuild / strictSemVer := false
will relax the MiMa compatibility checks and allow you to perform such breakage if desired.
- When set to