-
Notifications
You must be signed in to change notification settings - Fork 24
Description
(Documenting some of my conversations with @outkaj for broader discussion and async. Note this is a discussion related to the upcoming changes switching to sbt-git versioning, not what is currently in master.)
Currently we have sbt-git utilizing it's default versioning schematic, which is almost identical to what git describe does.
In this schematic, if the last release was tagged v1.2.3, you may notice your local version is something like 1.2.3-7-a1b2c3d. This means you are 7 commits past release 1.2.3, and the latest commit was SHA a1b2c3d.
There are two changes we may want to discuss making to this behavior.
Making the versions more SemVer compliant
There is an official specification for allowing pre-release versions in SemVer, and this differs from it a little. Basically it's this:
Major.Minor.Patch-pre(.pre)*+metadataPrimary section: 3 dot separated fields, numeric major, minor, patch numbers (MUST exist, and MUST be numeric). This is the "public API" of SemVer.
Optional pre-release section: Following a
-separator, any number of dot separated fields. What can go in them is more relaxed, alphanumerics are supported, thus you'll often see things like-rc.3or-1oralpha.123. While this portion is less standardized, generally people try to keep them as something that can be ordered.Build metadata: Following a
+, anything goes here that should not affect version ordering.
(For more formal spec with more detail see https://semver.org)
Version ordering: The most notable change is the that in SemVer, 1.2.3-7 would indicate a prerelease of 1.2.3, e.g. something that comes before it.
This is very common with pre-releases in SemVer, and is widely adopted in the wild. (This is what we do with NPM in openlaw-client, as it's the default.)
Metadata: In SemVer, the separator before build metadata field should be +. I don't see this as often in the wild, but it's in the specification. I consider this to be less of an issue but it's there.
Combing the above, the simplest set of changes would mean 1.2.3-7-a1b2c3d would become 1.2.4-7+a1b2c3d.
Neither would affect public releases at all unless we wanted to start pushing these versions to GitHubReleases+BinTray. This is more for our local development currently? Unknown to me is how SBT considers version ordering and how this might affect it.
We could also use a different schematic for pre-release versions if we ever want to actually "release" them, and not care so much about what sbt-git shows locally when doing development. Combining this choice with the SNAPSHOT option below could help enforce that better.
Adding in SNAPSHOT for more cases
Currently sbt-git only appends SNAPSHOT if your local worktree is dirty (e.g. non-commited changes). We may wish to make it so anything not explicitly on a release tag is considered a SNAPSHOT -- and thus can't accidentally be released to BinTray.
(If we did that, but still wanted to release a "pre-release" version at some point, we could just do a semver prerelease git tag within our normal release process and it would work.)
Implementation
sbt-git gives us the flexibility to totally override the versioning schematic as we see fit. So anything we want should be achieveable. An example from someone's blog post where they were doing something fairly similar (I think? I still don't grok sbt-git configuration intuitively. But it still shows it's easy to get under the hood):
val VersionRegex = "v([0-9]+.[0-9]+.[0-9]+)-?(.*)?".r
git.gitTagToVersionNumber := {
case VersionRegex(v,"") => Some(v)
case VersionRegex(v,"SNAPSHOT") => Some(s"$v-SNAPSHOT")
case VersionRegex(v,s) => Some(s"$v-$s-SNAPSHOT")
case _ => None
}