This repository demonstrates how to use GitVersion to automatically version a C# NuGet package based on your git workflow, eliminating the need for manual version maintenance.
Instead of manually updating version numbers in your project files, GitVersion automatically calculates semantic versions based on:
- Branch names (main, develop, feature, release, hotfix, etc.)
- Git history and commits
- Configured versioning rules
gitversion.yml- GitVersion configuration defining version calculation rules for each branchDirectory.Build.props- MSBuild property file that ensures all projects use GitVersionsrc/MyLibrary/MyLibrary.csproj- C# class library withGeneratePackageOnBuild: trueazure-pipelines.yml- Azure DevOps pipeline showing automated versioning and packaging
Your team currently:
- Manually updates version numbers in project files
- Builds and packages
- Manages version numbers across multiple files
- Push commits to branches following your branching strategy
- GitVersion automatically calculates the version
- Build and pack - version is automatically applied
- NuGet package contains the correct version
The configuration defines version bumping rules:
branches:
main: # Production releases - Patch version bumps
develop: # Main development - Minor version bumps
feature/*: # Feature branches - Minor increments until merged
release/*: # Release branches - Patch increments
hotfix/*: # Hotfixes - Patch version bumpsThe Directory.Build.props file:
- Adds the GitVersion.MsBuild NuGet package to all projects
- Automatically calculates version during the build
- Applies the version to assembly and package metadata
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>This setting ensures:
- NuGet package is created on every build
- Package version matches what GitVersion calculated
- No manual version management needed
- .NET 9 SDK (or whichever version is installed)
- GitVersion (installed via
azure-pipelines.ymlor locally viadotnet tool install -g GitVersion.Tool)
# Install GitVersion tool (one-time)
dotnet tool install -g GitVersion.Tool
# Build the library
dotnet build src/MyLibrary/MyLibrary.csproj --configuration Release
# Alternative: Use msbuild directly
msbuild src/MyLibrary/MyLibrary.csproj -p:Configuration=Release
# View generated NuGet package
ls bin/Release/*.nupkg- Create a new repository in Azure DevOps
- Push this code to the repository
- Create a pipeline from
azure-pipelines.yml - The pipeline will:
- Calculate the version using GitVersion
- Build the project
- Generate the NuGet package with correct version
- Publish as an artifact
This demo uses Git Flow with these branch patterns:
| Branch | Version Bump | Use Case |
|---|---|---|
main |
Patch (1.0.0 → 1.0.1) | Production releases |
develop |
Minor (1.0.0 → 1.1.0) | Integration branch |
feature/* |
Pre-release on develop merge | New features |
release/* |
Patch from Release | Release candidates |
hotfix/* |
Patch from Main | Critical fixes |
# Create a tag for the initial release
git tag v1.0.0
git push origin v1.0.0# On develop branch
git checkout develop
git checkout -b feature/add-division
# Make changes...
git commit -m "Add division method to calculator"
git push origin feature/add-division
# PR → Merge to develop
# Result: v1.1.0-rc.1 (Release Candidate)
# After merge: v1.1.0-prerelease.1git checkout release/1.1.0
git commit -m "Bump version for release"
git push origin release/1.1.0
# Result: v1.1.0-rc.X
# After merge to main: v1.1.0 ✓git checkout -b hotfix/critical-bug
# Make fix...
git commit -m "Fix critical calculation bug"
# Merge to main
# Result: v1.0.1 (Patch bump)
# Also merge back to develop to keep in syncGitVersion exposes many variables for use in your build process:
GitVersion.SemVer = 1.2.3
GitVersion.MajorMinorPatch = 1.2.3
GitVersion.Major = 1
GitVersion.Minor = 2
GitVersion.Patch = 3
GitVersion.PreReleaseTag = (empty if not pre-release)
GitVersion.FullBuildMetaData = ... (full metadata)
After building, check the generated NuGet package:
# Open package with NuGet Package Explorer or:
unzip bin/Release/MyLibrary.*.nupkg -d temp-package
cat temp-package/.nuspecThe .nuspec file will show:
<version>1.2.3</version> <!-- Automatically set by GitVersion -->- No More Manual Versioning: Version is derived from git history automatically
- Consistent Versioning: Same version calculation across local, CI/CD, and production
- Semantic Versioning: Automatically follows SemVer standards (Major.Minor.Patch)
- Branch-Based Bumping: Different branches trigger different version increments
- Reproducible Builds: Same commit = same version, every time
Before (Manual):
- Developer manually edits
MyLibrary.csproj→ version="1.2.3" - Easy to forget updating
- Risk of version mismatches in CI/CD
- Multiple files to maintain
After (GitVersion):
- Commit to branch → GitVersion calculates version → Build uses that version
- No manual updates needed
- Consistent across all builds
- Single configuration in
gitversion.yml