Getting started with CruiseControl.NET and Subversion

The mini tutorial is designed to show how easy it is to get started with CruiseControl.NET . The aim will be to get a continuous integration build of a Visual Studio 2005 solution including nUnit unit tests running as quickly as possible using Subversion as the source control provider.

As ever the first step is to download it - the version used with this is CruiseControl.NET 1.3, which can be downloaded from:

http://sourceforge.net/project/showfiles.php?group_id=71179&package_id=83198&release_id=517823

Grab the CruiseControl.NET-1.3-Setup.exe and CruiseControl.NET-CCTray-1.3-Setup.exe setup kits.

Run the CruiseControl.NET-1.3-Setup.exe installation on the build server - the install is really basic.  Install all the components (CruiseControl.NET Server,Web Dashbord and Examples) make sure to Install CC.NET as Service and also Create Virtual Directory for the Web Dashboard.

While you are downloading and installing grab the XML logger from:

http://ccnetlive.thoughtworks.com/MSBuildXmlLogger-Builds/

Copy the logger binary (ThoughtWorks.CruiseControl.MSBuild.dll) to the CruiseControl.NET install dierctory (by default C:\Program Files\CruiseControl.NET\server).

Now to configuration, starting with the server...

On the build server checkout a working copy of the Visual Studio 2005 solution to somewhere sensible.  You need to make sure that the build works using MSBuild.exe.  Tghis is best done from the command line - if you don't know msbuild.exe is in C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 and command line to test will be:

	msbuild path to solution file /t:Clean /p:Configuration=Debug
	

Make sure the build is successful before moving on!

Now you configure the CruiseControl.NET server...

Open the ccnet.config file found in the server install directory which by default is C:\Program Files\CruiseControl.NET\server.  You are going to create a basic project entry to get tested and running.

<project name="Basic Project">

 

 

      <sourcecontrol type="svn">

 

 

            <trunkUrl>url to solution directory in subversion</trunkUrl>

 

 

            <workingDirectory>solution working directory</workingDirectory>

 

 

            <executable>C:\Program Files\CollabNet Subversion Server\svn.exe</executable>

 

 

      </sourcecontrol>

 

 

      <triggers>

 

 

            <intervalTrigger seconds="60" />

 

 

      </triggers>

 

 

      <tasks>

 

 

            <msbuild>

 

 

                  <executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>

 

 

                  <workingDirectory>solution working directory</workingDirectory>

 

 

                  <projectFile>solution file name</projectFile>

 

 

                  <buildArgs>/p:Configuration=Debug /v:diag</buildArgs>

 

 

                  <targets>Build</targets>

 

 

                  <timeout>15</timeout>

 

 

                  <logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MSBuild.dll</logger>

 

 

            </msbuild>

 

 

      </tasks>

 

 

</project>

 

 

 

 

 

Some points to note in the basic settings above; the sourcecontrol trunkUrl element is the subversion url to the solution, and working directory both in source control and msbuild task are to the local check out directory.  The msbuild element also has the solution file name and paths to the msbuild exe and the logger we downloaded earlier.  The trigger is what fires the build, in this case every minute (if there have been committed changes) the build will run.

The logger is referenced from the copied location, you can exclude the logger path, but you would need to put the logger dll in each project working folder.

 

Next step is to get the CruiseControl build running using the ccnet.exe (default location C:\Program Files\CruiseControl.NET\server) from the command line:

	ccnet.exe -project:"project name"

All being well (basically if you haven't set anything wrong in the ccnet.config) this should also successfully build.  If not you need to tweak until it does.

So finally to get the unit test running....

The simplest way to get nUnit tests running is to use the nunit task which you configure in the ccnet.config file after the msbuild.  The following is the basic config:

<nunit>

 

      <path>C:\Program Files\NUnit 2.4.3\bin\nunit-console.exe</path>

 

      <assemblies>

 

            <assembly>path to unit test binary</assembly>

 

      </assemblies>

 

</nunit>

 

 

So nothing complex here - the path is the path to the nunit-console.exe, and for each unit test assembly add a full path to the output binary.  Again make sure everything works with the ccnet.exe from the command line, make sure the unit tests pass too, tweaking as needed to get running.   Once its all running smooth then you can start the CruiseControl.NET service.

Finally to monitor the state of the build from the development client, install the CCTray application from the CruiseControl.NET-CCTray-1.3-Setup.exe on each development machine - again a really basic installer.

Following install run cctray and in the File Settings menu select the Build Projects tab and add a Build Server.  You have choices as to which way to monitor the build, I suggest using the "Connect directly using .NET remoting" option supplying server name of the build server - even though the install recommends against this this is the only option which will support the force build option, allowing you to demand a build from the development client.

You will be displayed a list of available project(s), select the available project to monitor - you now have a nice system tray notification showing status of your CI build...

If you want to know more there is plenty to read http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET.

Vista bits

We all know that users reject change - they inevitably want the new bit of software (that you have spent ages on) to look and operate 'exactly' like their last bit of software!  Clearly being one of those annoying users I have spent some time looking to making Vista operate 'exactly' like XP - well at least replicating some of the shortcuts I have got used to using. 

The first one was Send To.  I have got used to having Notepad and Notepad++ (amongst other things) in the send to menu - I find it a really quick way to get stuff done.  To edit the Send To menu in Vista you need to run:

%APPDATA%\Microsoft\Windows\SendTo

either in the run dialog or in an explorer.  Then you can drop in whatever shortcuts you want...

The other one I have got used to is the command prompt from the context menu.  Under XP its an addition to the registry for the directory to open a command prompt:

[HKEY_CLASSES_ROOT\Directory\shell\CommandHere] 
@="&Command here..." 
[HKEY_CLASSES_ROOT\Directory\shell\CommandHere\command] 
@="cmd.exe /k cd %1" 

I was dead chuffed to find that in Vista you don't have to bother as its built in - just hold down shift as you open the context menu and you get an "Open Command Window Here" option. You also (as a double bonus) get get a "Copy as Path" option - a zero hassle way to get paths for files and directories into the paste buffer.

TortoiseSVN and DiffMerge

I have used subversion as a source control repository for some time (without getting into the religious argument - I find it does the job really well); and recently I have started to use the DiffMerge tool from SourceGear (http://www.sourcegear.com/diffmerge/index.html).  I know there are loads of tools out there, I have found that this one does a reasonable job of just about everything (that's pretty much why I use it!).  I particularly like the implementation of the three file view for conflict resolution.

conflict

It doesn't take too much setting up to use with TortoiseSVN.  Open the Settings dialog from the TortoiseSVN Settings menu.

settings

In the External Programs section select Diff Viewer and select the External radio and supply the command line argument:

path\DiffMerge.exe /t1=Mine /t2=Original %mine %base

Make sure you supply a valid path to the installed DiffMerge product! When displaying changes this will display your version changes in the left panel with base in the right. 

To get the three panel merge select the Merge Tool in the External Programs section, and as before select the External radio and supply the following command line argument:

path\DiffMerge.exe /t1=Mine /t2=Base /t3=Theirs /r=%merged %mine %base %theirs

This will display three columns with your version, followed by the base version followed by the repository version - allowing you to merge changes from both sides into the centre at your leisure...

Using Workflow Foundation Rules Engine beyond Workflow ...

Most people are aware that Workflow Foundation is a massively powerful flexible toolset to allow you to build workflow based applications.  In true golden hammer style, once you have used it you will be surprised just how many problems look like they need to be solved with workflow!  What you may have missed is that part of the delivery is a very powerful rules engine that can easily be used outside of workflow applications.

In an effort to keep this post short I will keep it very simple and demonstrate how easy it is to use the rules engine outside of the context of workflow activities.

Before you start make sure you have .NET 3.0 installed (http://www.microsoft.com/downloads/details.aspx?FamilyID=10CC340B-F857-4A14-83F5-25634C3BF043&displaylang=en), installed the Visual Studio 2005 extensions for WF (http://www.microsoft.com/downloads/details.aspx?familyid=5D61409E-1FA3-48CF-8023-E8F38E709BA6&displaylang=en) and finally make sure you have read the excellent introduction to the rules engine by Jurgen Willis http://msdn2.microsoft.com/en-us/library/aa480193.aspx.

The simplest way to create a RuleSet is to use the RuleSetDialog in the System.Workflow.Activities.Rules.Design namespace to create and edit a RuleSet. The dialog is supplied a context object on construction - basically the type is reflected to see what is available for the intellisense on the editor dialog.  To use the RuleSetDialog you need to reference the System.Workflow.Activities and System.Workflow.ComponentModel assemblies.

RuleSetDialogCode

The RuleSetDialog allows you to define rules which are constructs similar to a basic If-Then-Else programming structure, with the condition and actions defined in an expression language based on the CodeDom model (read Jurgens article for more description).  Basically you can access properties and methods on you context object, and static methods on any class referenced within the host assembly.

RuleSetDialog

The RuleSet is serialisable (to XAML), so dead easy to create persist and reload collections of rules - you can work this bit out for yourself.

To execute a RuleSet you use the RuleEngine in the System.Workflow.Activities.Rules namespace.  You supply it an instance of your object and then Execute and off it goes.

RuleEngine

As you can see in this somewhat traditional bogus example, the rule checks for a literal value on a property of the context object, setting it to a different value if true.

Bogus though the example is, it doesn't take much imagination to picture how the rules engine can be harnessed to create massively powerful and extensible apps - with rules persisted outside of the app and editable by users that are able to operate on and affect data within your objects!  Get me a nail I have a new hammer...

Draggy bags...

You know those bags with wheels and handles! Hate them.  Crowded places like railway stations and airports where we are all herded through like sheep are annoying enough without having to trip over the little draggy bags - suitcases are easy to avoid, but the little ones just get under your feet!!

CruiseControl.NET installation in 7 easy steps

I often find people are intimidated by CruiseControl.NET. One of the phrases I have heard before is that it is "only really sensible for new projects" - the explanation behind this usually being that it is too difficult to set up for existing solutions.  This guide is designed to show how easy it is to get started on any .NET solution, no matter where in the development phase. 

The primary goal of this guide is simply to create a nightly build of a project maintained in Visual SourceSafe 2005 with CruiseControl.NET - one of the simplest configurations you can imagine. Those of you doing continuous integration will already recognise this as the first in many baby step's that can be taken to improve existing process using CruiseControl.NET (hopefully the subject of a future article). Those of you who want more information on what continuous integration is and can do to help may find these articles useful:

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

http://confluence.public.thoughtworks.org/display/CCNET/What+is+Continuous+Integration

Step 1 is to download and install the CruiseControl.NET application from http://sourceforge.net/projects/ccnet/ - pretty straight forward!  The version dealt with in the post is 1.3 which was released 21/06/2007.

Step 2 is to get the project(s) buildable using MSBuild from the command line, this is just a simple check to make sure the projects work! eg:

	msbuild c:\test\app.sln /t:Clean /p:Configuration=Debug
	

Step 3 create a VSS user specifically for CruiseControl.NET to log in as.

Step 4 configure the ccnet.config file which is found in the installation directory (default Program Files\CruiseControl.NET\server).  Simple config will require the a project with sourcecontrol section, an interval trigger and an msbuild, eg:

<cruisecontrol>
  <project name="TestCCNET">
    <sourcecontrol type="vss" autoGetSource="true" applyLabel="true">
      <executable>E:\Program Files\Microsoft Visual SourceSafe\ss.exe</executable>
      <project>$/TestProject</project>
      <username>ccnet</username>
      <password>ccnet</password>
      <ssdir>e:\vss\</ssdir>
      <workingDirectory>E:\work\LocalVSS\TestProject</workingDirectory>
      <cleanCopy>true</cleanCopy>
    </sourcecontrol>
    <triggers>
      <intervalTrigger seconds="60" />
    </triggers>
    <tasks>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>
        <workingDirectory>E:\work\LocalVSS\TestProject</workingDirectory>
        <projectFile>TestProject.sln</projectFile>
        <buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag</buildArgs>
        <targets>Build</targets>
        <timeout>15</timeout>
        <logger/>
      </msbuild>
     </tasks>
    <publishers>
      <xmllogger />
    </publishers>
  </project>
</cruisecontrol>

Don't be frightened - when you actually look at it - there is very little required, just the source safe details and solution location!  Note that we have set the build interval to 60 seconds - this will allow us to test the configuration easily in the next step.

Step 5 download the XML Logger for MSBuild from http://ccnetlive.thoughtworks.com/MSBuildXmlLogger%2DBuilds/ and copy to the the project workingDirectory (in the example above this is set to E:\work\LocalVSS\TestProject). This logger is used by CruiseControl as described in http://confluence.public.thoughtworks.org/display/CCNET/Using+CruiseControl.NET+with+MSBuild.

Step 6 is to check the configuration setting using the command line tool.  The ccnet.exe command line tool can be found in the server directory beneath the install directory (default Program Files\CruiseControl.NET\server).  The console will run the settings and attempt the build every 60 seconds (as configured previously).  The console output is good and it should not take you long to get a basic configuration like the example above working.

You can use the Web Dashboard to force through a build (so you don't need to make a change in SourceSafe!). The Web Dashboard will be available at http://server/ccnet and the Force button is available under the admin header for each server.

Step 7 finally change the ccnet.config to replace the 60 second interval trigger with a schedule trigger eg:

<scheduleTrigger time="23:30" buildCondition="ForceBuild" name="Scheduled">
</scheduleTrigger>

Which again is fairly straight forward and will run the build every day at 2330.

So that's it CruiseControl.NET up and running to run nightly builds in 7 steps! You can now use the service rather than the command line to listen for builds, and you can use the web dashboard on the CruiseControl.NET server (http://server/ccnet) to see status of builds and force builds (when the service is running).

Clearly there is loads more that CruiseControl.NET can do (notably run your unit tests) all of which you can find using the ThoughtWorks documentation site

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

Debugging ASP in Visual Studio 2005

I recently had to go back in time, and debug some traditional/classic ASP.  The fact that the code was relatively nasty is pretty much irrelevant, having the capability to debug and edit in my familiar Visual Studio 2005 IDE made the job a little easier to bear! Here are the steps to enable ASP debugging in studio...

Firstly you need to Enable Server Side ASP script Debugging in IIS - this can be done at the web site level or at the virtual directly level.  For the web site go to the Home Directory Tab on properties page, and for the Virtual Directory go to the Virtual Directly tab on the properties page.  From this tab select the Configuration button under Application Settings.  On the Configuration screen select the Debugging tab and check the Enable server-side ASP script debugging.

The quick way to get to the point of debugging with all code in the IDE is to open the Web site in Visual Studio (File, Open, Web Site).

If you are using server side JavaScript then you can use the debugger statement in code to force debugging - you are offered the choice of debug tools...  Or you can attach to the running process using Debug Attach to Process.  On XP the ASP process runs under a process dllhost.exe under the IWAM user.  Clearly you need to ensure you attach to the correct process, fortunately the IDE gives a nice visual warning if you get the wrong one.

InvalidProcess

Either way you do it you will be shown a warning when attaching to the process

AttachProcessMessage

And once you attach you can step through the code as normal!

In the code I was looking at there was another interesting feature.  At some point during the difficult and painful life of this product the page Language had managed to get set to JScript.Encode (even though the code was no longer encrypted) which blocks debugging.