One great benefit of having a Continuous Integration server like TeamCity (http://www.jetbrains.com/teamcity/) building your code is that you can hook into the build process to have it also handle tedious or time-consuming tasks for you, such as running all of your unit tests, code coverage analyses, etc.
Now that NuGet (http://nuget.org/) has arrived and simplified package management in .NET, wouldn’t it be nice to have your CI server build an updated NuGet package for you along with every build? An why not go one step further and have your build process automatically push the newest version of your package to the central NuGet server (or even your own hosted NuGet server)?
It turns out this is actually very easy to do – let’s see how.
Super-Quick NuGet Package Introduction
If you would like to familiarize yourself with what NuGet is and how to use it, take a look at the project homepage at http://nuget.codeplex.com/.
For this post it’s really only necessary to know that a NuGet package starts out as a specification file (*.nupec) and usually some deliverable content (Dlls, script files, etc). Once you have a specification file, you use the NuGet.exe command line utility to turn it into a package (*.nupkg) that can then be uploaded to the masses via http://nuget.org/. [Full details are available at http://nuget.codeplex.com/documentation?title=Creating%20a%20Package].
Building and Deploying Your Package
You’ll need to have your *.nuspec file checked into source control, and I also find it useful to check in the nuget.exe command-line utility as well (although this is not necessary as long as it is on your build server). I tend to put my specifications in a /Build/NuGet folder, so it’s outside of the main /src/ folder.
Note: The following steps are TeamCity specific, but any build process with the ability to run a batch file should be able to do the same thing.
1. Open up your project’s build configuration and select #3, “Build Steps.”
2. Click “Add Build Step.”
3. Under Runner Type choose “Command Line,” and then under Run choose “Custom Script.” You can optionally specify a working directory to have your script run in that directory, which I find to be quite helpful.
4. Now you are ready to write your custom script, which should be able to perform the following steps: (1) cleanup old *.nupack files, (2) create your newest package with the correct version number, and (3) push that package up to nuget.org or another nuget server.
My script is as follows:
NuGet.exe pack Project\Project.nuspec -Version %system.build.number%
forfiles /m *.nupkg /c "cmd /c NuGet.exe push @FILE <your-key>"
5. That’s all there is to it, just replace <your-key> with your access key from nuget.org (look under MyAccount)
On line two notice how I use TeamCity’s %system.build.number% to inject the build number into the generated package. This is very important because NuGet pays close attention to your package version number (as David Ebbo describes in detail in his NuGet versioning blog series http://blog.davidebbo.com/2011/01/nuget-versioning-part-3-unification-via.html).
The third line is pretty fun—basically it is saying for every file that ends in *.nupkg, call ‘NuGet.exe push <filename> <your-key>’. I really like this approach, and it could even be adapted to build and push multiple NuGet packages during every build run.
Overall there wasn’t too much work to do, we just created a command line script build runner and added a few lines of code to automatically build and push versioned NuGet packages.
Now that I’m using NuGet a lot more, with one OSS project on nuget.org (http://dataannotationsextensions.org/) and several hosted on my own internal company NuGet server, I find this automatic build and deploy process the perfect way to keep my packages up to date.