Wednesday, April 11, 2012

Creating a TFS Work Item from ClojureCLR

At my day job we use Team Foundation Server 2008 (TFS) for our automated builds, iteration management, and source control. TFS may not be the most ideal way to manage these processes but in our MS environment it has helped us communicate with our non-technical team members and customers.  So we’ve been looking into ways to add bugs automatically when automated tests fail (see Creating A TFS WorkItem From IronRuby) or errors are reported from our applications via a message queue.

This morning I had a little time to do some ‘research’ on how to programmatically create a new bug work item.  My goal was to write code that would create a new work item bug with an image attached to it.  Before I get into the code let me take a second to introduce you to a TFS Bug Work Item.

A TFS Bug Work Item

In TFS Work Items are a way to track work that needs to be done. There are a total of five different type of Work Items available but we typically only use three: Task, Scenario, and Bug. Each Work Item type UI has different fields. Here is what a Bug Work Item looks like in our environment.

empty-bug-wi-tfs

In this example we will create a new bug and enter text into the highlighted fields plus attach an image file. In order to create the bug I need to do a little setup.

The Setup

There are three assemblies needed to create a TFS Bug Work Item. The are: Microsoft.TeamFoundation.dll, Microsoft.TeamFoundation.Client.dll, and Microsoft.TeamFoundation.WorkItemTracking.Client. All three of these DLLs can be found in the C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies directory. I copied the three Dlls into the project’s libs directory.

The Code

The first step is to load the TFS assemblies from libs directory using the assembly-load-from function. I follow that call up with the import function pulling in the specific classes I need.  Once the assemblies and classes have been loaded I can start working on creating a bug work item. First, I created the -main function. The first few lines of –main are responsible for creating the necessary objects for WorkItem creation.

The first line gets the server object by making a call to the static method TeamFoundationServerFactory.GetServer passing in the name of the server I am working with.  The returned server object is used to create a WorkItemStore object.  A WorkItemStore encapsulates the data store that contains all work items on a particular server.  The next line gets the TFS project that I want to work with by using the filter function.  The last setup line uses the project object to retrieve the WorkItemType object that represents a bug.  Now I 'm are ready to create a new bug WorkItem.

Creating the Bug WorkItem

Since I will be creating bugs that have attachments and bugs that do not I created a function that creates and returns a WorkItem object. As I stated previously, the work items created this way will have the bare minimum values: title, area, iteration and description. The code is straight forward, just create the WorkItem object by passing in the WorkItemType object. Next I set the properties of for the four parameters. When everything has been set I return the WorkItem object.

Adding the Attachment

Now that I have my WorkItem object its time to add my image file as an attachment. I wrote another small and simple function to create the Attachment object. It takes three parameters, the WorkItem, the path to the file to attach and a description of the file.  First I use the path and desc parameters to create the Attachment object.  After the Attachment is created I can added it to the WorkItem object’s Attachments collection by calling the Add method passing the Attachment object as its only parameter. 

At this point I have a WorkItem object with an Attachment in memory.  At this moment the WorkItem is not visible through the TFS toolset.  I still have one last line of code to write to ensure that the WorkItem is saved. Surprisingly enough all I need to do is call the WorkItem’s save method.

(.Save work-item)

Now, If I look at the Pending Bugs report in TFS I will see my newly created bug in the list.

pending-bugs-clj-ir

Summary

This post is another illustration of how easy it is to use .NET Assemblies from ClojureCLR.  In this case I walked you through the simple process of creating a Bug WorkItem in TFS.  Having the ability to programmatically create and report bugs will help us close the feedback loop in our applications. 

In The Future

In my ‘free time’ I will be checking into TFS’s build and source control APIs to see what we may be able to do improve our processes.  If and when I find anything of interest I will be sure to do a post or two about my findings.

Resources

TFS API: http://msdn.microsoft.com/en-us/library/bb130146(v=vs.90).aspx

My Source (this blog’s code is the 5-create_tfs_work_item):https://github.com/rippinrobr/clojure-clr-intro/zipball/master