Scenario:

Developer wants to start working on a Feature or Bugfix. He pulls latest master branch and creates a branch: feature/ or bugfix/. He starts adding/changing code and commits multiple times. Once done with making changes on local repo, he pushes the changes to Azure DevOps remote repo. Azure DevOps pipeline build the feature branch changes. Once it is successful, he creates pull request to merge the changes into Master. Once pull request builds fine and all reviews are completed, it is good to be merged to Master using Basic Merge (no Fast Forward) Merge type.

At this point, you expect GitVersion to behave as below for the versioning of the master branch:

  • when changes from a  feature branch (i.e. a branch starting by feature/) are merged, it should automatically increment the Minor number.
  • when changes from a bug fix branch (i.e. a branch starting by bugfix/) are merged, it should automatically increment the Patch number.

Versioning Flow expected is as shown below-

Solution:

We will use GitVersion (Mainline Development), Git Hook (prepare-commit-message), Azure DevOps Pipeline, Basic Merge Type  for Pull Request.

Tools needed:

  • Install GitVersion on your build agent – https://gitversion.net/docs/usage/cli/installation

Pre-requisites:

    • Ensure gitversion is working after install. Run ‘gitversion version’ to check its version.
    • Add following step in Azure DevOps build Pipeline (azure_pipeline.yaml)
trigger:
- main
- feature*
- bugfix*

jobs:
- job: BuildAndTest
  workspace:
    clean: all
  pool:
    name: Self-Hosted-Agent
  steps:
  - task: gitversion/execute@0
    inputs:
      useConfigFile: true
      configFilePath: './GitVersion.yml'
  - script: echo current version is $(GitVersion.SemVer)
    displayName: 'Display calculated version'      
  - task: Bash@3
    inputs:
      targetType: inline
      script: echo "##vso[build.updatebuildnumber]$(SemVer)"
    displayName: 'Update build number'

 

Create base version tag 1.0.0 for remote master branch-

 

>> Create GitVersion.yml and save it in master branch

mode: Mainline
branches:
  feature:
    regex: ^feature?[/-]
    source-branches: [‘main’,’master’]
    tag: feat-{BranchName}
  fix:
    regex: bugfix(es)?[/-]
    source-branches: [‘main’,’master’]
    tag: bugfix-{BranchName}
ignore:
  sha: []
merge-message-formats: {}

 

>> Ensure that Master Branch Policy has Build Validation enabled. This ensures that the PullRequest builds successfully before it merges to Master branch.

STEPS:

>> Clone/Pull the latest master branch to your local setup- git pull origin master

>> In your local repository, got to .git/hooks folder and create executable script prepare-commit-message

cd <root repository>/.git/hooks

vi prepare-commit-msg

Add following content to the file and save

-----------------------------------------------------------------------------------------------------------

#!/bin/sh

BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD 2> /dev/null | grep -oE "[a-z]+[/]")

if [ "$BRANCH_NAME" = "feature/" ]; then
sed -i.bak -e "1s/$/[+semver: minor] /" $1
fi

-------------------------------------------------------------------------------------------------------------

chmod +x prepare-commit-msg

Note: This git hook will add [+semver:minor] string at the end of every commit message.

>> Create a feature branch from master – git checkout -b  feature/newfeature

>> Commit couple changes in feature branch and see how git hook adds semver string to the commit message –

>>Push the code to Azure DevOps remote repo- git push origin feature/newfeature

>> At this point Azure DevOps will start the feature build and it will show the version as

>> Create a Pull request to merge these changes to Master branch. Once the PR build finishes, it will show the version as below (Note the minor version is bumped by 1)-

>> Now complete the PR and merge it using Basic Merge (no FF) merge type-

 

 

>> The Pipeline shows the final Master version as 1.1.0

>> Now we can try the same process for Bugfix branch. On your local repo, checkout master branch and sync it with remote master repo-

git checkout master

git pull origin master

>> Create Bugfix branch – git checkout -b bugfix/fix1

>> Add couple of commits to this branch and push it to remote repo-

git commit -m “this is bugfix 1” –allow-empty

git commit -m “this is bugfix 2” –allow-empty

>> These commits to Bugfix branch triggered the git hook but did not add any semver string to commit messages-

>>Push the code to Azure DevOps remote repo- git push origin bugfix/fix1

>> At this point Azure DevOps will start the bugfix build and it will show the version as

 

>> Create Pull Request for this bugfix branch. This will trigger PR build which will display the version like

>> Complete the PR and Merge it to Master branch

>>Finally the master branch version will be 1.1.1

 

Summary:

You can use GitVersion (Mainline Development) with Azure DevOps pipeline to create semantic versions for the artifacts. This works well with Basic Merge type Pull Request. Using git hooks adds the semver string to commit messages to bump the minor version. When semver string is not added the only patch version is bumped up.