Automatic Versioning with GitVersion
GitVersion takes the pain out of manual versioning and arguing with your colleagues by automatically generating version numbers based on your Git history and Semantic Versioning (SemVer) principles. Instead of remembering to bump version numbers manually (and inevitably forgetting), GitVersion analyzes your commits and branches to determine the next logical version number.
This eliminates the classic "oops, forgot to update the version" moments and ensures every build gets a consistent, meaningful version number. When integrated with your CI/CD pipeline, it means every commit-even on feature branches-gets its own unique, traceable version.
INFO
Every commit gets a version number! GitVersion generates unique pre-release versions for every commit on feature branches (e.g., 1.1.0-JIRA-1234-user-login-form.1, then .2, and so on). This means you can create testable builds from any point in your development process.
GitFlow with SemVer
Since any commit in your Git repository could potentially be deployed, GitVersion can calculate a proper SemVer number for any branch and commit. GitVersion provides a configurable way to automate this process while keeping your version numbers SemVer-compliant.
Installation
Install GitVersion locally using Chocolatey:
choco install gitversionOr integrate it into your CI/CD pipeline using these templates:
Configuration
You'll need to add a GitVersion.yml file at the root of your repository to configure GitVersion for your specific workflow. The configuration below is tailored for the trunk-based workflow presented in this documentation, but you may need to adjust it based on your project's constraints.
The complete GitVersion.yml configuration is shown below:
mode: ContinuousDelivery
assembly-file-versioning-scheme: MajorMinorPatchTag
assembly-versioning-scheme: MajorMinorPatchTag
major-version-bump-message: "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\\([\\w\\s-]*\\))?(!:|:.*\\n\\n((.+\\n)+\\n)?BREAKING CHANGE:\\s.+)"
minor-version-bump-message: "^(feat)(\\([\\w\\s-]*\\))?:"
patch-version-bump-message: "^(build|chore|ci|docs|fix|perf|refactor|revert|style|test)(\\([\\w\\s-]*\\))?:"
commit-message-incrementing: Enabled
branches:
main:
label: beta
feature:
regex: ^((task)|(feat(ure)?))[/-](?<BranchName>.{1,25})
label: '{BranchName}'
increment: Minor
source-branches: ["main", "feature"]
mode: ContinuousDelivery
support:
regex: ^support[/-](?<BranchName>.+)
label: RC
increment: Patch
source-branches: ["main"]
mode: ContinuousDelivery
fix:
regex: ^(bug|hot)?fix[/-](?<BranchName>.{1,25})
label: '{BranchName}'
increment: Patch
source-branches: ["main", "support"]
mode: ContinuousDeliverySupport branches and minor/patch digits
The configuration above works pretty well and relies on commit messages (following conventional commits formatting) to bump the right digit. There's a small caveat when using support branches:
In this example, since the commit on the support branch is using the feat: type, GitVersion will bump the minor digit, ending with a potential 1.1.0 future release... Which we could rather see on main.
There are two ways to avoid it:
- Prevent
feat:commits andfeaturebranches on support workflow, and use any other type - After all, you're not supposed to add features on support branches, right? - Set
commit-message-incrementing: Disabledand rely on branch types only. But you'll lose the conventional commit support.