Latest Posts »
Latest Comments »
Popular Posts »

Build Automation: The Best Thing Since Sliced Bread

Written by Kendall Miller on May 26, 2008 – 12:06 am

Editor’s Note: This is the second article in a three article series, with a new article posted every few days.

In the last 15 years, software development tools have advanced significantly. More than language or runtime, the modern integrated development environment is an amazing productivity tool. You don’t even have to spend money to get this benefit - check out Eclipse and its ecosystem for a free and powerful tool. Combined with the extraordinary processor power of modern desktops, you can do things today that just weren’t feasible 15 years ago. In many cases, this is a great improvement, but it has come at a cost: When you can compile even a large project and debug it in tens of seconds instead of 30 minutes it tends to take you away from the good Mom and Apple Pie aspects of having a tight build process and not doing development by debugging.

Benefits of a Build System

When you have a common means of performing each build, you get a number of advantages that will pay off for your team.

  1. Consistency: Without a doubt, the greatest benefit is that each build is consistent and you know that it is consistent. Both pieces are important. You will be able to dismiss with confidence questions about the accuracy of the information that indicates what exact source code was used to make each build, what defects really were fixed in each build, etc. This is particularly powerful because it is most useful when the team is under maximum stress: rapid fire builds under pressure, when there are multiple builds in play at various stages of certification, etc. It’s in these situations that you have to be able to absolutely trust that the records are accurate or you will burn a significant amount of time across your team verifying what was in each build. This is waste effort when you can tolerate it least.
  2. Knowledge Containment: Each developer doesn’t need to know the details of building the entire system. Usually only one developer needs to know the packaging and release details, numbering scheme, etc. Individual developers only have to know at most what it takes to add their new project to the build process. When a new member joins the team, they can get up and running fast and start contributing without having to take on the whole beast right away. When you come back to the system six months after it shipped and need to make one change, no one needs to remember all of the intricacies of creating a full build.
  3. Change Management: Whenever a new output file is added or a change needs to be made to how the application is built, the build will need to be updated. By insisting on an automated process you ensure that each change has to be fully addressed before the build can be tested. This will force issues to the surface earlier in the process when the team will tend to be under less stress instead of later when the team is under tighter deadlines.
  4. Time Savings: Running a build is generally an annoying waste of time. If you take on that a build includes all of the steps we discussed in the first article in this series then even for a simple project it’s going to take a minute, but for a project of real complexity it will tend to be 10 minutes or more. More is actually better in this case because it represents more human actions that are automated into the build. If the build is happening on the developer’s system then the time savings is limited - the developer will generally be idle while the build is running. The time saved in this case is the time for a human to manually perform each step vs. the computer, perhaps 40% of the total time.

Benefits of Centralization

This part is often more controversial, but has become accepted more and more as a best practice. Many have argued that you should automate the build, but make it so each developer can run the build on their system. This was relatively straightforward in the good old days of “make”, but there are several advantages to centralizing builds for modern applications.

The big benefits of centralization are:

  1. Forced Standardization: We’ve all had the experience of two computers building the same source code and not producing the same binary images. This is generally due to small differences in the software installed on each system that the build is referencing. It probably won’t hurt you, but it might - and the more third party items you reference the higher the odds it will. Instead, by building on the central server you can ensure that if there’s a new version of a common library you know exactly what one is being referenced by the build. You know that you only have to update it in that one place for it to go out, not on each developer’s system.
  2. No Cheating: Let’s face it, it’s tempting - any individual developer will be tempted in the right circumstances with short cutting a build on their system, perhaps swapping one file into the output directory and just re-running the packaging step to get a new distribution. If it’s on a central system that few if any have direct access to then you know for sure each build came from the full, correct process.
  3. Major Time Savings: With the build happening on a central system, the developers are free to do whatever they want while it’s running. They can continue to do extended unit testing waiting for the build to complete, or move on to entirely new functionality. The build should be designed to pull its source code immediately or otherwise ensure that it’s protected from changes checked in while it’s running to make this possible.
  4. Central Objective Metrics: With a central build who’s status is published to everyone, the entire team knows if the system currently builds or doesn’t. It establishes a central point to look at to get a quick understanding of where the team is. After all, your customers don’t care if your personal code compiles, they’re buying a whole solution which requires a full build work.
  5. Workstation Decoupling: With a central build process, it isn’t necessary for any individual workstation to be capable of building the entire system, they just need to be able to build their part of it. This can be very handy in several circumstances including reduced licensing costs for third party components by segmenting developers by subsystem and reducing the overhead of upgrading referenced components because individual workstation inconsistencies aren’t an issue unless the developer’s run into a defect in the course of the work they’re performing. This is particularly handy during maintenance when a developer has moved on to a new project.

Not all of these benefits will apply to every operating system or application type. In fact, it seems this discussion is most frequently had in Windows development teams. This may well be an artifact of the tendency for Windows environments to be more distributed than Unix environments with centralized builds being more the rule than the exception on Unix.

Best Practice: Continuous Integration

When you’ve created a fully automated build and then centralized it, you’re dangerously close to a best practice called Continuous Integration. Continuous Integration builds on the concept that if the entire build is automated, and it can be done on a central server, then each build is free. The only potential cost of a build is the risk that you’ll make a change while the build is running and want to start another build of the same project. If you’re coming from a world of expensive and time consuming builds, this is a revelation.

  1. If builds are free, do a new build every time someone checks in a change. Now you’ll know right away if that change breaks something, and you’ll know that a build reflects the latest code changes.
  2. If builds are free, let anyone trigger a build. If someone just isn’t sure if a change made it in, or you made a change to the build server, or you just want to see an updated test run, or even just want to make the lights on the server blink faster - do a build. No harm, no cost.
  3. If builds are free, anything the build does is free. Seems obvious, but follow me on this one: Anything you can teach the build to do, it’s free. Why not have it run some automated tests on the software? What about uninstalling the old version from your test environment and installing the new one? How about some performance tests? Notify the development team of new builds? Move defects that are claimed resolved in the new build to the next workflow state so they get tested?

Automated Testing

We’ve found it always an uphill battle to introduce automated testing into development teams that aren’t currently doing it. Automated testing is often viewed as a post-developer action that automates what manual testers would otherwise perform but we believe this misses the point. Usually the highest benefits from automation don’t come from slavishly automating the exact process that is done manually but instead looking at what you could do if the whole process was automated. For example, no human is going to completely regression test an application for a minor change, it is simply too time consuming. It may not be feasible to perform an accurate regression test purely using the public, published surface of the product either.

Instead, look at introducing automated tests into the development process itself. Don’t get hung up on whether they are automated unit tests or system tests or just make you feel happy tests. We’re big fans of using NUnit/JUnit to get developers to start writing good, idempotent tests in parallel with their code. You can even use these when your software isn’t necessarily written in either .NET or Java, provided you can call it from .NET or Java. Most automated build systems can intrinsically talk directly to NUnit/JUnit, and if not they can call a command line to invoke the test execution capability distributed with NUnit/JUnit. This means the developers get the benefit when they are writing the code that they can prove it correct, and you get the benefit of each of these tests being run every time the system is built.

Even if you don’t get into automated unit testing, consider writing just a simple script or executable that will smoke test the application. Then, have your build process distribute the fresh package to a test system, install it, and run the smoke test application. This should be part of the success/fail criteria of the build. This will give you a base level of confidence in the entire process nose to tail, and will encourage developers to add things to the test process because they know they’ll get benefit every time the build is run.

Coming Next: Great Results through Incremental Investment

In the final article of our series we’ll look at how to create an automated build incrementally and make it a natural evolutionary process of your team, providing both immediate and ongoing value. Really, it’s no joke and it’s not going to require upending your technology or team.


Tags: ,
Posted in Process, Software Development |

Leave a Comment