Visual Studio 2013, Code Metrics and TFS Builds

So you're using Visual Studio 2013 and running Code Metrics.  All is good in your life and you feel fulfilled.  Then you have a brainwave, wouldn't it be great to run Code Metrics as part of your TFS build process - and even better be able to pass or fail a build depending on the results.  After all, who wants to maintain monolithic functions?!  Now this post isn't intended to demonstrate the goodness of Code Metrics or how you can use them to measure complexity and maintainability of your code - if you're looking for that start here: https://msdn.microsoft.com/en-us/library/bb385910.aspx

What I'm interested in here, is how you hook up Code Metrics as part of your automated build processes.  For starters you'll need the latest Visual Studio 2013 Code Metrics PowerTool: https://www.microsoft.com/en-us/download/details.aspx?id=41647.  Once you've got this you need a way of invoking it from your TFS Build Definition.  Now you could just shell out directly from within the TFS Build workflow and Invoke the Metrics.exe - much like documented here: https://blogs.msdn.com/b/slange/archive/2011/04/14/running-code-metrics-as-part-of-a-tfs-2010-build-the-poor-man-s-way.aspx

However, the Community TFS Build Extensions is a much cleaner way to implement this.  If you are unfamiliar with the build extensions, take a look at some of the great extensions available here: https://tfsbuildextensions.codeplex.com/.  Now the extension I'm interested for the sake of this article is the CodeMetric build activity.  This workflow activity not only invokes the Metrics.exe to analyse your specified build outputs, but also allows you to set thresholds for build warnings or errors. This is all well documented here: https://tfsbuildextensions.codeplex.com/wikipage?title=How%20to%20integrate%20the%20codemetric%20build%20activity&referringTitle=Documentation

Now, if you are using Visual Studio 2013 you'll need the latest version of the Code Metrics PowerTool (https://www.microsoft.com/en-us/download/details.aspx?id=41647) and an updated Community TFS Build Extensions set of binaries.  If you try to use the current version you'll see the following error: 

 

I've recently submitted a pull request to the repository which has updated references for the VS 2013 PowerTool component.  Until the request is accepted, you can use my Fork here: https://tfsbuildextensions.codeplex.com/SourceControl/network (you'll need to compile them locally).  Once you've got the binaries you'll need to add them into Source Control so they can be pulled down by your TFS Build Controllers.  Once they are in Source Control, you then need to setup your Build Controller's custom assemblies to point to their version control location eg:

Next up, you'll need to be able to add the TFS Build Extensions into your existing build definition workflow.  The easiest way to do this is to create a new Visual Studio class library project, delete the class files and Add References to the TFS Build Extensions binary files.  You'll also need to add your TFS Build Definition template into the project.  If you are using the default build templates, add a link to the DefaultTemplate.xaml file or copy the file into your project.

Then, you'll need to add the TFS Build Extensions into the Visual Studio Toolbox, so that you can add the new build activities into the workflow process.  Right click on the Toolbox and select Add Item.  Select the CodeMetrics item from the TFSBuildExtensions.Activities.dll:

 

Now you'll see a new item appear in your Toolbox, you can drag this to a suitable point in your workflow where you want to run the Code Metrics eg:

Then you'll need to configure the properties of the CodeMetrics Activity (highlight the activity and press F4).  Here you get to set all the goodness of the tool including warning and error thresholds.  It is important to set the BinariesDirectory - the directory to scan for your build outputs and the FileToProcess - files which should be analysed by Metrics.exe.  If you leave the later blank it defaults to scanning all *.exe and *.dlls.  From TFS Build you probably aren't interested in scanning everything, so I set mine to only include specific component wildcards eg:

Note: In the above I've also excluded running code metrics against the Test dlls.  Beware here of dependencies in your components, if you see Error 521, this is likely caused by a referenced asssembly not being found eg:

Once all this is done, you'll need to check into the DefaultTemplate.xaml back into Source Control, then create a build definition using the modified DefaultTemplate.xaml file.  Then, invoke the build and wait for the Code Metrics to automatically be run :)

 I've not mentioned it here, but there is also a CodeMetricHistory activity that you can include in your build workflow to log code metric results in a central location.