A minimalistic .NET package for versioning .NET SDK-style projects using Git tags.
Platform support: all platforms supported by .NET SDK-style projects.
Also available as a command line tool for use in any Git repository.
- .NET Core SDK 2.1.300 or later
- libcurl (Linux only)
- Install MinVer.
- Build your project.
Your project will be versioned according to the latest tag found in the commit history.
When you want to release a version of your software, whether it's a pre-release, RTM, patch, or anything else, simply create a tag with a name which is a valid SemVer 2.0 version and build your projects. MinVer will apply the version to the assemblies and packages. (If you like to prefix your tag names, see the FAQ.)
When the current commit is tagged with a version, the tag is used as-is.
When the current commit is not tagged, MinVer searches the commit history for the latest tag. If the latest tag found is a pre-release, MinVer will use it as-is. If the latest tag found is RTM (not pre-release), MinVer will increase the patch number and add default pre-release identifiers, e.g. 1.0.0
becomes 1.0.1-alpha.0
. If no tag is found, the default version 0.0.0-alpha.0
is used.
You will notice that MinVer adds another number to the pre-release identifiers when the current commit is not tagged. This is the number of commits since the latest tag, or if no tag was found, since the root commit. This is known as "height". For example, if the latest tag found is 1.0.0-beta.1
, at a height of 42 commits, the calculated version is 1.0.0-beta.1.42
.
MinVer sets the following custom properties:
MinVerVersion
MinVerMajor
MinVerMinor
MinVerPatch
MinVerPreRelease
MinVerBuildMetadata
Those properties are used to set the following .NET SDK properties, satisfying the official open-source library guidance for version numbers:
Property | Value |
---|---|
AssemblyVersion |
{MinVerMajor}.0.0.0 |
FileVersion |
{MinVerMajor}.{MinVerMinor}.{MinVerPatch}.0 |
PackageVersion |
{MinVerVersion} |
Version |
{MinVerVersion} |
This behaviour can be customised.
Options can be specified as either MSBuild properties or environment variables.
MinVerBuildMetadata
MinVerMinimumMajorMinor
(this is still namedMinVerMajorMinor
in 1.0.0-beta.1, the new name will be used in 1.0.0-beta.2)MinVerTagPrefix
MinVerVerbosity
Note that the option names are case-insensitive.
(With TL;DR answers inline.)
- Can I bump the major or minor version? (yes)
- Can I use my own pre-release versioning scheme? (yes)
- Can I prefix my tag names? (yes)
- Can I use my own branching strategy? (yes)
- Can I include build metadata in the version? (yes)
- Can I use the version calculated by MinVer for other purposes? (yes)
- Can I control the logging verbosity? (yes)
- Can I use MinVer to version software which is not built using a .NET SDK style project? (yes)
- What if the history diverges, and more than one tag is found? (nothing bad)
- What if the history diverges, and then converges again, before the latest tag (or root commit) is found? (nothing bad)
- Why does MinVer fail with
LibGit2Sharp.NotFoundException
? (easy to fix) - Why does MinVer fail with
System.TypeInitializationException
? (easy to fix)
Yes! You probably want to do this because at a point in time, on a given branch, you are working on a MAJOR.MINOR
range, e.g. 1.0
, 1.1
, or 2.0
. The branch could be master
, develop
, a special release branch, a support branch, or anything else.
Before you create the first tag on that branch, interim builds will use the latest tag found in the commit history, which may not match the MAJOR.MINOR
range which the current branch represents. Or if no tag is found in the commit history, interim builds will have the default version 0.0.0-alpha.0
. If you prefer those interim builds to have a version within the current range, specify the range with MinVerMinimumMajorMinor
. For example:
<PropertyGroup>
<MinVerMinimumMajorMinor>1.0</MinVerMinimumMajorMinor>
</PropertyGroup>
MinVer will now use a default version of 1.0.0-alpha.0
.
If you begin to release versions in the 1.0
range from another branch (e.g. a special release branch), update this value to 1.1
, 2.0
, or whatever MAJOR.MINOR
range the current branch now represents.
Note that MinVerMinimumMajorMinor
will be redundant after you create the first tag with same MAJOR.MINOR
. If you don't care that the versions of interim builds before that first tag will have a lower MAJOR.MINOR
, then simply don't specify MinVerMinimumMajorMinor
.
Also note that if the latest tag found in the commit history has a higher MAJOR.MINOR
than MinVerMinimumMajorMinor
, then MinVerMinimumMajorMinor
will be ignored.
Yes! MinVer doesn't care what your pre-release versioning scheme is. The default pre-release identifiers are alpha.0
, but you can use whatever you like in your tags. If your versioning scheme is valid SemVer 2.0, it will work with MinVer.
For example, all these versions work with MinVer:
1.0.0-beta.1
1.0.0-pre.1
1.0.0-preview-20181104
1.0.0-rc.1
Yes! Specify the prefix with MinVerTagPrefix
.
For example, if you prefix your tag names with "v", e.g. v1.2.3
:
<PropertyGroup>
<MinVerTagPrefix>v</MinVerTagPrefix>
</PropertyGroup>
Yes! MinVer doesn't care about branches. It's all about the tags!
That means MinVer is compatible with Git Flow, GitHub Flow, Release Flow, and any other exotic flow.
Yes! Specify build metadata with MinVerBuildMetadata
.
For example, in appveyor.yml
:
environment:
MINVERBUILDMETADATA: build.%APPVEYOR_BUILD_NUMBER%
You can also specify build metadata in a version tag. If the tag is on the current commit, its build metadata will be used. If the tag is on an older commit, its build metadata will be ignored. Build metadata in MinVerBuildMetadata
will be appended to build metadata in the tag.
Yes! You can use any of the properties set by MinVer, or override their values, in a target which runs after MinVer.
For example, for pull requests, you may want to inject the pull request number into the version. E.g. using Appveyor:
<Target Name="MyTarget" AfterTargets="MinVer" Condition="'$(APPVEYOR_PULL_REQUEST_NUMBER)' != ''" >
<PropertyGroup>
<PackageVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch)-PR.$(APPVEYOR_PULL_REQUEST_NUMBER).$(MinVerPreRelease)</PackageVersion>
<PackageVersion Condition="'$(MinVerBuildMetadata)' != ''">$(PackageVersion)+$(MinVerBuildMetadata)</PackageVersion>
<Version>$(PackageVersion)</Version>
</PropertyGroup>
</Target>
Or for projects which do not create NuGet packages, you may want to populate all four parts of AssemblyVersion
. E.g. using Appveyor:
<Target Name="MyTarget" AfterTargets="MinVer">
<PropertyGroup>
<APPVEYOR_BUILD_NUMBER Condition="'$(APPVEYOR_BUILD_NUMBER)' == ''">0</APPVEYOR_BUILD_NUMBER>
<AssemblyVersion>$(MinVerMajor).$(MinVerMinor).$(APPVEYOR_BUILD_NUMBER).$(MinVerPatch)</AssemblyVersion>
</PropertyGroup>
</Target>
Or for projects which do create NuGet packages, you may want to adjust the assembly file version to include the build number, as recommended in the official guidance. E.g. when using Appveyor:
<Target Name="MyTarget" AfterTargets="MinVer">
<PropertyGroup>
<APPVEYOR_BUILD_NUMBER Condition="'$(APPVEYOR_BUILD_NUMBER)' == ''">0</APPVEYOR_BUILD_NUMBER>
<FileVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(APPVEYOR_BUILD_NUMBER)</FileVersion>
</PropertyGroup>
</Target>
Yes! Set MinVerVerbosity
to quiet
, minimal
, normal
(default), detailed
, or diagnostic
. At the quiet
and minimal
levels, you will see only warnings and errors. At the detailed
level you will see how many commits were examined, which version tags were found but ignored, which version was calculated, etc. At the diagnostic
level you will see how MinVer walks the commit history, in excruciating detail.
The verbosity levels reflect those supported by MSBuild and therefore dotnet build
, dotnet pack
, etc. In a future version of MinVer, these verbosity levels will be inherited from MSBuild and MinVerVerbosity
will be deprecated. Currently this is not possible due to technical restrictions related to libgit2.
Yes! MinVer is also available as a command line tool. Run minver --help
for usage. The calculated version is printed to standard output (stdout).
The tag with the higher version is used.
What if the history diverges, and then converges again, before the latest tag (or root commit) is found?
MinVer will use the height on the first path followed where the history diverges. The paths are followed in the same order that the parents of the commit are stored in git. The first parent is the commit on the branch that was the current branch when the merge was performed. The remaining parents are stored in the order that their branches were specified in the merge command.
You may see an exception of this form:
Unhandled Exception: LibGit2Sharp.NotFoundException: object not found - no match for id (...)
This is because you are using a shallow clone. MinVer uses libgit2 to interrogate the repo and libgit2 does not support shallow clones. To resolve this problem, use a regular (deep) clone.
Important: By default, Travis CI uses shallow clones with a depth of 50 commits. To build on Travis CI, remove the --depth
flag.
You may see an exception of this form:
Unhandled Exception: System.TypeInitializationException: The type initializer for 'LibGit2Sharp.Core.NativeMethods' threw an exception. ---> System.DllNotFoundException: Unable to load shared library 'git2-8e0b172' or one of its dependencies.
This is probably because you are running on Linux, and you do not have libcurl installed. See the prerequisites.
Tag by Ananth from the Noun Project.