91

TLDR: Where is dotnet pack pulling the version information when it creates the nuget package for an assembly?

I have a library, that I had transitioned from a .NET 4.6.1 project to a .NET Core project with project.json. For my CI during this period (using TFS 2015 vnext), I would get my version number and replace the version number in the project.json file with the new version. The dotnet pack command would pick the version up just fine, and create a new package with the updated version number.

Last week, I upgraded from TFS 2015 to TFS 2017. Turns out, project.json was replaced with an updated .csproj file. I've updated my CI. During my CI - I update my /Properties/AssemblyInfo.cs file, replacing the AssemblyVersion tag with the version for the current build. Then I build the solution - which builds just fine. Then I package the solution.

However, despite the AssemblyVersion and AssemblyFileVersion being set in AssemblyInfo.cs to the correct build number - dotnet pack is still producing .nupkg files that are *.1.0.0.nupkg.

What am I missing?

Here is my pack command:

dotnet pack $projectFile -o $currentDirectory
Nate Barbettini
  • 51,256
  • 26
  • 134
  • 147
Alexander Matusiak
  • 1,748
  • 2
  • 18
  • 29

4 Answers4

115

Better yet, specify /p:Version=$(Build.BuildNumber) (TFS/VSTS) on the dotnet pack command and it will build it with the specified version in the nuget package. Example (non TFS specific):

dotnet pack .\src\example\example.csproj -o c:\published\example -c Release /p:Version=1.2.3

Example (TFS specific) <- we use this for our TFS 2017 packing using a powershell script step.

dotnet pack $(Build.SourcesDirectory)\src\example\example.csproj -o $(Build.ArtifactStagingDirectory)\Pack -c Release /p:Version=$(Build.BuildNumber)

Note: It does not update package reference versions.

Edward
  • 1,407
  • 2
  • 10
  • 15
  • 22
    For anyone struggling with this - make sure you don't have any `` or `` values in your `*.csproj` file. Otherwise these will override whatever you specify in your command line. – trailmax Nov 06 '17 at 10:23
  • Thanks Edward. After searching the internet I came to the same conclusion (I want to set the version via ci build). I added a default in the csproj so I can tell if a Dev built on their personal PC. I used a Condition in the csproj to only set VersionSuffix if not defined. I did NOT override Version definition. This way the version will have "private.$USERNAME" at the end. Here's how it all goes together in Build source code https://github.com/dotnet/sdk/blob/94a3f2856cb09e66ee7472820b4e26fb576b4686/src/Tasks/Microsoft.NET.Build.Tasks/build/Microsoft.NET.DefaultAssemblyInfo.targets – ripvlan Feb 07 '18 at 16:26
  • 1
    If I recall correctly, dotnet pack back then ended up calling msbuild under the hood and all unknown parameters, like /p:xxx gets passed to that application. The /p arguments is something I've learned setting up automated builds for many years. FYI, the dotnet pack build step in TFS 2018 now has the option to set the package version so we don't need to set the parameter like that any more. – Edward Nov 14 '18 at 16:26
  • For anyone trying to find why `AssemblyVersion` is not changed with `pack /p:Version` - make sure that you have executed `build /p:Version` before since `pack` just creates nuget package if there is project assembly available. – oleksa Dec 10 '19 at 12:46
  • For those on Git and building from the command line with Git Bash, the syntax requires a dash rather than a slash: -p:Version=$(Build.BuildNumber) – Alex Sanséau Nov 16 '20 at 10:04
  • 2
    This does not seems to be working when specifying a .nuspec file. Previously `nuget.exe pack -Version` would, but not with `dotnet pack` with the `-p:NuspecFile=` argument. Tried both `-p:Version` and `-p:PackageVersion`. It stick to the version in the .nuspec file (which is required), and I'm unable to override it with the version coming from the git task from my build server. – Dunge Nov 25 '20 at 02:46
  • @Dunge did you manage to resolve it? I have the exact same issue – John Demetriou Dec 10 '21 at 15:29
  • No I reverted to use nuget.exe pack instead of dotnet pack – Dunge Dec 11 '21 at 16:46
58

When you use dotnet pack, the version is pulled from the project definition (previously project.json, now *.csproj), not AssemblyInfo.cs. So, your new workflow will be very similar to what it was with project.json.

From the project.json to csproj migration docs, you can use the VersionPrefix and VersionSuffix properties.

Before:

{
  "version": "1.0.0-alpha-*"
}

Now:

<PropertyGroup>
  <VersionPrefix>1.0.0</VersionPrefix>
  <VersionSuffix>alpha</VersionSuffix>
</PropertyGroup>

You can also use the single Version property, but the docs warn that this "may override version settings during packaging".

<PropertyGroup>
  <Version>1.0.0-alpha</Version>
</PropertyGroup>
Nate Barbettini
  • 51,256
  • 26
  • 134
  • 147
  • 2
    I ended up using powershell to rewrite the .csproj as part of the build to replace the version prefix & version suffix. – Alexander Matusiak Mar 15 '17 at 14:32
  • 9
    To add to this, you can provide the VersionPrefix and VersionSuffix (or just the single Version property) at the command line by adding something like "/p:Version=1.0.0-alpha" to the dotnet pack command. – Daniel Lo Nigro May 08 '17 at 02:31
19

NOTE: I understand this question is not specifically about VSTS/Azure Dev Ops but a search for how to do this on a build pipeline lands here so adding what worked for me

  1. Use the dotnet core task
  2. Tools version 2.*
  3. Command = custom
  4. Custom Command = pack
  5. Arguments = -p:Version=1.0.$(Build.BuildId) -o $(Build.ArtifactStagingDirectory)

The -o argument is required if the task following the packaging is going to push to a feed (isn't that why one would build packages?)

Sudhanshu Mishra
  • 6,523
  • 2
  • 59
  • 76
  • Just a note that you can do this with the Visual Studio Build step too if your project has the nuget build tasks. Using the `/t:Pack` command and then specifying version and packageoutputpath as additional properties. – Encryption Jan 11 '22 at 15:19
2

I've tried many variations of changing the version of the target nuget package and the following solution by my colleague worked for me. In the src folder, there is a file called 'Directory.Build.props' where the versions are set like below:

  <Target Name="CustomVersion" AfterTargets="MinVer">
    <PropertyGroup>
      <FileVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch)</FileVersion>
      <AssemblyVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch)</AssemblyVersion>
    </PropertyGroup>
  </Target>

You can replace this with version you are trying to create the nuget package eg:

  <Target Name="CustomVersion" AfterTargets="MinVer">
    <PropertyGroup>
      <FileVersion>106.11.7</FileVersion>
      <AssemblyVersion>106.11.7</AssemblyVersion>
      <InformationalVersion>106.11.7</InformationalVersion>
      <PackageVersion>106.11.7</PackageVersion>
    </PropertyGroup>
  </Target>

Now, on running 'dotnet pack -c Release -o nuget -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg' respective nuget package with desired version will be created

  • Good tip. Just did something similar in .net 5 following https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2019, and all we had to do was set – Mike May 27 '21 at 23:49