MSBuild NuGet Pack and Restore with older Net 4.5 projects

With Visual Studio 2017, MSBuild and NuGet are better integrated, which removes the need for things like package.config, as packages can be tracked in the csproj directly, and custom MSBuild targets for packaging like NuProj, as one can now do it all from the csproj with the built in functionality in MSBuild 15.

All that is great, but I found myself stuck with an old SQLPROJ. I wanted to generate a NuGet package out of it. Here's how one can do it:

<Project ...>  
  ... any initial imports ...
  <PropertyGroup>
    <!-- RestoreProjectStyle is required to be set to PackageReference to use msbuild restore/pack targets -->
    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
  </PropertyGroup>
  ... rest of your project here ...
  <!--
    Visual Studio won't restore this project and package generation fails.
    This means that package generation only happens if you build from command line.
    > nuget restore
    > msbuild
  -->
  <Import Project="$(MSBuildSDKsPath)\NuGet.Build.Tasks.Pack\build\NuGet.Build.Tasks.Pack.targets" Condition="'$(BuildingInsideVisualStudio)'!='true'" />
</Project>  

The import statement will load the MSBuild targets assocaited with creating a nuget package and they will register a dependency on your build. If the property GeneratePackageOnBuild is set, a NuGet package will be generated as part of your build.

RestoreProjectStyle is required to be set to PackageReference so a project.assets.json is created as part of the restore phase (when you do msbuild /t:restore or nuget restore). This is a requirement for the package to be generated later on, during build.

A limitation, however, of this approach, is that it only work when calling MSBuild directly from the command line. I couldn't find a way for Visual Studio to properly call restore before build.

In summary:

  1. Set properties RestoreProjectStyle and GeneratePackageOnBuild
  2. Import $(MSBuildSDKsPath)\NuGet.Build.Tasks.Pack\build\NuGet.Build.Tasks.Pack.targets
  3. Generate a package from the command line by opening Visual Studio 2017 developer tools and running: msbuild /t:restore (or nuget restore) and then msbuild

Just in case you are curious on how to add custom files to your NuGet package for a SQLPROJ, here's how I ended up doing it:

  <Target Name="PackDependencies" DependsOnTargets="SqlBuild">
    <ItemGroup>
      <None Include="$(OutDir)\$(SqlTargetName).dacpac">
        <Pack>true</Pack>
        <PackagePath>contentFiles</PackagePath>
      </None>
    </ItemGroup>
  </Target>