TeamCity NuGet package build for different .NET Frameworks
Asked Answered
M

1

4

I've been doing updates to .NET Framework targeted versions of projects updating to latest .NET (4.6.2).

Some of these projects are NuGet packages, built in TeamCity 9.0.2.

I've use the steps in this guide to create multiple build configurations for different .NET Framework version as some of the projects I haven't updated to 4.6.2 reference the NuGet packages. So I am trying to get TeamCity to use these build configurations to output the various Net40, Net45, Net46 and Net462 versions so that I have full compatibility without forcing the need to upgrade all projects that use the NuGet when updating the packages.

I really can't figure out how to do this in TeamCity. I am fairly sure that this should be done in the "Build Steps" configuration, but so far I've not managed to get this to work.

Current Build Steps

So one thing I've tried, which I think I need to do but am not sure is duplicate the first build step and set the Configuration to Release-Net46. I think this is necessary otherwise this version of the assembly wouldn't be built (please correct me if I'm wrong about that!)

The second thing I've tried is to duplicate the NuGet Pack step and in Properties set Configuration=Release-Net46 but all that did was replace the Net462 version with Net46 and not include both in the artifacts like I'd hoped.

I also tried in the Properties of NuGet Pack to have multiple Configuration elements like Configuration=Release;Configuration=Release-Net46 or Configuration=Release,Release-Net46 but both of those resulted in the build failing altogether so clearly that's not the answer.

NuGet Pack Properties

I think there must be a way to get this NuGet Pack build step to pick up the output from the other build configurations and output all available versions of the assembly to the artifacts.

Is that possible? I had thought about creating separate projects for each build configuration in TeamCity but I'm unsure if that's the correct way or it that would cause issues with the package feed and it would seem untidy to duplicate the project four times for each .NET Framework version.

Modulate answered 14/10, 2016 at 15:21 Comment(0)
M
5

Ok I ended up solving this through trial and error and learning about NuSpec. Note, I didn't find a way to do this using purely TeamCity settings but this is equally good.

I was correct that you need extra build steps to build the assemblies in the solution/project level build configurations and point each Configuration at Release-NetX.

TeamCity Build Steps

EDIT I've found it's actually best in the above to point the NetX build steps at the .csproj rather than the .sln. That way you don't need the build configurations at a solution level, as long as they exist in the .csproj then it will all build fine.

Once this is done, TC will then be building all versions into their respective bin\Release-NetX directories.

Next was to add a .nuspec file to the root directory of the solution project to build the NuGet for.

<?xml version="1.0"?>
<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <id>Foo.Bar.Package</id>
    <version>1.0.23</version>
    <authors>FooBar Industries</authors>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>FooBar Industries package</description>
  </metadata>
  <files>
    <file src="bin\Release\*.dll" target="lib\net462" />
    <file src="bin\Release-Net46\*.dll" target="lib\net46" />
    <file src="bin\Release-Net45\*.dll" target="lib\net45" />
    <file src="bin\Release-Net4\*.dll" target="lib\net40" />
  </files>
</package>

Next is to alter the NuGet Pack TeamCity Build Step and in Specification files section and point this to your .nuspec file. There's a checkbox for Prefer project files to .nuspec. It worked for my just by unchecking this and I didn't even need to point to .nuspec file.

TeamCity NuGet Pack build step

Then on triggering a build, all versions are outputted and are then available to use without upgrading all projects that reference this package.

enter image description here

Modulate answered 18/10, 2016 at 15:3 Comment(4)
Cool solution! But what about tests? It seems that only 'Release' configuration will be tested during wildcard that contains 'Release' substring. What about testing assemblies in 'Release-Net46' folders and others?Sherman
You raise an excellent point, you would have to create duplicate NUnit steps for each set of tests. Which should be pointed at bin\Release-NetX of the various build configs. To be honest, I only needed the the different framework versions outputted for targeting in other projects and I hadn't thought to expand the unit tests to use each version. Good thinking though!Modulate
Regarding your EDDIT. Could you clarify what you meant by "That way you don't need the build configurations at a solution level". @RobinFrenchBucci
@Bucci If you set the Net4X build profiles on the solution then they appear in the solution configurations drop down where there would usually only be 'debug' and 'release'. However, you don't actually need the new configurations at the solution level, if you put them directly into the csproj files and point to them in the TC build step then you can avoid editing the solution at all. I found it useful as I only need this for one project, not the entire solution.Modulate

© 2022 - 2024 — McMap. All rights reserved.