Setting the version number for .NET Core projects - CSPROJ - not JSON projects

Jay picture Jay · Apr 7, 2017 · Viewed 58k times · Source

This question is very similar to Setting the version number for .NET Core projects, but not the same. Using the latest stable version of .NET Core at the time of writing (1.1) and VS2017, .NET Core has switched from JSON based project files to CSPROJ files.

So - what I am trying to do is set up a CI environment where I would like to be able to modify something prior to a build to stamp my builds with the correct version number.

If I use the attributes like this the old (SharedAssemblyInfo.cs trick):

[assembly: AssemblyFileVersion("3.3.3.3")]
[assembly: AssemblyVersion("4.4.4.4")]

somewhere in the project, I get
CS0579 - Duplicate 'System.Reflection.AssemblyFileVersionAttribute'
and
CS0579 - Duplicate 'System.Reflection.AssemblyVersionAttribute'
errors when building.

When digging into it a bit, I find that there is a file which looks like this generated during the build process (it doesn't exist before I build) in \obj\Debug\netcoreapp1.1:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Reflection;

[assembly: System.Reflection.AssemblyCompanyAttribute("TestApplication")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyDescriptionAttribute("Package Description")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.1.99.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.1.99")]
[assembly: System.Reflection.AssemblyProductAttribute("TestApplication")]
[assembly: System.Reflection.AssemblyTitleAttribute("TestApplication")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.1.99.0")]

// Generated by the MSBuild WriteCodeFragment class.

Question - How do I do this bit?
So I can see that this must somehow be generated from the values entered in the project properties 'package page', but I don't know what the right way would be to change these values on my CI machine.

Ideally, I'd like to be able to specify all this information in my (Jenkins) CI script, but I'd settle for just being able to set the version number.

EDIT - More Info
After reading the first answer, I wanted to make it clear that I am creating both services and NuGET packages - and I would prefer to have 1 way of versioning everything, which would be like the old JSON project where I could just update a single file.

UPDATE I am going with scripting a change to the CSPROJ file which in my opinion is rather hacky as the section I need to modify looks like this...

<PropertyGroup>
 <OutputType>Exe</OutputType>
 <TargetFramework>netcoreapp1.1</TargetFramework>
 <Version>1.0.7777.0</Version>
 <AssemblyVersion>1.0.8888.0</AssemblyVersion>
 <FileVersion>1.0.9999.0</FileVersion>
 <Company>MyCompany</Company>
 <Authors>AuthorName</Authors>
 <Product>ProductName</Product>
 <Description />
 <Copyright>Copyright © 2017</Copyright>
</PropertyGroup>

So - the problem here is that there are multiple 'PropertyGroup' elements; the others appear to be labelled - but not knowing how the CSPROJ is put together, I can't say this will always be the case.

I am working on the premise that the package details will always be filled in, otherwise the value tags (above) don't appear in the XML - so then I can use a script to update the values in place. If the value tags were not there, I would have no clear idea which PropertyGroup element to insert the values into (and also which order, as this appears to be important; changing the order stopped me from loading the project in VS2017).

I am still holding out for a better solution than this one!

Update: After someone marking this question as a possible duplicate (Auto Versioning in Visual Studio 2017 (.NET Core)) - I hadn't seen this question before and now reading it seems to be almost the same except that I dont just want to set the version number. Also, the answers to this question do not solve my problem - only asks what I asked in my question. The accepted answer to my question is exactly the answer I need to solve my problem - so while the other question came first and appears the same - it does not help me at all. Maybe a mod can help?

Answer

Martin Ullrich picture Martin Ullrich · Apr 7, 2017

You can override any property from the command line by passing /p:PropertyName=Value as arguments to dotnet restore, dotnet build and dotnet pack.

Currently, Version composition works as this: If Version is unset, use VersionPrefix (defaults to 1.0.0 if unset) and - if present - append VersionSuffix.

All other version are then defaulted to whatever Version is.

So for example you can set <VersionPrefix>1.2.3</VersionPrefix> in your csproj and then call dotnet pack --version-suffix beta1 to produce a YourApp.1.2.3-beta1.nupkg (if you have project reference that you want the version suffix to be applied to as well, you need to call dotnet restore /p:VersionSuffix=beta1 before that - this is a known bug in the tooling).

Of course, you can use custom variables as well, see this GitHub issue for a few examples.

For a complete reference of supported assembly attributes, i suggest looking at the source code of the build logic here (the values surrounded with $() are the properties used). And since i'm already talking about the source, this is the logic that composes the version and a few other properties.