I've read a handful of posts (see references below) and have yet to find a guide on best practices that is specific to my tech stack.
The goal: Create a single NuGet package targeting multiple .NET frameworks built from a single .csproj file via TeamCity using MSBuild and NuGet.
The constraints:
I have two approaches in mind:
Create a single build configuration. It would contain three build steps: compile .NET 3.5, compile .NET 4.0, pack with NuGet. Each build step would be contingent upon success of the last. The only real problem I see with this approach (and hopefully there's a solution that I'm not aware of) is that each build step would require its own set of build parameters (e.g., system.TargetFrameworkVersion and system.OutputPath) to designate the unique location for the DLL to sit (e.g., bin\release\v3.5 and bin\release\v4.0) so that the NuGet pack step would be able to do its thing based upon the Files section in the .nuspec file.
Create multiple build configurations. One build configuration per the build steps outlined above. With this approach, it is easy to solve the TargetFrameworkVersion and OutputPath build parameters issue but I now have to create snapshot dependencies and share the assembly version number across the builds. It also eats up build configuration slots which is ok (but not optimal) for us since we do have an Enterprise license.
Option #1 seems like the obvious choice. Options #2 feels dirty.
So my two questions are:
References:
For SDK-style projects, you can configure support for multiple targets frameworks (TFM) in your project file, then use dotnet pack or msbuild /t:pack to create the package. nuget.exe CLI does not support packing SDK-style projects, so you should only use dotnet pack or msbuild /t:pack .
The target framework moniker (TFM) to apply when installing the package. This is initially set to the project's target when a package is installed. As a result, different <package> elements can have different TFMs. For example, if you create a project targeting .
PackagePath : Path where the file should be output in the package. NuGet issues a warning if more than one file is added to the same package path. BuildAction : The build action to assign to the file, required only if the package path is in the contentFiles folder. Defaults to "None".
Here is my preferred solution (Option #1):
The magic relies on an unfortunate workaround. If you're willing to make this compromise, this solution does work. If you are not, you can follow the issue that I opened on JetBrains' issue tracker.
The single build configuration looks like this:
Note the name of the first two build steps. They are, in fact, named explicitly as the TargetFrameworkVersion values for .NET 3.5 and 4.0, respectively.
Then, in the Build Parameters section, I have configured the following parameters:
And finally, the Nuget Pack step does the file path translation according to my .nuspec's files section:
<files> <file src="bin\release\v3.5\*.*" target="lib\net35" /> <file src="bin\release\v4.0\*.*" target="lib\net40" /> </files>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With