I have spent the better part of a few hours trying to find a way to auto-increment versions in a .NETCoreApp 1.1 (Visual Studio 2017).
I know the the AssemblyInfo.cs
You can use a MSBuild property function to set the version suffix based on current date:
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<VersionSuffix>pre$([System.DateTime]::UtcNow.ToString(yyyyMMdd-HHmm))</VersionSuffix>
</PropertyGroup>
This will output a package with a name like: PackageName.1.0.0-pre20180807-1711.nupkg.
More details about MSBuild property functions: https://docs.microsoft.com/en-us/visualstudio/msbuild/property-functions
The Version
is formed from the combination of VersionPrefix
and VersionSuffix
, or if VersionSuffix
is blank, VersionPrefix
only.
<PropertyGroup>
<VersionPrefix>1.0.0</VersionPrefix>
</PropertyGroup>
I accepted the above answer because @Gigi is correct (as of now) but I was annoyed and came up with the following PowerShell Scripts.
First I have the script in my solution folder (UpdateBuildVersion.ps1):
#Get Path to csproj
$path = "$PSScriptRoot\src\ProjectFolder\ProjectName.csproj"
#Read csproj (XML)
$xml = [xml](Get-Content $path)
#Retrieve Version Nodes
$assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion
$fileVersion = $xml.Project.PropertyGroup.FileVersion
#Split the Version Numbers
$avMajor, $avMinor, $avBuild = $assemblyVersion.Split(".")
$fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".")
#Increment Revision
$avBuild = [Convert]::ToInt32($avBuild,10)+1
$fvBuild = [Convert]::ToInt32($fvBuild,10)+1
#Put new version back into csproj (XML)
$xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild"
$xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild"
#Save csproj (XML)
$xml.Save($path)
I added this to csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyVersion>0.0.1</AssemblyVersion>
<FileVersion>0.0.1</FileVersion>
<PreBuildEvent>powershell.exe –NonInteractive –ExecutionPolicy Unrestricted -command "& {$(SolutionDir)UpdateBuildVersion.ps1}"</PreBuildEvent>
</PropertyGroup>
</Project>
Even through its set to be a PreBuildEvent, the fact is the version numbers do not get updated until AFTER the file has been loaded into memory so the version number will not reflect until the next build. In fact, you could change it to a PostBuildEvent and it would have the same effect.
I also created the following two scripts: (UpdateMinorVersion.ps1)
#Get Path to csproj
$path = "$PSScriptRoot\src\ProjectFolder\ProjectName.csproj"
#Read csproj (XML)
$xml = [xml](Get-Content $path)
#Retrieve Version Nodes
$assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion
$fileVersion = $xml.Project.PropertyGroup.FileVersion
#Split the Version Numbers
$avMajor, $avMinor, $avBuild = $assemblyVersion.Split(".")
$fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".")
#Increment Minor Version - Will reset all sub nodes
$avMinor = [Convert]::ToInt32($avMinor,10)+1
$fvMinor = [Convert]::ToInt32($fvMinor,10)+1
$avBuild = 0
$fvBuild = 0
#Put new version back into csproj (XML)
$xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild"
$xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild"
#Save csproj (XML)
$xml.Save($path)
(UpdateMajorVersion.ps1)
#Get Path to csproj
$path = "$PSScriptRoot\src\ProjectFolder\ProjectName.csproj"
#Read csproj (XML)
$xml = [xml](Get-Content $path)
#Retrieve Version Nodes
$assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion
$fileVersion = $xml.Project.PropertyGroup.FileVersion
#Split the Version Numbers
$avMajor, $avMinor, $avBuild = $assemblyVersion.Split(".")
$fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".")
#Increment Major Version - Will reset all sub nodes
$avMajor = [Convert]::ToInt32($avMajor,10)+1
$fvMajor = [Convert]::ToInt32($fvMajor,10)+1
$avMinor = 0
$fvMinor = 0
$avBuild = 0
$fvBuild = 0
#Put new version back into csproj (XML)
$xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild"
$xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild"
#Save csproj (XML)
$xml.Save($path)
You could do it like below, within the csproj file. I didn't figure out the math. I found that somewhere else on Stack Overflow, but this works and will give you something similiar to 1.0.* for version.
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<FileVersion>1.0.$([System.DateTime]::UtcNow.Date.Subtract($([System.DateTime]::Parse("2000-01-01"))).TotalDays).$([System.Math]::Floor($([MSBuild]::Divide($([System.DateTime]::UtcNow.TimeOfDay.TotalSeconds), 1.32))))</FileVersion>
<Version>1.0.$([System.DateTime]::UtcNow.Date.Subtract($([System.DateTime]::Parse("2000-01-01"))).TotalDays)</Version>
</PropertyGroup>
These values are now set in the .csproj
file:
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
<AssemblyVersion>1.0.6.0</AssemblyVersion>
<FileVersion>1.0.6.0</FileVersion>
<Version>1.0.1</Version>
</PropertyGroup>
These are the same values you see if you go in the Package tab in the project settings. While I don't think you can use *
to autoincrement the version, what you can do is introduce a post-processing step that replaces the versions for you (e.g. as part of your continuous integration).
I made a simple CLI tool for setting .csproj .NET Core version strings here. You can combine it with tools like GitVersion for automatic version bumping during CI builds, if that's what you're after.
What worked for me was to define Patch and Revision using a PropertyGroup
, then you can just use this variables for version (and prefix if needed). Version numbers must be short numbers so I use YearMonth for Patch, and MinutesOfDay for Revision. Add this lines to your csproj file:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VersionMajor>0</VersionMajor>
<VersionMinor>9</VersionMinor>
<VersionPatch Condition="'$(VersionPatch)' == ''">$([System.DateTime]::UtcNow.ToString("yyMM"))</VersionPatch>
<VersionRevision Condition="'$(VersionRevision)' == ''">$([System.DateTime]::UtcNow.TimeOfDay.TotalMinutes.ToString("0"))</VersionRevision>
</PropertyGroup>
<PropertyGroup>
<OutputType>...</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Title>Software Title</Title>
<Description>...</Description>
<Authors>...</Authors>
<Version>$(VersionMajor).$(VersionMinor).$(VersionPatch).$(VersionRevision)</Version>
</PropertyGroup>
....
</Project>
It can be achive in a generic way making use of Directory.build.props
file. More info here: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2019
Just add a file with this name in the project folder and place there these lines.
I came across here searching for a solution for shared projects. In my case, I solved it adding a Version.build.props
file in my shared project with the structure shown above, and just one new line at any csproj file for projects using my shared code:
<!-- Shared project import -->
<Import Project="..\Shared\Shared.projitems" Label="Shared" />
<!-- Version number generator -->
<Import Project="$([MSBuild]::GetPathOfFileAbove('Version.Build.props', '$(MSBuildThisFileDirectory)../Shared/'))" />
I'll left this code here just in case someone needs it.
*Solution tested for .Net5 but should works for earlier versions.