Suggestions on how to support .csproj Nuget pack targets?

Apr 12, 2013 at 4:21 AM
I've currently got a batch file that builds all of my packages. I use the NuGet functionality that lets me have a .nuspec sitting next to a .csproj file, and specify the .csproj file as my pack target instead of the .nuspec file.

In trying to get nugetter set up on my Team Build server, I can't do this. I've dug into the workflow a bit, and the primary issue seems to be that there are 2 activities that try to read the id element out of the .nuspec xml, and they fail if you specify the .csproj.

I see a couple ways of solving this and wanted some advice on the best way to do it so that my patch would be applied.

1) Add a boolean property to the process, something like "Pack project files if available" where the user configuring the build would still specify the .nuspec files in the multi-package list, etc... but for the last step where we invoke nuget to pack, we would check for the existence of a .csproj next to the .nuspec and use that if found.
2) Automatically detect if a .csproj file is specified as the pack target. If so, transparently open/read the .nuspec file sitting next to it.

I think #1 is the better option, as it doesn't rely on "magic" functionality that the user doesn't know about, but at the same time, #2 is similar to what nuget does itself when packaging.

I'd like to start making the changes, any preference on which direction to head? Any warnings on things I haven't mentioned that might be problematic?
May 3, 2013 at 10:34 PM
The problem here is that the Nuget specific operations happening in the NuGetter template are post build of the project and operate on the outputs in the drop location. At this point you do not have access to the project source and therefore there is no csproj. I think it would take a fairly substantial rework of the workflow steps to achieve this, but I could be wrong.

You could perhaps hack some way around this by using powershell in a pre-packaging step as this has access to the sources through the $tfsSourcesFolder variable. You could get the source into a pre-package folder in the drop location and then configure nuget through the template to execute against the csproj file, passing in the -Build switch as an additional command line option.
May 6, 2013 at 8:36 PM
Edited May 7, 2013 at 2:24 PM
Understood. Following your suggestion, I tried something a bit different: Tackle some missing pieces in the core nuget project to make this easier. I'm posting it here in case it's helpful. In the end, I ended up with couple simple modification to the TFS 2012 Build Template:
  • Add 3 arguments to the build template for NuGet OutputPath (My local NuGet Repository), A path to a powershell script to run, and my nuget version info (minus the build part, which I pull out of the build name)
  • Add an activity after build/test execution that checks to see if the powershell script was specified. If so, execute the powershell script which does all of the packaging and pushing.
I've submitted a pull request, available HERE for the NuGet project. The second part of that pull request is to fix BasePath support for packing project files, which is what makes things so simple.

I created a GitHub project that contains the Team Build template, Powershell script, and custom nuget.exe HERE