nugetvisual-studio-2017msbuild-15

How do I set the build-specific version number for a projectReference so that the NuGet package dependency lists the correct version


Using the new CSProj format in Visual Studio 2017, I have written a targets file to handle a new Configuration called CreateLocalPackages, which has the build create a NuGet package in a specific local folder and has it automatically increment its version number to be one higher than the highest number on any of the solution's packages in that folder.

My solution has several projects, each builds a NuGet package, with some having a dependency on other projects in the solution.

For example, with these files in the local package directory:

BaseLibrary.2.1.0.1-betalocal.nupkg
BaseLibrary.2.1.0.1-betalocal.symbols.nupkg
BaseLibrary.Specialized.2.1.0.1-betalocal.nupkg
BaseLibrary.Specialized.2.1.0.1-betalocal.symbols.nupkg

It would choose to create these packages the next time that the CreateLocalPackages Configuration was built clean:

BaseLibrary.2.1.0.2-betalocal.nupkg
BaseLibrary.2.1.0.2-betalocal.symbols.nupkg
BaseLibrary.Specialized.2.1.0.2-betalocal.nupkg
BaseLibrary.Specialized.2.1.0.2-betalocal.symbols.nupkg

I have gotten this working great, except for the fact that Visual Studio seems to create the BaseLibrary\BaseLibrary.Specialized\obj\project.assets.json file before I can hook into a MSBuild target and change $(Version) to 2.1.0.2, causing BaseLibrary.Specialized.2.1.0.2-betalocal.nupkg to instead just reference this dependency: BaseLibrary.2.1.0-betalocal. Visual Studio appears to generate project.assets.json during the NuGet restore step that it does before calling MSBuild to build the projects.

I have tried running my version number logic BeforeTargets="CollectPackageReferences;_ComputeTargetFrameworkItems" in order to get called early in the Restore target chain, but it doesn't seem like Visual Studio calls MSBuild /t:Restore in order to restore NuGet package references (and generate project.assets.json). I don't know if it has its own logic, or if it calls another tool.

I would like to be able to just tell VS to Rebuild and have it figure out the new version, build and pack everything, with the correct dependency versions listed, as well.


Solution

  • How do I set the build-specific version number for a projectReference so that the NuGet package dependency lists the correct version

    If I understand you correct, you want call the version number logic target CreateLocalPackages before VS/MSBuild Restore target.

    You can add an MSBuild Target that runs before the target Restore or _GenerateRestoreProjectSpec by following code snippet in your MSBuild .*csproj file:

      <Target Name="VersionNumberLogicBeforeRestore"
              BeforeTargets="Restore">
        <Message Text="Version Number Logic Before Restore!" Importance="high" />
      </Target>
    

    Or

      <Target Name="VersionNumberLogicBeforeRestore"
              BeforeTargets="_GenerateRestoreProjectSpec">
        <Message Text="Version Number Logic Before Restore!" Importance="high" />
      </Target>
    

    However, this only does work for dotnet cli not in Visual Studio.

    dotnet restore "xx.csproj"
    

    Besides, The NuGet restore changes will be part of 15.4 if it still makes it in. Otherwise 15.5.

    See Add support for pre restore MSBuild target that Visual Studio triggers for detail info.

    So, at this moment, we have to use dotnet cli to call the the version number logic target before Restore target and you can also use dotnet cli build the project.