UppercuT - Automated Builds - CruiseControl.NET Integration

So now you are rolling with UppercuT, but you don’t yet have Continuous Integration (CI). You can make that happen with CruiseControl.NET (or any other CI server like TeamCity or Hudson).

This article is geared to CruiseControl.NET (CC.NET), although there will be future articles on other CI servers. This is specifically geared towards CC.NET 1.4 and above, because it takes advantage of preprocessors. First a few sideline notifications and then we'll get right into it.

 

UppercuT Compatibility with CC.NET Notice

To use UppercuT on CC.NET, you either have to install the .NET Framework SDK for 3.5 OR you can upgrade to the latest version which has a more recent version of NAnt. My recommendation is to upgrade to the latest version of UppercuT. You will get additional functionality, and it will work on CC.NET without you scratching your head. Now that was just uploaded last night, so if you are one of those that grabbed it in the last two days (or in the past), you'll want to get it again. http://code.google.com/p/uppercut/downloads/list

This is what the error looks like:

<message>             [property] Target framework changed to "Microsoft .NET Framework 3.5".</message>
<message>            </message>
<message>            BUILD FAILED</message>
<message>            </message>
<message>            INTERNAL ERROR</message>
<message>            </message>
<message>            System.NullReferenceException: Object reference not set to an instance of an object.</message>
<message>               at NAnt.Core.FrameworkInfo.get_Version()</message>
<message>               at NAnt.Core.Project.UpdateTargetFrameworkProperties()</message>
<message>               at NAnt.Core.Tasks.PropertyTask.ExecuteTask()</message>
<message>               at NAnt.Core.Task.Execute()</message>
<message>               at NAnt.Core.Project.InitializeProjectDocument(XmlDocument doc)</message>
<message>               at NAnt.Core.Project.Execute()</message>
<message>               at NAnt.Core.Project.Run()</message>
<message>            </message>

It will fail silently and you will have an interesting time figuring out why. It's because NAnt 0.86 Beta1 had a bug in it that has since been corrected.

 

CC.NET Preprocessors Side Note

Preprocessors have made CC.NET, in my opinion, one of the best products for CI. Basically you can define how you want a project structured, then to add and remove projects it is one line of code!

<cb:uppercut_svn_project projectName="Bombali" queuePriority="80" svnPath="https://bombali.googlecode.com/svn/trunk/" />

This article is not about preprocessors though. There is a really good resource for that here: http://confluence.public.thoughtworks.org/display/CCNET/Configuration+Preprocessor

 

The Configuration

<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
  <!-- http://confluence.public.thoughtworks.org/display/CCNET/Configuration+Preprocessor -->
  <!-- Common Variables -->
  <cb:define working_directory="c:\CodeBuild" />
  <cb:define drop_directory="c:\CodeDrop" />

  <!-- PROJECT STRUCTURE -->
  <cb:define name="uppercut_svn_project">
    <project name="$(projectName)">
      <workingDirectory>$(working_directory)\$(projectName)</workingDirectory>
      <artifactDirectory>$(drop_directory)\$(projectName)</artifactDirectory>
      <category>$(projectName)</category>
      <queuePriority>$(queuePriority)</queuePriority>
      <triggers>
        <intervalTrigger name="continuous" seconds="60" buildCondition="IfModificationExists" />
      </triggers>
      <sourcecontrol type="svn" autoGetSource="true">
        <trunkUrl>$(svnPath)</trunkUrl>
        <workingDirectory>$(working_directory)\$(projectName)</workingDirectory>
      </sourcecontrol>
      <tasks>
        <exec>
          <executable>$(working_directory)\$(projectName)\build.bat</executable>
        </exec>
      </tasks>
      <publishers>
        <merge>
          <files>
            <file>$(working_directory)\$(projectName)\build_output\build_artifacts\mbunit\*-results.xml</file>
            <file>$(working_directory)\$(projectName)\build_output\build_artifacts\nunit\*-results.xml</file>
            <file>$(working_directory)\$(projectName)\build_output\build_artifacts\ncover\*-results.xml</file>
            <file>$(working_directory)\$(projectName)\build_output\build_artifacts\ndepend\*.xml</file>
          </files>
        </merge>
        <email from="buildserver@somewhere.com" mailhost="smtp.somewhere.com" includeDetails="TRUE">
          <users>
            <user name="YOUR NAME" group="BuildNotice" address="yourEmail@somewhere.com" />
          </users>
          <groups>
            <group name="BuildNotice" notification="change" />
          </groups>
        </email>
        <xmllogger/>
        <statistics>
          <statisticList>
            <firstMatch name="Svn Revision" xpath="//modifications/modification/changeNumber" />
            <firstMatch name="ILInstructions" xpath="//ApplicationMetrics/@NILInstruction" />
            <firstMatch name="LinesOfCode" xpath="//ApplicationMetrics/@NbLinesOfCode" />
            <firstMatch name="LinesOfComment" xpath="//ApplicationMetrics/@NbLinesOfComment" />
          </statisticList>
        </statistics>
        <modificationHistory onlyLogWhenChangesFound="true" />
        <rss/>
      </publishers>
    </project>
  </cb:define>

  <cb:uppercut_svn_project projectName="Bombali" queuePriority="80" svnPath="https://bombali.googlecode.com/svn/trunk/" />
  <cb:uppercut_svn_project projectName="UppercuT" queuePriority="80" svnPath="http://uppercut.googlecode.com/svn/trunk/" />

</cruisecontrol>

 

Cruise Control.NET Setup

1. On the build server we are going to create two folders, CodeBuild and CodeDrop (suggestion is not the C: drive, but another drive that is much bigger).

  clip_image002_thumb[1]

2. Right click on CodeDrop and Select [Properties].

  clip_image004_thumb

3. Select the [Sharing] tab and Click on {Share this folder}. Click {OK}. NOTE: We are leaving share permissions as ReadOnly to keep anyone from making changes to the files after they are built.

  clip_image006_thumb[1]

4. You will now have the little sharing icon under it.

  clip_image008_thumb

5. In the CodeBuild folder, when CC.NET gets the latest revision of the code, it puts it there.

  clip_image010_thumb[1]

6. If we make a change to source, CC.NET will trigger off and get the latest changes to the code and put them in the CodeBuild folder.

    a. I get notified something has changed  clip_image012_thumb

    b. I open CCTray to check it out (or just hover, it will tell me what it is building).

        clip_image014_thumb

    c. I can head out to the site to check it out.

        clip_image016_thumb[1]

    d. If we are successful, the build goes green.

        clip_image018_thumb

7. In the CodeDrop folder, you get something a little different than you may have been expecting. But it's very good!

  clip_image002[7]_thumb[1]

8. What? Where’s my build? Well, let’s explore what we see here. One of these folders is named B2-R99. That stands for Build 2 Revision 99. So what you are seeing is that you get a different drop for every build!

9. In each folder I have a build, ready for deployment. And it’s read only (so someone can’t change the files)!

  clip_image022_thumb[1]

10. We’re all ready to go with this package at this revision!

 

CruiseControl.NET Build Information

On CruiseControl.NET I can get information about this current build. Test, NCover and NDepend reports for every build (NDepend provided it is licensed and installed to the proper directory on the build server)! Note: You will need to update the dashboard.config file to see all of these (coming later).

  clip_image024_thumb[1]

  clip_image002[5]_thumb[1]

With this knowledge you shall build.


kick it on DotNetKicks.com

Print | posted @ Thursday, May 21, 2009 6:46 AM

Comments have been closed on this topic.