A side effect of having a very complex build environment is the need to provide people with some ability to impact assess the result of particular build jobs being triggered. At my current client we use NuGet packages and internal NuGet feeds for all our binary dependency management, and TeamCity for all our build jobs, so it seemed that all the information that we needed to provide this impact assessment was already available.

So I had a crack at implementing a plugin that exposed useful build dependency data, the result being a NuGet command line extension called “teamcity”. The extension can be found here: NuGet.Extensions. It would make sense from my point of view for this to exist within TeamCity, but to be honest I grabbed the closest tool to hand…and it is rare that I find Java close to hand (or any other JVM language to be honest).

One thing that might be unusual about our setup is that we typically consume every CI build. This means that if a solution holds a dependency on a package, and the solution that results in that package is triggered to build (via a commit or a dependency “ticking”) and subsequently the package is published, the dependent solution in turn will be triggered to build. This will then continue up the build graph.

The idea behind this is that a change anywhere in the build graph (or package dependency graph, whichever way you want to look at it) should result in every required build being run to ensure that any final output can be released if required. We have a few other tricks we use to get this to work, but that is for another day.

So, what does this “teamcity” extension command do? Basically, the following:

Checks for the complete set of package dependencies for a particular TeamCity project or instance by:

  1. Querying a set of builds for any NuGet Triggers

Checks which builds produce packages by either one or both of the following methods:

  1. Querying a set of builds for any NuGet Pack tasks
  2. Checking the build artifacts for the existence of any *.nupkg files

Based on this data, we then build a graph, matching publishers to consumers such that we can show exactly what builds will be triggered by the resultant output of which other builds.

For an example of the commandline options:

C:\temp>nuget teamcity
usage: NuGet teamcity

Provides the ability to graph NuGet publish and subscribe details into a graphical representation of your builds dependency graph.

options:

 -Project                        (p)  Project to confine search within
 -TeamCityServer                 (t)  Target TeamCity server
 -Feed                           (f)  Constrain to a single target feed.
 -NoPackageAsVertex              (v)  Does not output a package as a node, instead they are output as just a label on a
                                      n edge.
 -NoArtifact                     (a)  Don't use the presence of a package in the artifacts as evidence of a publish
 -NoPublishStep                  (b)  Don't use NuGet Publish step to build publish output.
 -IncludeUnconsumedPackages      (u)  Graph packages that are not consumed within graph.
 -Output                         (o)  Filename to output
 -Help                           (?)  help

On a simple test project, you can run the following:

C:\temp>nuget teamcity -t http://teamcity.dev -p Testing
Attempting to create graph from TeamCity server: http://teamcity.dev
Processing 6 build configurations...

Completed graph in 1.1351455 seconds

Which will the DGML graph shown below (rendered in VS2010, green ovals are the builds whilst the empty nodes are NuGet packages).