Karl Seguin

Sponsors

The Lounge

Wicked Cool Jobs

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
TDD Lesson 2 - Continuous Integration
I hate to digress from the raw TDD discussion so early on, but if you're serious about TDD, you have to consider whether continuous integration (CI) is right for you or not. Even if you aren't doing TDD or unit testing, many teams will find CI useful. For example, if your team is split up across the world (or even the country) the last thing you want is for Team B to have to deal with Team A's broken build. Of course, CI isn't only useful for geographically challenged teams. If I had to guess, I'd say you'll easily make up the initial time investment.

For n00bs to CI, the point is to ensure your code is always buildable and that all unit tests always pass. Basically, a CI solution hooks into your source control server, detects that a change was made, and rebuilds/retests your code automatically. The most common solution, CruiseControl.NET comes with a system tray utility that warns you when something goes wrong. In other words, if anyone breaks a build or makes a test fail, you're little icon turns red and you'll get a bubble warning. From there, you can opt to see detail information about what exactly failed and fix it!.

CruiseControl.NET simply monitors your source control repository, it's NAnt that actually builds and runs your code. The last time I was personally responsible for setting up NAnt was a couple years ago and it was a real pain. Now I see that they have a Solution task that makes everyone's life easier. The last thing I want to do is write a tutorial for CruiseControl.NET and NAnt, but I do want to share my configuration files, in case they help someone else


<project name="OLMD" default="build" basedir=".">
 <property name="releaseMode" value="debug" overwrite="false" />
 <property name="baseDir" value="c:\builds\" overwrite="false" />
 <property name="deployDir" value="${baseDir}olmd\" overwrite="false" />   
 <property name="reportDir" value="${baseDir}reports\olmd\" overwrite="false" />      
 <property name="projectDir" value="${deployDir}\olmd\" overwrite="false" />         
 
 <target name="build">
  <vaultgetfile url="http://s1"
                username="username"
                password="pass"
                repository="Fuel"
                path="$/1/Fuel/"
                destination="${deployDir}/Fuel"/>

   <vaultgetfile url="http://s1"
                 username="username"
                 password="pass"
                 repository="Fuel"
                 path="$/1/Olmd/"
                 destination="${deployDir}"/>
                    
  <solution configuration="${releaseMode}" solutionfile="${projectDir}\olmd.sln" />
     
  <call target="test" />
  <call target="clean" />           
 </target>

 <target name="clean" description="remove all generated files">
  <delete dir="${deployDir}" />
 </target>
   
 <target name="test" failonerror="true">
  <nunit2>
   <formatter type="Xml" usefile="true" extension=".xml" outputdir="${reportDir}" />
   <test assemblyname="${projectDir}\olmd\bin\${releaseMode}\Fuel.Projects.Olmd.dll" />
  </nunit2>
 </target>
</project>


Basically, the Build target (which is default), checks out 2 projects from Vault, and uses the wonderful Solution task to build everything. The Test target then uses the nunit2 task to run my unit tests with all reports sent to a global report directory. Finally, everything's cleaned up.


The CruiseControl.NET configuration is even simpler (mostly because I copied and pasted most of it from the CC.NET website):

<cruisecontrol>
 <project name="OLMD">
 <webURL>http://s2/ccnet/</webURL>
 <triggers>
  <intervalTrigger seconds="30" />
 </triggers>
 <modificationDelaySeconds>10</modificationDelaySeconds>
 <sourcecontrol type="vault" autoGetSource="false" applyLabel="false">
  <executable>c:\program files\sourcegear\vault client\vault.exe</executable>
  <username>user</username>
  <password>pass</password>
  <host>s1</host>
  <repository>fuel</
repository>
  <folder>$/1/</
folder>
  <ssl>false</
ssl>
  <useWorkingDirectory>false</
<useWorkingDirectory>
 </sourcecontrol>
 <tasks>
  <nant>
   <
executable>C:\builds\Nant\bin\nant.exe</executable>
   <baseDirectory>C:\builds\Nant-Config\</
baseDirectory>
   <
<buildArgs/>
   <buildFile>olmd.build.xml</
buildFile>
   <targetList>
    <target>build</target>
   </targetList>
   <buildTimeoutSeconds>300</
buildTimeoutSeconds>
  </nant>
 </tasks>
 <publishers>
  <merge>
   <files>
    <file>C:\builds\reports\olmd\*.xml</file>
   </files>
   </
merge>
   <xmllogger />
  <
/publishers>
 </project>
</cruisecontrol>


Here we tell CC.NET to use Vault and how to use it (you can get this extension from SourceGear's website for free) and tell it what to do when it detects a change - namely to run our NAnt build script above. The last thing to do is point it to the reports NAnt created.

I seem to remember this being a much bigger pain to set up, but this time it didn't take more than 1/2 an hour to set up (I had a bug in CC.NET which I eventually fixed by disabling all versions except 2.0). With CI in place, we're ready to continue TDD'ing.


Posted Mon, Jun 26 2006 10:26 AM by karl
Filed under:

[Advertisement]

Comments

Jeremy D. Miller wrote re: TDD Lesson 2 - Continuous Integration
on Mon, Jun 26 2006 3:31 PM
It did used to be much more difficult, but the CC.Net team has done a tremendous job making the configuration easier.  2-3 years ago it took me a week to get CC.Net up and running against CVS building web service projects.  The last time I did it from scratch it only took a couple of hours for everything.

Once you get past the CC.Net/NAnt configuration, here's an older post about CI etiquette --> http://codebetter.com/blogs/jeremy.miller/archive/2005/07/25/129797.aspx
randy.kibbe wrote re: TDD Lesson 2 - Continuous Integration
on Tue, Jun 27 2006 9:23 AM
After several attempts and false starts I got Nant workingon our older projects. Certainly the difficult part is converting .sln files. There is a Nant-contrib task called convert that works reasonably well., not so well 2005 files.  

We are moving towards CruiseControl. My question is does the Nant task:<solution configuration="${releaseMode}" solutionfile="${projectDir}\olmd.sln" />
work with CruiseControl and Nant for 2005 files. The Nant release notes say it does not for 2005 sln files.

Any suggestions if it doesn't ? Converting by hand is painful.
karl wrote re: TDD Lesson 2 - Continuous Integration
on Tue, Jun 27 2006 11:59 AM
Randy:
The docs make a point of saying it's 2002/3 only, so it probably is. Maybe this will help you though:
http://weblogs.asp.net/soever/archive/2006/05/18/447014.aspx
Jeremy D. Miller wrote re: TDD Lesson 2 - Continuous Integration
on Tue, Jun 27 2006 3:21 PM
You're going to have to go to MSBuild for compiling a VS2005 solution.  You can either go all out MSBuild, call MSBuild from NAnt, or CC.Net can be configured to kick off multiple build files at one time for exactly just this scenario.

It's fugly, slow, and leads to a tainted build, but you *could* use Visual Studio from the command line to do the compile from a NAnt "exec" task.
Jason Haley wrote Interesting Finds: June 27, 2006 PM edition
on Tue, Jun 27 2006 5:11 PM
randy.kibbe wrote re: TDD Lesson 2 - Continuous Integration
on Wed, Jun 28 2006 11:22 AM
Thanks for both of your inputs. Have you guys manually converted solution files before. A good learning experience, but quite a slow and tedious effort required.

We are also implementing Microsoft Team Foundation. I will probably have to have MSBuild call NAnt for now. I am partial to having NAnt handle all the tasks and in one build file. It is much more transparent and easily configurable. Till someone smarter than I upgrades NAnt-contrib to handle 2005 Visual Studio that is where I am .
Technical Related Notes » Blog Archive » links for 2006-06-28 wrote Technical Related Notes &raquo; Blog Archive &raquo; links for 2006-06-28
on Wed, Jun 28 2006 10:40 PM
Sam Gentile wrote New and Notable 106
on Thu, Jul 6 2006 12:10 AM
I had yesterday's N&amp;amp;N cut short with a trip to the Jersey Shore. After a fine cookout day yesterday,...
Devlicio.us