Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to use FAKE to automatically set version numbers based on your Git history. https://www.arthurrump.com/2019/07/19/git-based-versioning-using-fake
#r "paket:
nuget Fake.Core.SemVer
nuget Fake.Core.Target
nuget Fake.DotNet.Cli
nuget Fake.Tools.Git //"
#load "./.fake/build.fsx/intellisense.fsx"
open Fake.Core
open Fake.DotNet
open Fake.Tools
let [<Literal>] repo = "."
let [<Literal>] versionFile = "version"
let [<Literal>] versionPreFile = "version-pre"
let [<Literal>] project = "Project.fsproj"
module GitHelpers =
let isTagged () =
Git.CommandHelper.directRunGitCommand repo "describe --exact-match HEAD"
let previousChangeCommit file =
Git.CommandHelper.runSimpleGitCommand repo ("log --format=%H -1 -- " + file)
let fileChanged file =
Git.FileStatus.getChangedFilesInWorkingCopy repo "HEAD"
|> Seq.exists (fun (_, f) -> f = file)
module AzureDevOps =
let tryGetSourceBranch () =
System.Environment.GetEnvironmentVariable("BUILD_SOURCEBRANCHNAME")
|> Option.ofObj
let updateBuildNumber version =
sprintf "\n##vso[build.updatebuildnumber]%O" version
|> System.Console.WriteLine
module Version =
let withPatch patch version =
{ version with Patch = patch; Original = None }
let appendPrerelease suffix version =
let pre =
match suffix, version.PreRelease with
| Some s, Some p -> PreRelease.TryParse (sprintf "%O-%s" p s)
| Some s, None -> PreRelease.TryParse s
| None, p -> p
{ version with PreRelease = pre; Original = None }
let getCleanVersion () =
Trace.trace "Determining version based on Git history"
let version = File.readAsString versionFile |> SemVer.parse
let height =
if GitHelpers.fileChanged versionFile then
0
else
let previousVersionChange = GitHelpers.previousChangeCommit versionFile
let height = Git.Branches.revisionsBetween repo previousVersionChange "HEAD"
if Git.Information.isCleanWorkingCopy repo then height else height + 1
let pre =
if File.exists versionPreFile
then Some (File.readAsString versionPreFile)
else None
version |> withPatch (uint32 height) |> appendPrerelease pre
let getVersionWithPrerelease () =
let pre =
let branch =
match Git.Information.getBranchName repo with
| "NoBranch" -> AzureDevOps.tryGetSourceBranch ()
| branch -> Some branch
let isClean = Git.Information.isCleanWorkingCopy repo
if isClean && (branch = Some "master" || GitHelpers.isTagged ()) then
None
else
let commit = Git.Information.getCurrentSHA1 repo |> fun s -> s.Substring(0, 7)
let dirty = if isClean then None else Some "dirty"
[ branch; Some commit; dirty ] |> List.choose id |> String.concat "-" |> Some
getCleanVersion () |> appendPrerelease pre
[<AutoOpen>]
module MSBuildParamHelpers =
let withVersion version (param : MSBuild.CliArguments) =
{ param with Properties = ("Version", string version)::param.Properties }
let withNoWarn warnings (param : MSBuild.CliArguments) =
{ param with
NoWarn =
param.NoWarn
|> Option.defaultValue []
|> List.append warnings
|> Some }
let withDefaults version =
withVersion version >> withNoWarn [ "FS2003" ]
Target.create "Build" <| fun _ ->
let version = Version.getVersionWithPrerelease ()
AzureDevOps.updateBuildNumber version
DotNet.build
(fun o -> { o with MSBuildParams = o.MSBuildParams |> withDefaults version })
project
Target.runOrDefault "Build"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.