XDev.EasyVersion.Core
1.0.0.1
dotnet add package XDev.EasyVersion.Core --version 1.0.0.1
NuGet\Install-Package XDev.EasyVersion.Core -Version 1.0.0.1
<PackageReference Include="XDev.EasyVersion.Core" Version="1.0.0.1" />
paket add XDev.EasyVersion.Core --version 1.0.0.1
#r "nuget: XDev.EasyVersion.Core, 1.0.0.1"
// Install XDev.EasyVersion.Core as a Cake Addin #addin nuget:?package=XDev.EasyVersion.Core&version=1.0.0.1 // Install XDev.EasyVersion.Core as a Cake Tool #tool nuget:?package=XDev.EasyVersion.Core&version=1.0.0.1
This is Still a Work in Progress
Table of Contents
- Introduction
- Support Files
- dotnet Tool ##todo: update ToC!
Introduction
Automatically versioning builds while maintaining a semantic versioning scheme can get somewhat complicated quickly when you try to make an approach flexible enough to accommodate different versioning and naming schemes. This repo contains a collection of tools to help you build reliable CI-CD pipelines with minimal environment-specific scripts needed. The only real requirement is the .Net 6 or newer runtime for the CLI tool, or you can use a Cake build to import the XDev.EasyVersion.Core
or other packages directly.
The versioning concept encapsulated in this project is that all releasable products should have a unique version number that is never duplicated by separate builds. Also, build numbers are generated as part of a CI/CD pipeline process and not manually assigned. These 2 rules allows us to generate human readable unique build numbers applied in a Symantic Versioning scheme without having to worry about accidental duplication while building a variety of code bases, such as Nuget packages and multi platform application packages such as Xamarin or Maui apps, as well as desktop apps.
Support Files
Build Information.txt
This file is responsible for specifying the information needed to generate version numbers for a given repo, and must be included in the repo, by default the tool looks in the root source directory for this file.
/// ***********************************************************************************
/// ** The Release Pipeline will use this file to auto-version and track releases. **
/// ***********************************************************************************
/// <summary>
/// Specifies the name of the package to release.
/// This tag and value is required.
/// </summary>
/// <example>
/// [Package Name]
/// My.Package
/// </example>
[Package Name]
My.Package
/// <summary>
/// Specifies the 3 octet version of the release. This is the versioning schema used by Nuget.
/// This tag and value is required.
/// </summary>
/// <example>
/// [Release Version]
/// 1.2.3
/// </example>
[Release Version]
1.0.1
The Build Information.txt
file provides 2 key pieces of information, the Package Name and Release Version in semantic form (Major.minor.Patch) and is manually incremented as desired by the repo owner.
Package Name
This is the public name of the package. Whether we are building a Nuget repo, iOS or Android App, or desktop application, this is the product name that's included with the Release Metadata.
Release Version
This is the Major.Minor.Patch Semantic version of the package. This notation comes from the Nuget guidelines, it also allows a CI-CD Pipeline to auto-increment the 4th octet used for file versioning. You can use any 3 octet versioning scheme you choose such as Major.Minor.Patch, Major.Minor.Revision, Year.Quarter.Patch, etc. Just keep in mind that modifying Build Information.txt
is required to update any of the first 3 octets and fits well into a Git-Flow branch and merge strategy with a CI-CD DevOps process running auto builds on one or more of the long-lived branches, like dev
and main
or whatever you may call them.
Release History.json
This file is resident separate from the source code and keeps track of all builds and releases for a particular Repo. The presence of this file is what gives a build process the ability to generate unique version numbers that are also easy to read without resorting to some date-code or long hash code as part of a version number. A very popular option for CM of build history and build code itself is to keep it in the same repository as the source code. This is a very simple and easy option, if one does not mind "mixing" build code and source code, and if your dev team is also responsible for DevOps. However, this does introduce certain difficulties, such as the fact that any build that updates the history, now must make a commit back to the source repo, potentially causing a recursive build scenario unless one excludes the history file/directory from auto-build triggers, as well as introducing un-reviewed changes to otherwise protected branches.
In the opinion of the author, below are some better CM options because they allow separation of concerns between CI-CD and the source code:
- On a local build machine, simply keep this file in a location accessible by the build agents (runners)
- Keep this file in a git sub-repository and add steps to your build(s) to pull the correct sub-repo at the start of the build, and only commit changes to the sub repo responsible for the build history
- If you are using Azure Dev ops, Universal Packages are a very simple way to keep a versioned artifact between builds, including code coverage results or our
Release History.json
file. - Lastly, if none of the other options are available or suit you,
XDev.EasyVersion.Nuget.History
can provide a tool that is almost as easy as ADO's Universal Packages, but using NuGet as the packaging tool.
The below mentioned XDev.EasyVersion.exe
is capable of retrieving specific release information as well as rolling build number, generating context-specific version numbers from the semantic version including the build, and adding the new build to the history file: Release History.json
.
##todo: add buildinfo.txt details...
dotnet Tool Install
To install as a local tool, see instructions here to setup a local tool store, then install the package from nuget.org:
dotnet new tool-manifest
.
.
.
dotnet tool install XDev.EasyVersion
To install as a global tool (admin or root permissions required, so this is probably not a good option for pipelines):
dotnet tool install --global XDev.EasyVersion
To install a prerelease version, include --prerelease
and possibly --allow-downgrade
dotnet Tool Usage
XDev.EasyVersion
To set up EasyVersion via a command-line tool during a CI or CD pipeline, pass in a Package Name (i.e. "My.Custom.Package"
), 3 octet Release Version (i.e. 1.2.3), and Drop Type (i.e. alpha, beta, etc for a pre-release semantic version with tag format) (optional).
For a pre-Release build the options might look like:
dotnet easyVersion roll --PackageName=Foo.Bar --ReleaseVersion=1.2.3 --DropType=beta --ReleaseHistoryJsonPath="./Build Tracking/Release History.json"
With the output:
Package Name : Foo.Bar
Semantic Version : 1.2.3
Build : beta043
Package Version : 11.2.3-beta043
File Version : 11.3.3.43
Android Version Code : 110203043
Build Date : 2020-06-01T16:30:03.9423513-05:00
For a Release build the options might look like:
Bloomerang.Build.Versioning.exe roll --PackageName=Foo.Bar --ReleaseVersion=1.2.3 --ReleaseHistoryJsonPath="./Build Tracking/Release History.json"
With the output:
Package Name : Foo.Bar
Semantic Version : 1.2.3
Build : 43
Package Version : 11.2.3
File Version : 11.3.3.44
Android Version Code : 110203044
Build Date : 2020-06-01T16:30:03.9423513-05:00
- Note: the build number is continuous and monotonically increases regardless of whether the build is pre-release (tag) or release (no tag) supplied, so it is possible to have the following version result from a series of builds:
- 1.2.3-rc001
- 1.2.3.2
- 1.2.3-rc003
It is presumed that one would manually update the Major, Minor, or Patch version in BuildInfo.txt
if you wish to avoid the scenario of publishing a pre-release version newer than the last release version. You are free to manage how/when to roll the Major, Minor, Patch versions as best fits your project or preferred conventions.
Depending on where in your build you save the Release History.json
in a pipeline, you may have "skipped" build numbers, if you save the Release History.json
before ensuring that all build steps have succeeded. Again, you are in control of when you store the Releas History.json
file in your build so you can "discard" failed build numbers, or re-use a build number until the build succeeds.
Android VersionCode limit
Per google's dev docs, the max VersionCode is 2100000000. This tool may generate a value greater than this. Version your app | Android Studio | Android Developers
What this means is that this tool can produce an invalid AndroidVersion code, if Minor > 99, and/or if Patch > 99 in a semantic version like 12.100.222.3
would produce a versionCode of 12100222003
, which is > 2100000000
, the max-supported value by Google.
There is an issue to help mitigate this scenario by checking and appending "-invalid"
to the output, but this should be a rare and easily avoided situation.
To avoid this, limit input semantic versions to the pattern MMM.mm.pp.bbb
when consuming Android-VersionCode generation by this tool, per the previous example.
EasyVersionRoll.ps1
This powershell script provides a simple way to read the Build-Info.txt
file for Major.Minor.Patch version info, supply input to the cli tool, and then store the tool's output to ADO pipeline variables for use in later steps, such as setting version info in .csproj
files or ``AssemblyInfo.cs` files before building.
- Currently only ADO is supported with this script, but you could easily modify it for different build hosting environments.
Calling the versioning script might look like this for a pre-Release build:
EasyVersionRoll.ps1 -buildInfoPath "SomeDir\BuildInfo.txt" -easyVersionToolPath "SomeDir\XDev.EasyVersion.exe" -dropType "beta"
The script will read the Package Name and Release Version from BuildInfo.txt
, call XDev.EasyVersion.exe
with the parameters set. It will then process the return text from XDev.EasyVersion.exe
at set the Pipeline AndroidVersionCode, FileVersion, and PackageVersion variables.
The ADO pipeline variables that are set and available for later tasks in the pipeline:
- AndroidVersionCode
- FileVersion
- PackageVersion
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- CommandLineParser (>= 2.7.82)
- System.Text.Json (>= 7.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.0.1 | 117 | 6/17/2024 |
0.0.1-alpha010 | 134 | 4/26/2024 |
0.0.1-alpha009 | 177 | 4/16/2024 |
0.0.1-alpha008 | 107 | 4/4/2024 |
0.0.1-alpha007 | 101 | 4/3/2024 |
0.0.1-alpha006 | 112 | 3/26/2024 |
0.0.1-alpha005 | 129 | 3/18/2024 |
Pre-release for testing and dog-fooding.