Skip to content

Essential: Installation

jvican edited this page Oct 6, 2017 · 24 revisions

Index

  1. Motivation: First time here? Understand what sbt-release-early does and how.
  2. Requirements: Wanna install? Make sure your system is set up.
  3. Installation: You know everything and just want to install it? Come here.
  4. Use: Check instructions on how to use the plugin.
  5. Configuration: click on the link, you're on the wrong page.

Motivation

In a nutshell

Every time you push a commit to a branch, sbt-release-early will release an artifact with a version derived from the git metadata (version and distance from last git tag). For example, 0.3.0+10-4f489199, where 10 is the distance and the suffix is the commit hash.

Every time you push a tag to a branch, sbt-release-early will release an artifact with that tag version. This feature is usually used to cut final releases, for example, v0.1.0.

Why this way

sbt-release-early takes a distinct approach to releases.

While some projects decide to declare versions in sbt files, sbt-release-early derives the versions of your project from your git tags. This has several benefits:

  1. Reproducibility.
  2. Tag uniqueness. Git prevents you from trying to release a version twice by mistake.
  3. No need to push commits to bump up the versions of your projects.
  4. The tag history shows all the released versions over the time of a project.

These properties reduce the complexity of handling releases significantly. The repository revision history becomes the ultimate truth and build-related tasks are easy to set up -- no need to resolve the latest version or scrap the library version from its sbt build.

Note that the tag uniqueness property only holds if you don't delete an already pushed tag. This is so bad practice that we assume people are sensible and don't do it.

Version schema

The version lingo is extracted from the Semantic Versioning document.

This documentation and this plugin assumes that:

  • Version numbers are final if they only consist of a MAJOR, MINOR and PATCH VERSION. For example, 1.0.1, 2.4.98 and 10.1.6 are final releases.
  • Any other version number that contains build metadata or qualifiers like RC, beta or alpha are considered SNAPSHOTs even if they lack the -SNAPSHOT suffix. For example, 0.3.0+10-4f489199, 8.9.1-1f43aa21 or 1.0.0-RC are snapshots.

Note that the snapshot does not have a precise and commonly accepted definition. sbt-release-earlys definition differs from the common understanding of snapshot versions in the Scala community.

sbt-release-early considers the most literal definition of snapshot: it's a release that mirrors the codebase at a given point of time and whose artifacts could not provide the same guarantees as final releases. These guarantees are established by library authors.

Why not regular -SNAPSHOTs?

Snapshots have important shortcomings:

  1. They are not reproducible: downstream users can get different snapshot releases depending on the time they resolve/update them.
  2. Their resolution times are slower: build tools have to check all artifacts in all resolvers to choose the appropriate version.

The use of snapshots is no longer justified with sbt-release-early and sbt plugins like sbt-dynver that derive automatic versions from git invariants. sbt-release-early keeps your builds faster and more reproducible.

Differences with sbt-release

I already use the popular sbt-release plugin to create my own release pipeline. Why should I use sbt-release-early instead? Why have you spent time in this release plugin?

In my view, sbt-release makes ad-hoc design decisions that:

  • Complicate its use and understanding;
  • Require longer time to master; and,
  • Makes it difficult to maintain and add more feature.

We've created sbt-release-early to become the de-facto releasing plugin in the sbt community. For that, we've focused on simplicity and extensibility. That's why we've redesigned releasing in sbt compared to sbt-release.

Advantages over sbt-release

  • sbt-release-early can be invoked only for concrete projects and aggregation works out of the box.
  • sbt-release-early is easier to learn and customize. It reuses the task graph and does not require an ad-hoc dsl to specify the release pipeline. This alone eases the learning curve considerably.
    • Do you want to run a task after publish? Use dependsOn.
    • Do you want to run a task before publish? Use triggeredBy.
    • Do you want to change one pipeline step? No need to copy-paste all the sbt-release default steps.
  • sbt-release-early is only about releasing. sbt-release tries to create a release pipeline that aggregates lots of complicated steps (running tests, reading git tags, et cetera). Some drawbacks that come to mind:
    • You cannot reuse your release pipeline without waiting for all these steps to finish.
    • Running tests is insecure in CI servers.
  • sbt-release-early encourages remote releases in CI servers, while sbt-release's design is biased towards local releases (requiring users' input on several release steps).
  • sbt-release-early abstracts over whichever publisher you want to release to. sbt-release forces you to change the underlying publish sbt plugins by hand every time.
  • sbt-release-early has an opinionated handling of versions (delegating in sbt-dynver).
  • sbt-release-early is actively maintained by the Scala Center and some excellent contributors. sbt-release is rarely updated.

Disadvantages over sbt-release

  • sbt-release-early cannot suggest a version. The version is always set from the VCS environment.

Requirements

To use sbt-release-early, you must:

  1. Use git and have it executable both locally and in the CI (required by sbt-dynver).
  2. Have a GPG key and publish it to a PGP server like pgp.mit.edu.

Don't you fulfill these requirements?

  1. Install git.
  2. Make git executable (for all the platforms).
  3. Read the guide to create and publish your own gpg key.

Dependencies

This plugin depends on the following sbt plugins:

If you already depend on them, remove them from your plugins.sbt file. The addSbtPlugin line above will bring them in automatically.

Installation

Add the plugin to your build with:

// defined in project/plugins.sbt
addSbtPlugin("ch.epfl.scala" % "sbt-release-early" % "1.2.0")

To find out what's the last available stable release, check the tag releases in this repository.

Depend on an on-merge release

These are the last published versions to Maven Central.

Note that on-merge releases have no binary or source compatibility guarantees. They include changes that have been merged from pull requests and had not yet been as scrutinized as possible.

Use

  1. Make sure you fulfill all the requirements.
  2. Make sure you understand what the plugin does and how.
  3. Make sure your sbt build is set up correctly (by reading the Configuration).
  4. Make sure your CI server is ready (by reading the How To's on the sidebar).
  5. Run sbt releaseEarly in your CI and have fun.