Tuesday, December 18, 2007

Continuous Integration

with

Cruise Control.NET



  • By

    • Sudhir Kesharwani

    • Geeta Godbole


2.1Introduction

Integration as the word clearly says integration is about integrating / putting the code fixes to your Software Product. What’s the big deal, definition sounds so simple, but it becomes really painful when we have to do the same process again and again, especially when our product is in test-fix-deploy-test cycle, when we are giving final touches to our product.

Integration becomes part of your daily activity sometimes we end up deploying the same product 2-3 times due to small fixes and miss outs.

Integration should happen continuously, and is more often than we might think. The frequency of integration will vary from project to project, from developer to developer, and from modification to modification.

Best practices says that developer should integrate the changes once every few hours, at least once a day,

A successful integration is a measure of progress. It provides feedback that the new code runs correctly in the integration environment and successfully interoperates with the rest of the code base. Code sitting un integrated in a developer's local box simply does not exist. It is not part of the code base, it cannot be accessed by other developers or tested by the customer. Only when it has been successfully integrated is the benefit of the new code realized.

2.2Benefits

Why one should opt for continuous integration when everything is going fine, why to add additional complexity in the development process, we are already tied up with our schedules, what benefits do I get out of this?

Most of the times it happens that the code working in your local boxes perfectly suddenly stops working when integrated with other developer’s code and starts giving exceptions when deployed on the production. You are in a state of shock. You had done the unit testing perfectly. Why it happens in the integration time only. The problem is while you have been developing the fixes, somebody else was also changing other part of your software, His code working fine in his workstation, your code was working perfectly in your workstation, But the code integration task was scheduled for the later date, so when the Build Man starts deploying it to production, he gets all the hidden surprises.

Continuous Integration completely solves this problem. There's no long integration, you completely eliminate the blind spot. At all times you know where you are, what works, what doesn't, the outstanding bugs you have in your system. And surprisingly all this without any extra efforts, everything is taken care by Cruise Control .NET.

You do not require any human intervention for this, All you have to do is define the build steps for your project in the configuration of Cruise Control .NET, and execute the exe, You have to option of configuring Cruise Control as a window service, so it will keep on executing as a windows service in the server, whenever it detects the changes in your source code, it will automatically take the latest code from your source control and deploy the latest build in your server.

Effectively if you configure CCNET for automating your build process, integration becomes as easy as checking in the code to your version control tools (e.g. Visual Source Safe etc), and you can configure these tools with your ccnet server, CCNET scans the entire source safe database and checks for the modification, if modification is found then it starts with the build process, so by just checking in the code we have the latest build deployed onto our development / test environment. You can easily take out the report of what is working and what is breaking.

Other benefits of cruise control .net include:

  • Integration with a variety of Source Control systems

  • Integration with other external tools, such as NAnt and Visual Studio

  • Can build multiple projects on one server

  • Remote management and reporting

  • Email support.

You can configure cruise control with variety of tools, To view the list of third party tools and their configuration please click here

3Installing Cruise Control .NET



3.1Installation Pre-Requisites

CruiseControl.NET Server – For running Cruise Control .NET server you need to have following setup installed on your server.

  • Microsoft .NET Framework 2.0 (Download)

Cruise Control .NET Web-Dashboard : If you wish to install Web-Dashboard application you need to have following setup installed onto your Cruise Control .NET server.

  • Microsoft .NET Framework 2.0 (Download)

  • ASP.NET enabled web server (IIS with ASP.NET configured)

Workstations running ccTray application:

  • Microsoft .NET Framework 2.0 (Download)



3.2Installation Steps

Cruise Control can be downloaded from following url. http://confluence.public.thoughtworks.org/display/CCNET/Download

Latest build available for this is 1.3. Download CruiseControl.NET-1.3-Setup.exe

To install execute the setup file, From the available screen click on the next button, Cruise Control consists of few applications if you wish to install all the components keep the defaults alternatively you may choose to install it partially. Find the screen below.



In the next screen the setup asks you if you wish to install Cruise Control as a Windows Service, so that it will keep on running in the background. However using the ccnet.config file you can specify the build schedule, so build will be forced automatically depending on the schedule specified by you (e.g every Monday at 8:00 etc)

It also asks if you want to create a virtual directory in your IIS for the Cruise Control Web Dashboard, Web-Dashboard is an ASP.NET application which shows the current build status and other reports, it will be accessible to all the workstations in your Intranet, this web application is also useful if you want to check the build status as well as want to force build your solution. It lists down all the projects from your ccnet.config file and you can see a report of all the builds for any project and their status ( e.g if build was successful, the compilation errors, warnings). Find the screen shot below.

Click on next, specify the installation directory (we will refer to this as ccnetdir ) and click on finish to complete the installation of Cruise Control .NET. Generally it is best to use the roots for installing cruise control .net (e.g. c: )

So all the files will be copied inside <installdir>Cruise Control .NET

3.3Components of Cruise Control.NET

Cruise Control .NET mainly consist of three applications

  1. Cruise Control .NET Server – This is the server application that runs on the server, either as an exe or as a service (depending on the installation), all the client applications (web-dashboard, ccTray) connects to this application (for generating reports).

When you install cruise control .net server as a windows service, you can find the entry into the services console for cruise control.net, Please note that you may require starting this service; once you have configured your ccnet.config (this is the xml based configuration file that contains the project build steps. You can find this file inside <ccnetdir>serverccnet.config) for your project build steps. Please make sure to stop this service while you are making changes to your configuration files. Find the screen shot of the Cruise Control .NET Service.

If you do not want the Cruse Control .NET server to run in the background as a windows service, You may still do that, make sure to uncheck “Install CC .Net server as windows service” checkbox in the installation procedure. After installation is complete browse to <ccnetdir>Server directory, You will find ccnet.exe executable file, once you run this executable, it will start reading the ccnet.config file for your project configuration and start getting newer version of the code from source safe database. Once the build process is completed you can close this command window. You can run this executable as and when you want to take out fresh build.



  1. Cruise Control Web Dashboard – This is the asp .net web application which is accessible to everyone via Intranet/Internet, this application can be used to monitor the status of any build of all the projects that resides on the cruise control server. User may also force build using this application. When you install Cruise Control .NET automatically all the files (aspx and dlls) are deployed to your installation directory and a virtual directory is created inside your default web site with name ccnet, Any workstation can access this application by going to http://servername/ccnet url. Find screen shot of the homepage of Cruise Control .NET Web-Dashboard.

As you can see, the web-dashboard home page displays all the projects configured in the server, there last build status.

There is a force button displayed after each project row, this will be used to start the build of that project forcefully.

Project name is shown as hyperlinked and when you go inside that hyperlink you will get a detailed report of all the builds for that project. It gives all the builds as hyperlinked in the left hand side, and when you click on any of the build you will get the detailed report about that build, it lists all the modifications done since last build, Warnings and errors. Please refer to screen shots below.



As you can see in the left hand side, the successful builds are shown in green color and failed builds are shown in red color, when you click on any of the builds you get a detailed report for that build.

  1. ccTray Application – This is an optional application that can be installed, the setup file for this application is available in the Cruise Control .NET Web-Dashboard application (in the homepage you will find the link to download ccTray application), alternatively you can copy the setup from your Cruise Control .NET installation directory (<ccnet directory>webdashboardcctray). This application is installed onto your workstation and you can check status of all the projects onto your Cruise Control .NET server, you can also forcefully build the project using ccTray application, however you can not see the detailed report for your project build status,

it will just show your project icon as Green if last build was successful, it will show the icon in red color if the build was failed, and it will show the icon in gray color if your server is not started or ccTray is unable to connect to the server.

If you want to forcefully build any project, just select the project from the projects list and click on “Force Build” button.

Configuring ccTray Application:

ccTray desktop application can be configured to show any no of projects either from one cruise control server or many cruise control server. In order to configure ccTray application follows these steps.

  • Open ccTray application, click on FileSettings, following dialog box will be opened

  • Click on “Add” button, a window will appear from where you can add the server.

  • Click on “Add Server” command button. Dialog box will appear asking you for the server settings and how you want to connect to server

You can specify the Web-Dashboard URL (e.g. http://servername/ccnet) or you can specify the server IP address, if you wish to connect through .Net Remoting

  • Once you specify the server address, it will automatically list down all the configured projects, select any of the projects and it will be listed in your ccTray application. You can add multiple projects from the same server by repeating these steps.

4ccnet.config File:

When Cruise Control is installed, in installed directory there is a Folder created with the name ‘Server’. In this folder one can find a file named as ccnet.config file. This file acts as the base for every build that is generated through Cruise Control. It is an XML file that stores the entire configuration with predefined Elements and attributes associated with each of the element. It is not mandatory that all the Elements shall be included, but there is minimum configuration that is needed for Cruise Control to process the build successfully. We will study the Elements in detail here.

Once you installed the cruise control ccnet.config look like



<cruisecontrol>

<!-- This is your CruiseControl.NET Server Configuration file. Add your projects below! -->

<!--

<project name="MyFirstProject" />

-->

</cruisecontrol>

It is blank file with only one empty element.

4.1Structure of CCNET.Config file

CCNET.config file is the heart of Cruise Control .NET, it contains information about all the projects in the server that are to be built using cruise control.net.

Structure of this file is something like given below:



<cruisecontrol>

<project name="Project 1" queue="Q1" queuePriority="1">

<workingDirectory>yourWorkingDirectory</workingDirectory>

<category>Category 1</category>

<webURL>http://server/ccnet/server/local/project/testProject/ViewLatestBuildReport.aspx</webURL>

<triggers>

<yourFirstTriggerType ../>

<yourOtherTriggerType ../>

</triggers>



<sourcecontrol type=" " autoGetSource=" " applyLabel=" ">

<executable> </executable>

<project></project>

<username> </username>

<password> </password>

<ssdir></ssdir>

<workingDirectory></workingDirectory>

<culture></culture>

<cleanCopy> </cleanCopy>

</sourcecontrol>



<!--Labeler for the Code-->

<labeller type="defaultlabeller">

<prefix> </prefix>

<incrementOnFailure> </incrementOnFailure>

</labeller>



<prebuild>

<yourFirstPrebuildTask ../>

<yourOtherPrebuildTask ../>

</prebuild>

<tasks>

<yourFirstTask ../>

<yourOtherTask ../>

</tasks>

<publishers>

<yourFirstPublisherTask ../>

<yourOtherPublisherTask ../>

</publishers>

<externalLinks>

<externalLink name="My First Link" url="http://somewhere/" />

<externalLink name="My Other Link" url="http://somewhere.else/" />

</externalLinks>

</project>

</cruisecontrol>


4.2Elements of ccnet.config

  • cruisecontrol: this is the root node for ccnet.config file, all the project in the servers are defined as child nodes of <cruisecontrol> node.

  • Project Block : this node represents a single project in the cruise control server, all the child nodes of project nodes specify project details, like source control settings, trigger intervals, publisher settings for the project.
    Click Here to see various child elements of the project element.

  • Trigger Block : this node defines various trigger types associated with the project. A trigger specifies the build schedule for the project. Please see Trigger Block to get more details about various types of triggers supported by cruise control .net and their syntax.

  • Sourcecontrol Block : this node contains information about the source control integration, cruise control .net supports verities of source control software. Please have a look at the Source Control block to see the structure of source control block and supported source control tools.

  • Labeller Block : this node defines the labeller settings, once the build for the project is successful, cruise control can automatically apply a label for the code in your source control tool. This label can be used to take out reports and maintain history of various builds for the project. Please have a look at the labeller blocks to get the details about this block.

  • Tasks Block : tasks block defines the steps required to build the project. There are various types of tasks supported by cruise control .net, for e.g. Executable Tasks (.bat, exe etc), visual studio task (devenv). To see a detailed list of tasks supported by cruise control .net please check Task Block. Task blocks can be nested inside <tasks> section or <publishers> section. Please note that <tasks> section is executed before <publishers> section regardless of their order in the ccnet.config file.

  • Publishers Block : This block defines the set of tasks that run after the build is complete. These tasks are used primarily to clean up after the build and to publish and report on the build results. All tasks in this section will always run regardless of whether previous tasks fail or the build is broken. In general we specify the tasks to publish the reports e.g Email Publisher and Build Publisher tasks inside this.

4.3Project Configuration Block:

A <project> block defines the entire configuration for one project running in a CruiseControl.NET server. All the elements of a project configuration block are shown below.


Node

Description

Type

Required

Default

name

The name of your project - this must be unique for any given CruiseControl.NET server

string

yes

n/a

queue

The name of the integration queue that this project will use. By default, each project runs in its own queue. (Added in CCNet 1.3)

string

no

the project name

queuePriority

The priority of this project within the integration queue. If multiple projects have pending requests in the specified queue then these requests will be executed according to their priority. Higher priority numbers indicate that integration requests for this project will execute before other projects in the same queue.

string

no

0

workingDirectory

The Working Directory for the project (this is used by other blocks). Relative paths are relative to a directory called the project Name in the directory where the CruiseControl.NET server was launched from. The Working Directory is meant to contain the checked out version of the project under integration.

string

no

WorkingDirectory

artifactDirectory

The Artifact Directory for the project (this is used by other blocks). Relative paths are relative to a directory called the project Name in the directory where the CruiseControl.NET server was launched from. The Artifact Directory is meant to be a persistence location for anything you want saved from the results of the build, e.g. build logs, distributables, etc.

string

no

Artifacts

webURL

A reporting URL for this project. This is used by CCTray and the Email Publisher. Typically you should navigate to the Project Report on the Dashboard, and use its URL

string

no

http://localhost/ccnet

category

A general category for this project. This will be used by CCTray and the dashboard in the future to provide groupings to the project. The groupings can span servers in the farm.

string

no

empty string

modificationDelaySeconds

The minimum number of seconds allowed between the last check in and the start of a valid build.
If any modifications are found within this interval the system will sleep long enough so the last checkin is just outside this interval. For example if the modification delay is set to 10 seconds and the last checkin was 7 seconds ago the system will sleep for 3 seconds and check again. This process will repeat until no modifications have been found within the modification delay window.
This feature is in CruiseControl.NET for Source Control systems, like CVS, that do not support atomic checkins since starting a build half way through someone checking in their work could result in invalid 'logical' passes or failures. The property is optional though so if you are using a source control system with atomic checkins, leave it out (and it will default to '0')

integer

no

0

sourcecontrol

See Source Control Blocks

Source Control Block

no

Null Source Control Block

triggers

See Trigger Blocks

List of Trigger Blocks

no

Specifying an empty element (<triggers />) means integrations are only ever forced manually (for example using CCTray or the Web Dashboard.) Not including a <triggers> element at all means the project has a single Interval Trigger with default configuration.

state

See State Manager Blocks

State Manager Block

no

Project State Manager

labeller

See Labeller Blocks

Labeller Block

no

Default Labeller

tasks

A set of Tasks to run as part of the build. A failed task will fail the build and any subsequent tasks will not run. Tasks are run sequentially, in the order they appear in the configuration.

List of Task Blocks

no

empty list

prebuild

A set of Tasks to run before the build starts and before the source is updated. A failed task will fail the build and any subsequent tasks will not run. Tasks are run sequentially, in the order they appear in the configuration. *This section is available in the CCNet 1.1 release.

List of Task Blocks

no

empty list

publishers

A set of Tasks that are run after the build is complete. These tasks are used primarily to clean up after the build and to publish and report on the build results. All tasks in this section will always run regardless of whether previous tasks fail or the build is broken. You should always set an Xml Log Publisher in this section so that your Web Dashboard will be able to report results.

List of Task Blocks

no

If you don't specify a <publishers /> section at all then a default Xml Log Publisher is used as the sole publisher.

externalLinks

See ExternalLinks

List of ExternalLinks

no

empty list

4.4SourceControl block:

This block contains the entire configuration of integration with any source control. This is an inner element of Project Configuration Block.

Example:

Get Source Code From VSS-->

<!--Comment this at the time of release-->

<sourcecontrol type=" " autoGetSource=" " applyLabel=" ">

<executable> </executable>

<project></project>

<username> </username>

<password> </password>

<ssdir></ssdir>

<workingDirectory></workingDirectory>

<culture></culture>

<cleanCopy> </cleanCopy>

</sourcecontrol>



Node

Description

Type

Required

Default

executable

Path of the source control tool exe

String

Yes


Project

Project path in VSS

String

Yes


username

Login name for VSS

String

Yes


password

Password for VSS

String

Yes


Ssdir

Path of the project database

String

Yes


workingDirectory

Mapped Path on local

String

Yes


Culture

Culture to be applied

String

Yes


cleanCopy

Boolean value for cleaning the copy

String

Yes




4.5Labeller Blocks:

Labellers are used to generate the label that CCNet uses to identify the specific build. The label generated by CCNet can be used to version your assemblies or label your version control system with each build.

Commonly used types of labeller supported by cruise control are

  • Date Labeller – generates the label in the format of yyyy.mm.dd.build (e.g 2007.12.18.9)

  • Default Labeller – most commonly used labeller, here you can specify the prefix and the automatically it will append the current build no with the prefix (prefix.<build number> e.g. RMSWA.10). You can specify if the build number should be

  • Iteration Labeller - The Iteration Labeller is similar to the Defaul Labeller; however, it maintains a revision number that is incremented by one for each iteration from the release start date. For example, if the release start date was June 1, 2005 and the iteration duration was 2 weeks, the iteration number on July 1, 2005 would be 3. This would create a label of <prefix>.3.<build number>.

Example:

<!--Labeler for the Code-->

<labeller type="defaultlabeller">

<prefix> </prefix>

<incrementOnFailure></incrementOnFailure>

</labeller>

Node

Description

Type

Required

Default

Prefix

Label to be given to all files


False


incrementOnFailure

If true, the label will be incremented even if the build fails. Otherwise it will only be incremented if the build succeeds.


False

False

4.6Tasks Block:

Task Blocks are the action elements of CruiseControl.Net. They're the elements that do things, like executing a program, running tests, or send email results.

Types of Tasks blocks:

  1. Build Publisher

  2. Email Publisher

  3. Executable Task

  4. File Merge Task

  5. FinalBuilder Task

  6. ForceBuildPublisher

  7. Modification Writer Task

  8. MsBuild Task

  9. NAnt Task

  10. Null Task

  11. NUnit Task

  12. Statistics Publisher

  13. Visual Studio Task

  14. Xml Log Publisher

Task blocks must appear in either the <tasks> section or the <publishers> section. The <tasks> section is always run before the <publishers> section, regardless of the order in which they appear. However, within each of these sections, the tasks are run in the order they appear.

Below we are explaining mostly used blocks.

4.6.1Build Publisher:

The Build Publisher lets you copy any arbitrary files on a successful build.

Example:

<buildpublisher>

<sourceDir>C:myprojectsproject1</sourceDir>

<publishDir>\myfileserverproject1</publishDir>

<useLabelSubDirectory>false</useLabelSubDirectory>

</buildpublisher>

Node

Description

Type

Required

Default

sourceDir

The source directory to copy files from. This path can be absolute or can be relative to the project's working directory. If unspecified, the project's working directory will be used as the source directory.

string

false

n/a

publishDir

The directory to copy the files to. This path can be absolute or can be relative to the project's artifact directory. If useLabelSubDirectory is true (default) a subdirectory with the current build's label will be created, and the contents of sourceDir will be copied to it. If unspecified, the project's artifact directory will be used as the publish directory.

string

false

n/a

useLabelSubDirectory

If set to true (the default value), files will be copied to subdirectory under the publishDir which will be named with the label for the current integration.

bool

false

true

4.6.2Email Publisher:

The email publisher can be used to send email to any number of users. It is common to include one user who gets an email for every build and then also send email to every developer who checked code in for this build.

Example:

<email from="buildmaster@mycompany.com" mailhost="smtp.mycompany.com" mailhostUsername="smtpuser" mailhostPassword="smtppassword" includeDetails="TRUE">

<users>

<user name="BuildGuru" group="buildmaster" address="buildguru@mycompany.com"/>

<user name="JoeDeveloper" group="developers" address="joedeveloper@thoughtworks.com"/>

</users>

<groups>

<group name="developers" notification="change"/>

<group name="buildmaster" notification="always"/>

</groups>

</email>



4.6.3Executable Task:

The Executable Task lets you invoke any command line executable.

Minimalist example:

<exec executable="c:projectsmyprojectbuild.bat"/>

Full example:

<exec>

<executable>make</executable>

<baseDirectory>D:devMyProject</baseDirectory>

<buildArgs>all</buildArgs>

<buildTimeoutSeconds>10</buildTimeoutSeconds>

</exec>

Node

Description

Type

Required

Default

executable

The path of the program to run. If this is relative, then must be relative to either (a) the base directory, (b) the CCNet Server application, or (c) if the path doesn't contain any directory details then can be available in the system or application's 'path' environment variable

string

true

n/a

baseDirectory

The directory to run the process in. If relative, is a subdirectory of the Project Working Directory

string

false

Project Working Directory

buildArgs

Any command line arguments to pass in

string

false

no arguments

buildTimeoutSeconds

Number of seconds to wait before assuming that the process has hung and should be killed.

int

false

600 (10 minutes)



4.6.4Visual Studio Task:

Most complex build processes use NAnt or MSBuild to script the build. However, for simple projects that just need to build a Visual Studio.NET solution, the Visual Studio task <devenv> provides an easier method.

Minimalist example:

<devenv>

<solutionfile>srcMyProject.sln</solutionfile>

<configuration>Debug</configuration>

</devenv>

Full example:

<devenv>

<solutionfile>srcMyProject.sln</solutionfile>

<configuration>Debug</configuration>

<buildtype>Build</buildtype>

<project>MyProject</project>

<executable>c:program filesMicrosoft Visual Studio .NETCommon7IDEdevenv.com</executable>

<buildTimeoutSeconds>600</buildTimeoutSeconds>

</devenv>

Node

Description

Type

Required

Default

solutionfile

The path of the solution file to build. If relative, it is relative to the Project Working Directory.

string

true

n/a

configuration

The solution configuration to use (not case sensitive).

string

true

n/a

buildtype

The type of build. Valid values are Rebuild, Build or Clean (not case sensitive).

string

false

rebuild

project

A specific project in the solution, if you only want to build one project (not case sensitive).

string

false

The default is to build all projects selected by the configuration.

executable

The path to devenv.com.

string

false

If not specified, CC.NET will try to find this path from the registry for VS.NET 2003 and 2002 in that order. If you need to use VS.NET 2005, or if you need to use VS.NET 2002 when VS.NET 2003 is installed, you should specify this property to point to the location of devenv.com for the correct VS.NET version.

buildTimeoutSeconds

Number of seconds to wait before assuming that the process has hung and should be killed.

int

false

600 (10 minutes)

5Reference:

To get the detailed information on remaining blocks, please follow below link.

http://confluence.public.thoughtworks.org/display/CCNET/Task+Blocks

http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET

http://www.martinfowler.com/articles/continuousIntegration.html

http://programcsharp.com/blog/archive/2006/07/23/21483.aspx



©2006 Avanade Inc. All Rights Reserved 22