Channels ▼
RSS

.NET

Clever Hax: Broadcasting Build Notifications from TFS


A build notification tells you the results of a build. Did it succeed? Did it fail? And if it failed, why? And which module caused the failure? Continuous integration (CI) servers have a rich notification repertoire. Windows tray icons, e-mails, instant messaging, and IDE plug-ins are just some of the possibilities. This variety of options is a proof for the thesis that build notification is one of the most important parts of CI.

In fact, it's so important that some CI practitioners sacrifice an additional monitor or even a whole machine to provide constant monitoring for the team. It's usually an old computer with an old monitor that stands in a visible place in the developers' room or some place where everybody can see it. The sole purpose of this machine is to provide the team with up-to-date information about the build processes. The dashboard page may refresh every few minutes, or special custom software may monitor the CI server. If your team can benefit from something like this, set it up. Or get geeky and use the following LED message board to provide a broken build notification.

Providing Feedback via an LED Message Board

An LED message board is a gadget that comes from a big family of crazy USB toys from the China Seas area. The one this example uses is a matrix of 7×21 LED lights sealed in a small black plastic casing (sometimes called a human interface device, or HID). If you aren't a USB geek, the only thing you have to know is that the HID driver makes it easy to interact programmatically with an HID-enabled device. If you want to buy one, search for "USB LED message board" or "scrolling USB LED message board."

Let's write a simple program that checks the state of the builds on a TFS server. If it finds a broken build, it'll display a blinking red circle on an LED message board. This display should be hard to miss if the board is in the developers' room.

First, let's find out whether the last build in a given build definition was broken. The following listing shows the details.

Listing One: Sniffing around the last broken build in TFS 2010 round the last broken build in TFS 2010

NetworkCredential Credentials = 
    new NetworkCredential("marcin", "password"); 
TeamFoundationServer tfs = 
    new TeamFoundationServer(
        "http://tfs1:8080/tfs/CiDotNet", Credentials); 
IBuildServer buildServer = 
    (IBuildServer)tfs.GetService(typeof(IBuildServer)); 
IBuildDetailSpec buildDetailSpec = 
     buildServer.CreateBuildDetailSpec(
         "CiDotNet.Ch4.Tfs", "Ci.CiDotNet.Ch4.Tfs"); 
buildDetailSpec.MaxBuildsPerDefinition = 1;
buildDetailSpec.QueryOrder = 
    BuildQueryOrder.FinishTimeDescending; 
IBuildQueryResult results = 
    buildServer.QueryBuilds(buildDetailSpec); 
if (results.Failures.Length == 0 
   && results.Builds.Length == 1) 
{ 
    IBuildDetail buildDetail = results.Builds[0]; 
    if (buildDetail.Status == BuildStatus.Failed) 
    { 
        MyLedNotify(); 
    } 
}

This example uses the Microsoft.TeamFoundation API to sniff for the latest build output. You use the Microsoft.TeamFoundation, Microsoft.TeamFoundation.Client, and Microsoft.TeamFounda­tion.Build.Client namespaces to first connect to the TFS server and team collection using network credentials (lines 1-7). Then you get the build server from the TFS instance and query it for a given team project and build definition (lines 8-10). You take only the last build result (lines 11-13) and check its state. If it fails, you turn on the big red dot (14-23); see Listing Two.

Listing Two: Using an LED message board to notify you about a broken build.

HidDevice MessageBoard; 
HidDeviceList = HidDevices.Enumerate(0x1d34, 0x0013); 
if (HidDeviceList.Length > 0) 
{ 
    MessageBoard = HidDeviceList[0]; 
    MessageBoard.Open(); 
    Thread.Sleep(1000); 
    byte[] Packet0 = new byte[] { 0x00, 0x00, 0x00, 
    0xff, 0xfe, 0xff, 0xff, 0xfd, 0x7f }; 
    byte[] Packet1 = new byte[] { 0x00, 0x00, 0x02,
    0xff, 0xfb, 0xbf, 0xff, 0xf7, 0xdf };  
    byte[] Packet2 = new byte[] { 0x00, 0x00, 0x04, 
    0xff, 0xfb, 0xbf, 0xff, 0xfd, 0x7f };  
    byte[] Packet3 = new byte[] { 0x00, 0x00, 0x06, 
    0xff, 0xfe, 0xff, 0x00, 0x00, 0x00 }; 
    for (int i = 0; i < 10; i++) 
    { 
        MessageBoard.Write(Packet0); 
        MessageBoard.Write(Packet1);  
        MessageBoard.Write(Packet2);  
        MessageBoard.Write(Packet3);  
        Thread.Sleep(50); 
    }
    MessageBoard.Close(); 
}

This example uses a generic .NET HID device library from Mike O'Brien. The library provides a way to connect and use any HID-enabled device. All you have to do is to get a manual for the interface used in this device. The manufacturer of our LED message board was kind enough to provide one when asked.

To connect an HID device, you have to find it using a unique identifier provided by the manufacturer (lines 1-2). After you find the device, you must connect to it (line 6) and wait a while for the hardware to snap in. Next, you define the big red dot using a report formatted according to the manufacturer's interface description (7-16). For now, you'll have to believe us that the lights form a big red dot on the LED message board. You then send the light definition to the device (17-23), after which the device will look like the one shown in Figure 1. The packets sent to the LED message board light up the device for only a few milliseconds, so you have to refresh the signal to light it up periodically.

[Click image to view at full size]
Figure 1. LED message board blinking with a red eye to indicate a failed build.

It doesn't cost much to provide a new way to notify your team about a problem. Buying a flashing emergency vehicle roof light and installing it in the developers' room is an even better idea (of course, including the siren!). But because the Taiwanese LED device is a lot cheaper (around $10-$20), you can start with it. It's that important to react immediately to a broken build.

What if the blinking lights, emails, and sirens aren't doing the job? How about something more intrusive? Send an SMS message to every team member.

Providing Feedback via SMS Notifications

It's a scary idea to send someone an SMS message with a build notification. But what if you're on vacation climbing Mount Kilimanjaro and you want to know if your team is dealing with the broken build fast enough? No problem. You can take the easy route and send yourself an SMS message using Skype and an online computer in your office. Here's how.

Skype provides a COM library to automate some of its tasks. One of the methods provided by this API is SendSms, which we'll use here. This method requires you to have Skype installed and some money in your Skype account because, unfortunately, SMS isn't free.

You can download the Skype library here. Check the Tools and SDK area. To do the build-state sniffing, you can use a variation of the program shown earlier in Listing One. The hitch is to detect only the change in the state of the build from successful to broken, and then send one SMS message. After such an event, it's a matter of implementing the following code to send the SMS message:

Skype Skype = new Skype();
if (Skype.Client.IsRunning)
{
    Skype.Client.Start();
}
Skype.SendSms(PhoneNumber, Message);

From now on, you can sleep well, knowing that an SMS message will alert you if something goes wrong with your build. Isn't that comforting?

Summary

Access to immediate and accurate information about the state of your build process is vital to your CI quality. The faster you get the information about a change in the quality of your source code, the more quickly you can react to fix the problem. The faster you fix the problem, the better your team will work. You'll know where you journey is taking you and whether your project is starting to veer off the road. In this article, we discussed how to extend your build notifications.


— Marcin Kawalerowicz works for European customers in the automotive and financial sectors, among others. He blogs at iprogrammable.com. Craig Berntson is a Microsoft MVP. He blogs at www.craigberntson.com/blog. This article was adapted with permission from the authors' recently released book, Continuous Integration in .NET, published by Manning Publications.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video