1
votes

I created a NETStandard 2.0 project. The tooling support around generating a NuGet package works fine; I can set the Version, Description, etc. What I wanted to do was to extend my project to support a way to generate prerelease versions automatically as well. The solution I came up with was the following modifications to my csproj file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <PackageId>MyCompany.MyLibrary</PackageId>
    <Authors>MyCompany</Authors>
    <Version>1.1.8</Version>
  </PropertyGroup>

  <!-- Support Prerelease Versioning -->
  <PropertyGroup Condition="$(IsPrerelease) == true">
    <CurrentDate>$([System.DateTime]::Now.ToString(yyyyMMdd-HHmmss))</CurrentDate>
    <VersionSuffix>CI-$(CurrentDate)</VersionSuffix>
    <Version Condition="'$(Version)' != ''">$(Version)-CI-$(CurrentDate)</Version>
  </PropertyGroup>
</Project>

This works fine, specifically because the prerelease PropertyGroup follows the PropertyGroup generated by Visual Studio. If the Version is 1.0.0, Visual Studio removes the property because 1.0.0 is used by default, so the VersionSuffix will work properly. However, if Visual Studio sets the Version (1.1.8), then I need to replace the value of the property (as seen above).

When doing this, msbuild functions appropriately only in the case that no Version is specified:

  • msbuild MyCompany.MyLibrary.csproj generates 1.0.0.nupkg
  • msbuild MyCompany.MyLibrary.csproj /p:IsPrerelease=true generates 1.0.0-CI-*.nupkg

The next step for me was to pull out the additional PropertyGroup and create a NuGet package: MyCompany.Packaging.Prerelease, which has a .props file. The problem is that if Version is specified, it ignores the fact that I am overwriting that value and even when I specify /p:IsPrerelease=true it generates 1.1.8.nupkg. I'm not sure why, but I have a feeling that I misunderstood the way that NuGet target/props files would be included; I assumed that the NuGet target/props would be appended.

I'm not sure what I can do to alter my MSBuild so that my Prerelease Versioning section is able to overwrite the Version property when pulled in as a NuGet package.

1
I am not 100% sure, I understand your scenario, but here's me taking a crack at it. You create a package MyCompany.Package.Prerelease and added a target/props file in the build/MyCompany.Package.Prelease.props in that nupkg, and you installed it to a project, the "MyCompany.Library.csproj", is that right?imps
@imps: Correct, that is what I did; I created a NuGet package containing the props file. I think the problem is that the props are prepended instead of appended, so my props which is attempting to set the version property is being overwritten.myermian
You can easily check the order of the imports by generating the pp file via msbuild. You can also set the "PackageVersion" in your targets, as that's the metadata NuGet reads, but defaults to version if it's not set.imps
@imps: Oh wow, yes. I don't know how I overlooked the fact that PackageVersion is what NuGet looks for, and that Version is just a fallback. This makes it very easy to create my NuGet targets package to do what I need it to do.myermian

1 Answers

0
votes

Thanks to the comments made by imps, I updated my props/targets to update the PackageVersion property instead of attempting to overwrite the Version property; PackageVersion is the preferred metadata for NuGet packages, and it only falls back to Version if PackageVersion is not set. Additionally, I utilized a custom Target which will run prior to the Build target.

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Condition="$(IsPrerelease) == true" Name="Prerelease" BeforeTargets="Build">
    <PropertyGroup>
      <DateTimeFormat>$([System.DateTime]::Now.ToString(yyyyMMdd-HHmmss))</DateTimeFormat>
      <PackageVersion>$(Version)-CI-$(DateTimeFormat)</PackageVersion>
    </PropertyGroup>
  </Target>
</Project>

msbuild MySolution.sln /p:IsPrerelease=true will now generate a prerelease NuGet package instead.