Who Broke the Build?

Continuous Integration and automatic builds are fantastic tools for software teams, but only if developers take responsibility for their code. Karsten Kempe explains how to use Team Foundation Server to drive better continuous integration, and walks through a simple (open source) tool he built to make nightly builds more transparent, and more valuable.

Automatic build mechanisms, such as those available with the Team Foundation Server (TFS) 2013, have become paramount for development projects. Automatic builds support day-to-day tasks within development teams, helping them to write high-quality code and integrate a host of different software modules.

Having huge teams of developers in different departments working on a host of modules and only merging everything to form a single integrated project towards the end of the development period may lead to some sleepless nights, thanks to all-too-common problems:

  • You’re unable to integrate modules that have been developed individually, and which were intended to form a unit.
  • You’re unable to use allegedly simple interfaces because the author checked in a modification shortly before the deadline.
  • And the release date is approaching quickly.

Thankfully, processes like nightly builds are able to check the quality of the most-up-to-date code and give developers rapid feedback on each day’s work. Such a feedback option naturally brings benefits and has the potential to boost the source code’s quality – but only if it is taken into account and only if developers take responsibility for their code after check-in.

With great automation comes great responsibility

Continuous integration (CI) and the use of suitable tools (e.g. TFS 2013) enable us to take better control of some of the complex processes of software development, and source code integration is just the first step. I tend to focus on TFS because it’s an integrated ALM platform with VC and Build in one engine, plus rich APIs to extend the system. Hudson or Jenkins are other excellent build systems for continuous integration, but I’m just not as familiar with them.

Whichever tools you choose, before you start down this route, you need to acknowledge that automatic builds are only as useful as your ability to act on their output. They give immediate feedback on the current software quality and the integration level of all modules but, if you want any of the benefits that leads to, your whole team needs to acknowledge and act on the results and take responsibility for fixing broken builds.

In this article, we’ll look at ways of enhancing the visibility of continuous and nightly build results, knowing who needs to be responsible for fixing broken builds, and encouraging your team to make working software their top priority.

Two types of build

If you’re not familiar with CI and build automation, let’s start with the basics – builds can be “personal” or “impersonal”, and neither is inherently better than the other. You really do need both types to get a really good handle on your project and, while they each have their own unique problems, they also share at least one common issue – visibility (or, in extreme cases, enforceability) of feedback. To explain that a little more, and introduce some solutions, let’s look at what I mean when I talk about these different builds.

Continuous integration builds

Personal builds are usually triggered by developers, and they give feedback which is crucial to the individual. As a rule, continuous integration builds – also known as CI builds – are always triggered when developers try to commit source code to version control. They comprehensively check the status of the source code that is available in version control immediately after the check in, giving feedback regarding that code’s suitability for compiling and testing, or the code quality.

One drawback of this build type is that potentially negative feedback can be ignored by developers, meaning that corrupting source code can pass into version control and subsequently damage the overall system. And by damage I mean things like an inability to compile the current version, failing test cases or generally poor code quality.

The so-called ‘gated check-ins’ available on Team Foundation Server are intended to solve this drawback. This build type inspects the checked-in source code before it is added to version control and, as a result, it even becomes a little more personal as potentially only the triggering developer’s source code is (in)validated.

2048-1f00529b-b1fd-4482-9c09-c855d638596

In the event of negative feedback from a gated check-in, the source code is rejected from the version control system, prevent the developer from contributing to (or rather, damaging) the overall system, and forcing them to adapt their code to meet their team’s requirements.

To try and offer a broad overview, I did do a little searching to see if I could find similar functionality in other Build / CI systems, but a brief Googling didn’t yield any results. If I’ve missed something, leave me a note in the comments & I’ll update the article!

Scheduled builds

Scheduled builds, also called nightly builds, are what are referred to as impersonal builds, as they check all the code that has been checked in on that day by various developers or departments. They’re often run at night because all code commits must be checked for integrity, and an enhanced set of automatic tests is typically also run on the whole system. This often results in longer build and run times and increased build server loads, making night-time runs the ideal solution.

The feedback from these builds tends to be global and impersonal and, for this reason, it is too-often ignored. To me, it sometimes seems as if developers think “It’s OK, someone else will fix it” and, while it’s almost never down to maliciousness, it’s still a real shame. It has a negative effect on the overall concept of global feedback and, more importantly, puts the quality of the code at risk. In the long-term, such attitudes may also put the whole software release at risk.

A question of motivation

With this issue in mind, one may need to think of how to motivate a team of developers to take more responsibility or, in extreme cases, even force them to engage in a process that will only work if everyone collaborates (i.e. continuous integration, build automation, and being part of a development team!) In addition to repeated reminders of how important things like ‘team spirit’ and build feedback are, I also suggest optimising the available information to make it harder to ignore, and I’ll come to that in a moment.

As a rule, TFS provides a host of options to obtain information and monitor builds (e.g. TFS Web Access, Team Explorer in Visual Studio, Build Notification Client, etc.), but sometimes even this doesn’t seem to be enough. Admittedly, it’s not realistic to expect to boost team motivation with just a few neat tools and automatic processes – you need to factor in things like organisational culture, your team’s personality dynamics, and working environments to name just three major influences.

I obviously don’t have the space to discuss those human factors in this article, so for how we’ll look at a simple technical solution that might be able to influence some of those team dynamics. It’s basically just a service you can implement to optimize the information being made available to your team, and increase transparency.

The build notification service

In the 02/2014 edition of dotnetpro (in German), Andy Grothe writes about build status information requests using the TFS-API. This article inspired me to create a simple tool – simply called the Build Notification Service, and available on GitHub – to read out nightly builds from TFS 2013 units, write the information in HTML format, and then distribute the information by email to all developers using Microsoft Exchange Services.

The goal for this is simply to make the results of impersonal builds widely visible, and thus harder to ignore / easier to act upon. I’ll come back to how this service changes team behaviour in a moment, but first I’ll run through how it works.

2048-309bcc70-f61b-4679-827a-ed5edc5bc23

Under the hood

The Build Notification Serviceis a .NET console application that is run on the TFS app tier as a scheduled task – it uses the TFS client API to establish a connection to the Team Foundation Server, and then uses the service uses the TFS client object model to access the build information of a TFS team project. The service then reads out all completed build definitions of the last 24 hours and sends the results to every user on an email distribution list in html format using the exchange web services. Very simple in execution, but a remarkably effective way of ensuring that the whole team is consistently made aware of nightly builds, and so there are no excuses not to discuss the results and agree actions!

2048-11be6a11-d7bb-42ab-a88d-c3c22e468d9

Let’s take a look at how it works…

Establishing a connection to TFS

To start with, we need to request the required information from the TFS build service. This is triggered using an instance of the TFSTeamProjectCollection class that employs the GetService(Type) method which, in turn, allows you to load an instance from the IBuildServer:

All the required parameters, such as the collection URL or the Team Project Name, are read out from a configuration file and transferred.

Requesting build details

Once the TFS build service has loaded successfully, an IBuildDetailSpec build detail specification allows us to restrict the selection of build results to be loaded. For instance, the specification lists the team project build definitions that are searched, as well as the number of builds that are searched per definition and the sort order of the expected result.

At this point, the InformationTypes parameter within the build detail specification is particularly important. This parameter enables us to control the requests’ depth and to filter out obsolete information in advance, reducing the response times. Explicitly set it to ZERO and neither associated work items nor associated change sets or error details are read out by the build service, which will drastically reduce the response time of the QueryBuilds methods:

Processing build information

The request results are saved in the IBuildDetail type buildQueryResult.Builds array, evaluated in sequence for further processing, and then inserted into an html template. The html template used is relatively primitive and structured as follows:

Each individual placeholder is replaced by a value from the build results array, and this procedure is repeated for each completed build definition within the array. Once all parts of the html template have been completed, they are added to a larger html template and emailed to the team.

Using the exchange web services

Emails from the build notification service are sent using the managed API of the exchange web services (EWS), which provides a relatively simple object model to send messages. I recommend you take a closer look at the “Get started withthe EWS Managed API”MSDN article for more detailed information on the exchange web services.

The exchange service must be instantiated and the relevant authentication credentials must be set before you send the first email. In this example, we use default credentials because the application is run within the domain and the messages are sent using an on-premise exchange server:

In a last step, we set the service URL and complete initialisation. In this case, the AutodiscoverService is used to load the user settings of the current AD user – a valid URL can then be taken from its response and used by the EWS:

The remaining steps are pretty straight-forward – the EWS instance creates an EmailMessage and the system adds the corresponding information. The html template including all build definitions is used as the email body, and recipients are read and added from the configuration.

The trick with status images

The status placeholder from the html template is only filled with one content ID (e.g. cid:picOK) to visualise the build status in the email. Said content ID is linked to an email attachment with the same content ID shortly before sending the email and, as a result, the system replaces the text from the html template with the attachment and a status image.

Recurring morning task

As I mentioned earlier, the goal of all this is to give developers consistent, visible feedback on the previous night’s build runs. The Build Notification Service is a client application that uses the TFS client object model and, for this reason, the application must be run on a computer which has Visual Studio installed. The easiest way I’ve found is to create a daily task in the task scheduler to start the console program.

Transparency is good for business

Once everyone on your dev team is getting daily status updates for all relevant nightly builds, everyone theoretically has the same level of information available to them. However, emails are patient and can be ignored, moved or deleted, which makes them only as good as any other information medium. Team members that have always taken responsibility for the overall status of their project are happy about the additional information, and others can still try to avoid taking responsibility.

At the Manage Agile 2013 Conference in Berlin, Uwe Henker held a presentation entitled “Human Factors and SCRUM”, where he described how transparency and visualising results can, in fact, trigger improved results within the “overall system” (naturally including the team itself). On this basis, the Build Notification Service was recently enhanced to make it even more transparent.

The service now also tries to determine which development team is potentially responsible for a failed build, and distributes this information as part of the daily status email. This process is less about finding a guilty party and more about identifying the first port of call for troubleshooting – it’s intended to identify someone that is responsible for assessing the situation, as the error occurred somewhere in their code.

Such a process is relatively simple to implement – the build service just needs to request the build details for a certain build definition:

The build status is checked after having loaded the build details and, if it’s not OK, the system searches through the list of potentially responsible persons for the most likely trouble-shooter. For this purpose, the WhoBrokeTheBuild() method requests and evaluates the build errors from the build definition:

The name of the person or team responsible is shown until the error is rectified or the name is replaced by another responsible person or team (i.e. a new error case appears.)

Summary

I can happily say that, a few weeks after the introduction of these build status emails at one of our customers, this new transparency has led to a slight increase in quality. Builds are more stable and any occurring faults are quickly rectified. However, I can also say that as soon as the service is unable to find a responsible person or team, we’re still rolling back to a situation where no one voluntarily takes responsibility, and our troubleshooting process suffers delays as a direct result.

So, where does that leave us? Firstly, we have established that the build notification service has plenty of room for improvement and, secondly, we can say that software quality is generally only as high as its developers’ motivation. Hopefully the two tools I’ve described here will help you increase feedback visibility in your teams, and help encourage developers to acknowledge when it’s their responsibility to improve the quality of their code and, ultimately, be part of a team.

Next steps and potential enhancements

Admittedly, the build notification service is not the cleverest, as it currently only monitors a single team project and is also unable to distinguish between teams. As a result, it’s currently not possible to focus and channel the information, so a viable enhancement for the future would be to integrate an option to configure team and team project monitoring.

A further enhancement would be to do away with classic distribution lists which are currently saved in the configuration file. If we consider the team idea from the first enhancement, it may also be beneficial to write a mechanism that reads out the members of the corresponding team, determines their email addresses and sends them the relevant build information.

If you’ve got any ideas or suggestions, I’d love to see your suggestions on the GitHub project, or leave a comment – I’d love to hear from you!