Branch Based Versioning

Branch Based Versioning

Preface

Features

How it Works

Release 1.0.0 and Subsequent Major Versions

Snapshot Anti-Pattern

“The SNAPSHOT value refers to the ‘latest’ code along a development branch, and provides no guarantee the code is stable or unchanging”.

Sharing Work In Progress

Conclusion

Appendix — Implementation Using Git and sbt

# Exits with 1 if their a uncommitted differences
> git diff-index --quiet --exit-code HEAD
# Outputs string of format: lastTag-numCommitsSinceTag-hash
> git describe --long --tags
# Outputs current branch name
git rev-parse --abbrev-ref HEAD
trait BranchType
case object Master extends BranchType
case object Feature extends BranchType
case object HotFix extends BranchType
case object Unknown extends BranchType
case class SemVer(major: Int, minor: Int, patch: Int) {
def incMinor: SemVer = this.copy(minor = minor + 1, patch = 0)
def incPatch: SemVer = this.copy(patch = patch + 1)
def toString: String = s"$major.$minor.$patch"
}
trait PublishAction
case object Unchanged extends PublishAction
case class TagAndPublish(version: String) extends PublishAction
case class PublishOnly(version: String) extends PublishAction
def publishAction(
hasUncommittedChanges: Boolean,
numCommitsSinceTag: Int,
semVer: SemVer,
branchType: BranchType,
branchName: String
): PublishAction = {
val snapAction = PublishOnly(s"$semVer-$branchName-SNAPSHOT")
branchType match {
case _ if hasUncommittedChanges => snapAction
case _ if numCommitsSinceTag == 0 => Unchanged
case Master => TagAndPublish(s"${semVer.incMinor}")
case HotFix => TagAndPublish(s"${semVer.incPatch}")
case _ => snapAction
}
}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store