Takeaway: When a commit takes place against the source control repository, a separate, objective, and impartial system should execute an automated build process and report the build result.
By now, you're probably scratching your head and asking "Why do I need to go through all this hassle again?" Some of it can be pretty trying at first. But after you've done it a few times, you'll find it's quick to set up. There are tons of example build scripts online that you can grab to help you get started. Testing, depending on how far you go with it, can really pay dividends in the long run, but make no mistake—it is an investment.
You'll get the maximum payoff from the topics discussed here when you perform them frequently and make them part of your routine. Adhering to the build and testing cycle takes discipline, but soon becomes a habit. It's like safety belts: At first they can be rather uncomfortable and annoying, but soon you don't even know they're there, and eventually, you can't imagine ever not wearing one. One of the best ways to get yourself and your team to stick to the discipline is to increase the visibility of the tasks, making a computer do them for you and report status.
The easiest way to accomplish this is by using what's known as "Continuous Integration." That is, the build gets run every time someone on your team commits code to the source code repository. Any compile errors, test failures, or other problems will be more visible, and helps raise team awareness—and that raised awareness helps remove friction and roadblocks, and eliminates confusion about why a build failed. As time progresses and developers gain trust in the process, successful builds can be made available as deployment packages for testers or managers to review to keep track of the team's progress.
There are two popular software packages in the .NET space that provide continuous integration services: ThoughtWorks' CruiseControl.NET, which is free/open source and JetBrains' TeamCity which is a commercial product (i.e., not open sourced), but is free for small or medium teams (see the licensing terms for more information). TeamCity offers some compelling features over CruiseControl.NET, including simpler setup, a more user-friendly interface, and the ability to run a build on three different computers simultaneously. JetBrains calls the build computers "agents." The neat thing about agents is that they can be running on different platforms with different configurations. For example, you could run your build and tests against SQL Server 2005 on Windows 2000, Oracle 9i on Windows Server 2008, and MySQL on Windows Server 2003. There is a limit to the number of projects you can host in TeamCity and the number of build agents you can use before you have to pay for the software. But for most purposes, the free version of TeamCity provides plenty of room plus some for expansion. I recommend you use TeamCity to get up and running. If you outgrow the free version of TeamCity you can decide whether you want to pay for the enterprise version or move to CruiseControl.NET. At that point, you'll have more experience with Continuous Integration, and the decision will be easier.
Before getting into the "How" you may want to know more about the "Why," so I recommend you read Jeremy Miller's article on Continuous Integration.
Preparing a Integration Box
You can use just about any Windows XP or later computer to run the integration and build; Windows Server 2003 and 2008 work fine also. Depending on which version of Windows you have and what type of project you're building (.NET 2.0/VS2005 or .NET 3.5/VS2008), you'll want to make sure that you have .NET 2.0 and the 2.0 SDK installed. If you're using .NET 3.5/VS2008, make sure that the .NET 3.5 Framework as well as the Windows SDK 6.1 (which includes the .NET 3.5 Framework SDK) are installed.
|Author's Note: I strongly advise you not to install any version of Visual Studio on your integration box. It may make setup a little easier, but doing so eliminates most of the impartiality that the integration box brings to your environment.
Also, NAnt 0.86 currently has an issue when running on Windows Server 2008 that you can easily fix yourself. To do that, download the latest NAnt build (0.86 nightly or later) and use that in your tools\NAnt folder. Open the NAnt.exe.config file in a text editor and find where it references the "v6.0A" version of the Windows SDK. Change that to "v6.1" to make it work properly with the Windows Server 2008 and .NET Framework 3.5 SDK (Windows SDK v6.1). After you take these steps, your NAnt build should run fine on Windows Server 2008.
Setting up TeamCity
|Figure 7. TeamCity Installer Options: If this is your first time installing TeamCity, accept all the defaults.|
At the time of this writing, TeamCity 3.1.1 is the latest available version, which you can download here
. Make sure you get the Professional (free) edition. Run the installer (see Figure 7
), and (at least your first time) accept all the defaults. Later, you can specify build agent and work folder paths on different disks as your needs demand. At first, keep things simple.
When the TeamCity installer completes, you'll see a configuration screen (see Figure 8) that lets you change the basic configuration settings. The default settings are usually fine and you can safely click Close. You'll see a Finished screen that provides the option to open the web management site for TeamCity. Click Finish and wait for the web management site to load for the first time. Finally, you'll need to create the administrator account for TeamCity's web management application. When that's done, TeamCity is officially installed and you can begin adding new projects.
|Figure 8. TeamCity Advanced Options: You set basic configuration settings on this screen, but the default settings are usually fine.|
Configuring a Project in TeamCity
Click the "Create Project" link to get started. Give your project a name and a brief description and click the Create button.
You'll need to create a "Build Configuration." A configuration defines your version numbering scheme, the products of your build (TeamCity calls them "artifacts"), and how to interact with your source control system for this build. For now, add a new build configuration with a name. Leave the rest alone and click the VCS Settings button.
Attaching the Project to Subversion
|Figure 9. Connecting to Subversion: The settings shown here illustrate configuring TeamCity's connection to a Subversion server.|
Next, you need to tell TeamCity about your Subversion source control repository, so it can begin listening for changes and take appropriate action. Click the "Create and attach new VCS root" link to enter the details of your Subversion repository (see Figure 9
). Make sure that when you end your Subversion repository URL with /trunk
to prevent TeamCity from grabbing all the branches and tags every time you run a build (see the sidebar "Trunks, Branches, and Tags
"). At this point I suggest that you fire up your Visual SVN Server admin console program and add a new user for TeamCity to use when connecting to SVN. While not required, that can help later with logging and access to the system.
This configuration screen shown in Figure 9 has many options. For now, I recommend leaving all alone. You can configure them later if necessary. However, make sure you click the Test Connection button and, finally, click Save when you're done.
Clicking Save from the screen shown in Figure 9 takes you back to the "Build Configuration" screen, at which point you should click the "Choose Build Runner" button to begin telling TeamCity what to do with your source code, now that it has access to your repository.
Configuring the Build Runner
On this screen, you tell TeamCity how to run your build. TeamCity supports many different types of build runners including NAnt. Choose NAnt as the runner. In the "targets" textbox, type "package." Next, change the NAnt Home option to point to your tools folder using a special variable that TeamCity has to identify where the current code that's being built and tested actually resides. This is a transient working directory, so you can't simply hard-code it. Placing the value %system.teamcity.build.checkoutDir%\tools\NAnt
for the NAnt Home option will keep things properly relative. This ensures that TeamCity is using the version of NAnt that you want for your specific project. If you ever change your version of NAnt, you won't have to update the build server. Finally, click Save to complete this screen.
At this point, you have a basic CI environment complete with source control, automated build, test, and deployment and continuous integration among the developers.
Set Build Triggering
|Figure 10. TeamCity Project Status: When TeamCity completes a build, it lets you know how many tests passed.|
One last setup step you should consider is setting up the build so it launches automatically when someone commits files to the Subversion repository. This is normally how CI works, but in TeamCity this option is off by default. On the right-hand side of the screen, when editing the Build Configuration, step number 4 is "Build Triggering." Click this step and then check the checkbox to enable triggering.
You may also want to consider a "quiet period" of 60 seconds or so, which helps handle the case when many people commit code at nearly the same time, which would otherwise trigger many builds.
Testing the Build
To test that the build is working, pick a file and save it (add an empty whitespace somewhere, etc.). Commit the file to Subversion. Open the TeamCity web application and click on the Projects tab. After a minute or two, you should notice that your project has an active build running. With everything configured correctly, the build will complete successfully (see Figure 10) and let you know how many tests passed.
Repeatability is all about reducing friction, surprises, and lost work due to otherwise preventable problems. While there is some startup cost and pain involved when introducing repeatability into your development process, the return on investment is fast and leads to a sustainable pace of success well into the future.
Finally, you don't need to apply every recommendation here at once. You can add them incrementally. I encourage you to give some of them an honest try and see how well they benefit your environment and affect your bottom line.