This example will use TeamCity as the build platform as well as the Alpha Nuget Trigger and Update/Install Packages Build step found here.
It will also use my preferred Package Update Strategy defined here.
The build targets are specified in the build directory of the solution (here)
The build targets are linked into the solutions via the Named MsBuild Hook.
The automated build for each component has 4 main build steps
- Update and Install packages
This is done by adding the Alpha NuGet Build Step and selecting the options relevant to your update strategy. I make liberal use of Build Parameters here.
- Increment Version Number
This is done via the TeamCity.targets.
It takes the TeamCity build number, makes it the revision number in the AssemblyInfo. The pack command later uses this as the package version.
- Check In
This is not implemented in the example and will depend on your VCS. However updating packages will change the packages.config and the project files of your solution. These will need to be checked in. If you also check in packages, these will need to be added as well.
- Create, Lock Versions, Publish Package
Creating and Publishing a package are trivial with NuGet. Package.Targets contains targets that Exec NuGet to do create a package. I use a Shared Drive for my repository so publishing is just a matter of specifying the output directory of pack to the repository UNC path. However there is also a publish command in NuGet if you want to push to the official feed.The interesting part of this step is my need to ensure all dependencies read from my project file will be locked to the version used to build the current version. This involves changing all dependency elements in the nuspec file inside the package. The target unzips the package, runs the LockDepedencyVersions Target found here and then re-zips the package.
The last piece of the TeamCity puzzle is triggers; we want a build to be triggered if there is a new dependent package. At the moment it is a little clumsy as you must create a trigger per package you wish to monitor. I only monitor internal dependencies and then only direct internal dependencies.
So for example the UI project whilst it uses Common, Common is a dependency of Service A and Service B. So I only need to add triggers for those two packages. Because when Common changes, Service A and B will be triggered and when they publish their new versions the UI build will be triggered.