AngryHacker
AngryHacker

Reputation: 61596

How to auto increment the version (eg. “1.0.*”) of a .NET Core project?

In the old .NET framework, you could set the [assembly: AssemblyVersion("1.0.*")] and the compiler would auto-increment the version.

With .NET core, I've tried all sorts of things, but I can't get it to auto-increment.

None of it seems to work. Am I missing something simple? This is just a standard .NET Core Web Project.

Upvotes: 41

Views: 32727

Answers (6)

Jinlye
Jinlye

Reputation: 2234

Here's a way with no extensions and no templating. Put this in the .csproj file of your project file and be happy.

<PropertyGroup>
  <Version>
    1.0
    .$([System.Math]::Floor($([MSBuild]::Divide($([System.DateTimeOffset]::UtcNow.ToUnixTimeSeconds()), 86400))))
    .$([MSBuild]::Divide($([MSBuild]::Modulo($([System.DateTimeOffset]::UtcNow.ToUnixTimeSeconds()), 86400)), 2))
  </Version>
</PropertyGroup>

Your version numbers will then come out looking like 1.0.19901.41107. The build part will increment each day, and the revision part will increment with each two seconds that pass.

Explanation:

Version numbers are in the format major.minor.build.revision

In the example above, I have set major.minor to 1.0 because I want to.

The build and revision parts are derived from System.DateTimeOffset.UtcNow.ToUnixTimeSeconds() which is the number of seconds past the Unix epoch of 00:00:00 UTC on 1 January 1970. For the build number we divide the UnixTimeSeconds by the number of seconds in a day (86400), so our build number is the number of days since the Unix epoch and increments by one each day. By the time we get to 65,534 days past the epoch (65,534 being the maximum allowable for any part of a version number) we are into the year 2149 and we can have a think about a new system of auto versioning. For the revision number we are the number of seconds into today (number of seconds past midnight) divided by two. We divide by two so that we keep below the 65,534 maximum value allowed.

If you want your build number to have an epoch of 1 Jan 2000 (like the old Visual Studio auto-numbering did) instead of 1 Jan 1970, subtract the difference in days between those dates (10,957), so your PropertyGroup Version block looks like this (note the difference to either end of the Build line, with Subtract ... 10957):

<PropertyGroup>
  <Version>
    1.0
    .$([MSBuild]::Subtract($([System.Math]::Floor($([MSBuild]::Divide($([System.DateTimeOffset]::UtcNow.ToUnixTimeSeconds()), 86400)))), 10957))
    .$([MSBuild]::Divide($([MSBuild]::Modulo($([System.DateTimeOffset]::UtcNow.ToUnixTimeSeconds()), 86400)), 2))
  </Version>
</PropertyGroup>

Remember that this (and any other auto-versioning scheme) means that your binaries change with every build, whether there are changes in your code or not. See also deterministic builds in Net Core.

Upvotes: 13

aaron aaron aaron
aaron aaron aaron

Reputation: 189

It is possible to use an extesion called Automatic Versions. Extension Link

You can download it from the page or install it from Visual Studio. Top Menu> Extension> Manage Extensions Install extension

After that, on Top Menu >Tools You will see the option "Automatic Versions Settings" where you will be able to configure it, there are lots of options. By default it increase the version on each build.

Automatic version config

The extension adds two keys to the csproj. Keys added

You can access the version reading the assemby

Reading version

Upvotes: 2

user3163684
user3163684

Reputation: 104

I know this thread is really old, but it's still the first thing that comes up on Google. After reasearching this for too long, I finally found a lightweight solution that let's you use your own custom C# code to define the version.

Basically, use a T4 template to generate the version number (using any code and logic you like) and then read the result into the version property using an MSBuild static method call in your .csproj file.

Step-by-step example:

Create a new file on your project's root level called "version.tt" and insert this code:

<#@ output extension=".txt" #>
<#
int major = 1;
int minor = 2;
int patch = 3;
int build = (int)((DateTime.UtcNow - DateTime.Parse("2020-01-01")).TotalDays);
string output = major + "." + minor + "." + patch + "." + build;
#>
<#= output #>

This should, after saving, immediately create a file named "version.txt" containing a version string like "1.2.3.123" which will be updated automatically by Visual Studio in the future.

Then go into your .csproj and define the version like this:

<Version>$([System.IO.File]::ReadAllText(version.txt))</Version>

Upvotes: 5

I used this article : https://www.codeproject.com/Articles/5260362/NET-Core-Standard-Auto-Incrementing-Versioning

and informations provided here to generate application build number on Year.Month.Day.incremental.

<VersionSuffix>$([System.DateTime]::UtcNow.ToString(yyyy.MM.dd.mmff))</VersionSuffix>
<AssemblyVersion Condition=" '$(VersionSuffix)' == '' ">0.0.0.1</AssemblyVersion>
<AssemblyVersion Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</AssemblyVersion>
<Version Condition=" '$(VersionSuffix)' == '' ">0.0.1.0</Version>
<Version Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</Version>

<GenerateAssemblyFileVersionAttribute >false</GenerateAssemblyFileVersionAttribute >
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<Deterministic>false</Deterministic>
<GenerateAssemblyTitleAttribute>true</GenerateAssemblyTitleAttribute>
<GenerateAssemblyConfigurationAttribute>true</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>true</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>true</GenerateAssemblyProductAttribute>
<GenerateAssemblyCopyrightAttribute>true</GenerateAssemblyCopyrightAttribute>
<GenerateAssemblyVersionAttribute>true</GenerateAssemblyVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>true</GenerateAssemblyInformationalVersionAttribute>

Upvotes: 4

Heinzi
Heinzi

Reputation: 172210

Maytham's solution is fine, but there's also a solution that allows you to both

  • generate the AssemblyInfo from the csproj settings and
  • auto-fill the file version with the (auto-generated) assembly version:

To do this, you just need to suppress auto-generation of the FileVersion attribute with the GenerateAssemblyFileVersionAttribute setting:

<PropertyGroup>
    <AssemblyVersion>1.0.*</AssemblyVersion>
    <GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
    <Deterministic>false</Deterministic>
</PropertyGroup>

(Credit for this technique goes to this answer.)

Upvotes: 9

Maytham Fahmi
Maytham Fahmi

Reputation: 33387

One simple way I did it previously is by reading the current version and increasing it by one, so you get the current version and increment by one using the command line.

With that said, it is possible to do the following for the .net core project:

In your .csproj file, you add the following:

<PropertyGroup>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <Deterministic>false</Deterministic>
</PropertyGroup>

In your code, for instance, in your entry point class, add the following:

using System.Reflection;

[assembly: AssemblyVersion("1.0.*")]

When you build the code, it will get a version like 1.0.8419.40347.

enter image description here

To make more customization, check this article: https://sachabarbs.wordpress.com/2020/02/23/net-core-standard-auto-incrementing-versioning/

In addition, I added this link:

Equivalent to AssemblyInfo in dotnet core/csproj

And I use this exertion as well for Visual Studio:

https://marketplace.visualstudio.com/items?itemName=PrecisionInfinity.AutomaticVersions

Upvotes: 23

Related Questions