Instantly share code, notes, and snippets.

Embed
What would you like to do?
Use git tag information to version nuget packages with FAKE scripts
open Fake
open Fake.Git
module GitFlowVersioning =
// ----------------------------------------------
// START: Version from git tag
// ----------------------------------------------
type ReleaseType = Release | Beta | Alpha | ReleaseCandidate
/// Get the SHA1 for the last available tag or None, if not tags set in repository
let getShaFromLastTag =
let gitLastTagShaCommand = "rev-list --tags --max-count=1"
let ok,msg,error = runGitCommand "" gitLastTagShaCommand
if ok then Some msg.[0] else None
/// Get the tag name for the given SHA1 commit or None, if no tag for this commit
let getTagForCommit sha =
let gitLastTagCommand = sprintf "describe --tag %s" sha
let ok,msg,error = runGitCommand "" gitLastTagCommand
if ok then Some (msg |> Seq.head) else None
/// Get version from the last tag in git or "0.0.0" version as fallback
let getLastTag prefix =
let fallbackVersion = "0.0.0"
let tagVersion =
match getShaFromLastTag with
| Some s ->
match getTagForCommit s with
| Some ss -> ss
| None _ -> prefix + fallbackVersion
| None _ -> prefix + fallbackVersion
let pattern =
if isNullOrEmpty prefix then "^" else sprintf "(?<=^%s){1}" prefix
let pattern = sprintf "%s%s" pattern "(\d+\.\d+){1}(\.\d+){0,2}$"
let versionRegex = System.Text.RegularExpressions.Regex(pattern)
match versionRegex.Match tagVersion with
| s when s.Success -> SemVerHelper.parse s.Value
| _ -> SemVerHelper.parse fallbackVersion
/// Release state
let getReleaseState =
let currentBranch = environVarOrDefault "CI_CURRENT_BRANCH" (Git.Information.getBranchName "")
match currentBranch with
| "master" -> Release
| "develop" -> Beta
| s when startsWith s "hotfix/" -> ReleaseCandidate
| s when startsWith s "release/" -> ReleaseCandidate
| _ -> Alpha
/// Get the version for assembly (+1 on patch level, if not on master)
let getAssemblyVersion prefix buildCounter =
let version = getLastTag prefix
let patch =
match getReleaseState with
| Release -> version.Patch
| _ -> version.Patch + 1
sprintf "%d.%d.%d.%s" version.Major version.Minor patch buildCounter
/// Get the version for nuget package (+1 on patch level, if not on master)
let getNugetVersion prefix buildCounter =
let version = getLastTag prefix
let releaseState = getReleaseState
let patch =
match releaseState with
| Release -> version.Patch
| _ -> version.Patch + 1
match releaseState with
| Release -> sprintf "%d.%d.%d" version.Major version.Minor patch
| s -> sprintf "%d.%d.%d-%A%s" version.Major version.Minor patch s buildCounter
/// TRUE: stable realease
let isStableRelease =
match getReleaseState with
| Release -> true
| _ -> false
// ----------------------------------------------
// END: Version from git tag
// ----------------------------------------------
@WebDucer

This comment has been minimized.

Copy link
Owner

WebDucer commented Apr 30, 2016

Usefull for working on packages with git-flow branching model.

With CI_CURRENT_BRANCH environment variable you can set the current branch, if your CI server only support headless checkout (like GitLab CI do).

Examples

X - Build counter from CI system

  • Tag: 0.1 on developer branch
    • getAssemblyVersion: 0.1.1.X
    • getNugetVersion: 0.1.1-BetaX
  • Tag: 0.2 on master branch
    • getAssemblyVersion: 0.2.0.X
    • getNugetVersion: 0.2.0
  • Tag: 0.3.7 on feature branch
    • getAssemblyVersion: 0.3.8.X
    • getNugetVersion: 0.3.8-AlphaX
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment