3
votes

I am trying to configure GitVersion to work with the Release Flow branching strategy.

enter image description here

Basically, I have a mainline Master branch, Release, Feature and Fix branches. The Feature and Fix branches are created from the Master branch and merged back into Master via a pull request. At the end of a sprint, I create a Release branch from Master, which will last till the end of the next sprint, when a new Release branch will be created. The Release branches are not merged back into master. They can even be deleted after a new Release branch has been created. If there's a hotfix needed, it will be developed on a Fix branch created from and merged back into master and then cherry-picked into the current Release branch. I only use git tags for major releases.

Going back to GitVersion, I want to configure it so that the minor version number will increase when I create a new release branch and the patch number to increase when there's a new commit on the release branch (cherry-picked from a Fix branch).

Has anyone done that already and can help me?

2

2 Answers

4
votes

We use flow pretty similar to this one (actually based on it). We do hotfixes right on release branches and we also create pre-release branches before release ones (convenient to have separate channels in octopus-deploy).

After a bit struggle, i ended up with my own PowerShell script. The script is simple and works super fast (near 1 second, unlike GitVersion, which could work 5-15 minutes on our huge repos with big amount of branches). Now, the result looks like that:

It mostly designed to usage with TeamCity, but i think you could easily change it to feet you needs. You can see detailed description of calculation algorithm inside script comments. It also briefly explained on this diagram:

Caveat: In future/topic branches, unlike GitVersion, script uses always growing build counter from teamcity, instead of commits counter. I had to do it, when i found out than our colleges use force pushes(some "clean history" politics), and i can't rely on commits history.

0
votes

I was able to get this to work doing an Anti-Pattern for just one part of release flow. But this is not a big deal if you use Azure DevOps because Microsoft provides a quick and easy way to see if your release branch is ahead/behind the master branch. I have tested this and I am using Release Flow for almost complete automation of versioning besides creating a release branch, and new tag at the end of each sprint. This method also is working well for Semantic Versioning 2.0 of my Nuget Packages, which I use views instead of the suffix tags.

Modified Release Flow

I apologize, and hope it is not too late to help someone out. I have added the yml, and I also have a powershell that I made to handle the release branch naming when cherry picking a HF from master. Note that this powershell step adds a version tag on a release branch so that GitVersion will pick it up.

Powershell: Release {{TeamProject}}/{{RepoName}} with your team project and repo name

- powershell: |
   $url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/build/definitions/$($env:SYSTEM_DEFINITIONID)?api-version=2.0" 
   Write-Host "URL:" $url 
   $definition = Invoke-RestMethod -Uri $url -Headers @{ Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" } 
   Write-Host "Pipeline = $($definition | ConvertTo-Json -Depth 100)"
  displayName: Build Details
  env: 
   SYSTEM_ACCESSTOKEN: $(system.accesstoken)

- powershell: |
   #Get branch version and increment from release branch
   $branchName = "$env:BUILD_SOURCEBRANCHNAME"
   $versionNotIncremented = ($branchName -Split "-")[1]
   [System.Version] $version = "0.0"
   [System.Version]::TryParse($versionNotIncremented, [ref]$version) > Null
   $ver = New-Object System.Version($version.Major,($version.Minor + 1))
   #Create new commit and tag on master
   git checkout master
   $env:GIT_TRACE=1
   git pull
   git commit --allow-empty -m "Create Tag ***NO_CI***"
   git push https://$env:[email protected]/{{TeamProject}}/{{RepoName}}/_git/{{TeamProject}}.Lookup.Api
   $commitId = git log --format="%h" -n 1
   #$commitId = git rev-parse --short HEAD
   git tag $ver $commitId -f -m "Release-$ver"
   git push https://$env:[email protected]/{{TeamProject}}/{{RepoName}}/_git/{{TeamProject}}.Lookup.Api $ver -f --porcelain
  displayName: 'Update Version for Upcoming Release'
  condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/releases/'))
  env: 
   SYSTEM_ACCESSTOKEN: $(system.accesstoken)

GitVersion Yaml:

assembly-informational-format: '{FullSemVer}'
mode: Mainline
branches:
  master:
    tag: ''
    increment: Patch
    prevent-increment-of-merged-branch-version: true
    track-merge-target: false
    regex: master|releases?[/-]
    tracks-release-branches: false
    is-release-branch: false
  feature:
    mode: ContinuousDelivery
    tag: useBranchName
    increment: Inherit
    prevent-increment-of-merged-branch-version: false
    track-merge-target: false
    regex: features?[/-]
    tracks-release-branches: false
    is-release-branch: false
  pull-request:
    mode: ContinuousDelivery
    tag: PullRequest
    increment: None
    prevent-increment-of-merged-branch-version: false
    tag-number-pattern: '[/-](?<number>\d+)[-/]'
    track-merge-target: false
    regex: (pull|pull\-requests|pr|[0-9]+)[/-]
    tracks-release-branches: false
    is-release-branch: false
  hotfix:
    mode: ContinuousDelivery
    tag: beta
    increment: Patch
    prevent-increment-of-merged-branch-version: false
    track-merge-target: false
    regex: hotfix(es)?[/-]
    tracks-release-branches: false
    is-release-branch: false
  develop:
    mode: ContinuousDeployment
    tag: unstable
    increment: Patch
    prevent-increment-of-merged-branch-version: false
    track-merge-target: true
    regex: dev(elop)?(ment)?$
    tracks-release-branches: true
    is-release-branch: false
ignore:
  sha: []