Welcome to blogs.conchango.com Sign in | Join | Help

Welcome to blogs.conchango.com

John Rayner's Blog

Brain.Extract<IBloggable>( Where.Author.Is( "John.Rayner" ) );

Setup of a continuous integration build

I thought I'd document our continuous integration build, since we had to pull together a number of libraries from different sources in order to get it working.  This is quite a long post, but there was quite a lot to do ...  :-)

Solution background
Our project is currently a .Net 2.0 Windows application which uses some external libraries.  There is a database (obviously) but there is no other back-end or middle tier system (e.g. web services) at present.  Our source code is stored in Subversion (SVN), we are using CruiseControl.Net v1.0.1 (CC.Net) for continuous integration and NUnit for unit tests.

Overview of the build process
We'll get down to the detail of all these steps a bit later, but at a high level our continuous integration process is as follows:

  1. CC.Net is configured to monitor subversion for changes
  2. When it detects some, it assigns a build number and kicks off the main build process
  3. The build process in CC.net has one task, and that is to fire up MSBuild with our build script.  Steps 4-12 are executed within MSBuild.
  4. Existing source code is removed
  5. Our artefact directory is cleaned out (more on this later)
  6. The latest version of source code is obtained from Subversion
  7. The CC.net build label is inserted into an AssemblyVersion attribute in a common AssemblyInfo.cs.  This file is then copied into source directories for all our projects.
  8. The main compilation occurs
  9. NCover is called.  This shells out to NUnit in order to execute all the unit tests and collects code coverage information at the same time.
  10. NCoverExplorer produces some rolled-up coverage statistics which drive a really useful report.
  11. FxCop is called to perform static code analysis.
  12. The compiled binaries are copied to a drop location, in a folder named with the CC.net build label.
  13. CC.net then merges a number of XML files in order to produce the build report.  These XML files are produced by all the various utilities we call (NUnit, FxCop, etc) and are all created in the artefact directory.

We also modified a few other settings and stylesheets within CC.Net.  For the sake of completeness, I talk about these in a separate section at the end of this post.

1. Setting up CC.Net to monitor subversion
Not a very difficult task this, just create an SVN account and add the following into the ccnet.config file:

<sourcecontrol type="svn">
    <
trunkUrl>svn://192.168.104.10/amr/trunk</trunkUrl>
    <
workingDirectory>D:\Projects\MyProject\src</workingDirectory>
    <
executable>C:\Program Files\Subversion\bin\svn.exe</executable>
    <
username>cruise.control</username>
    <
password>ccnet</password>
</
sourcecontrol>

You should replace "cruise.control" and "ccnet" with the username and password of your SVN account.  Note that CC.Net is able to poll SVN for changes, but can't yet checkout the latest source code to perform the build.  We do this from MSBuild in step 6 below.

2. Choosing a build number
We are on an agile project, so the IterationLabeller makes sense for us.  We also use the build label for versioning (step 7 below) and the IterationLabeller also suits that purpose.  Our ccnet.config file contains the following:

<labeller type="iterationlabeller">
    <prefix>1.0</prefix>
    <
duration>4</duration>
    <
releaseStartDate>2006/7/3</releaseStartDate>
    <
separator>.</separator>
</
labeller>

3. Kicking off MSBuild
We decided that MSBuild is a more supported and extensible environment than CC.Net (and also a number of people have written build tasks which we could leverage).  So our <tasks> element in ccnet.config contains a single entry:

<msbuild>
    <
executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\msbuild.exe</executable>
    <
projectFile>ContinuousIntegration.build</projectFile>
    <
buildArgs>/noconsolelogger /p:Configuration=debug /v:n</buildArgs>
    <
targets>BuildTestAnalyse</targets>
    <
timeout>600</timeout>
    <
workingDirectory>D:\Projects\MyProject\Build</workingDirectory
    <
logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,D:\Projects\MyProject\Build\CruiseControl.1.0.1\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</
msbuild>

Steps 4 thru 12 occur with the context of MSBuild in the ContinuousIntegration.build file which you see referenced above.

4. Deleting existing source code
Easily done in MSBuild as follows:

<Target Name="CleanSource">
    <
Message Text="Removing all source files from $(SourceDirectory)" />
    <
RemoveDir Directories="$(SourceDirectory)" />
</
Target>

5. Cleaning out the artefact directory
Once again, this is pretty straightforward:

<Target Name="CleanPreviousArtefacts">
    <
Message Text="Cleaning previous XML output files from $(ArtefactDirectory)" />
    <
Delete Files="$(ArtefactDirectory)\*.xml" />
    <
Delete Files="$(ArtefactDirectory)\*.cs" />
</
Target>

6. Getting the latest source code from SVN
This is the first step where we need some third-party code.  The MSBuild Community Tasks Project (http://msbuildtasks.tigris.org/) is the place to go.  This project provides, amongst other things, a number of SvnXxxx tasks are relevant when connecting to SVN.  To include these tasks, copy the downloaded files into a directory somewhere and then include the following in your build script (the path is relative to the buils script file):

<Import Project="Tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>

The tasks are now available for use.  Our build target looks like this:

<Target Name="GetSource">
    <
Message Text="Checking out trunk into $(SourceDirectory)" />
    <
SvnCheckout RepositoryPath="svn://192.168.104.10/myproject/trunk" 
        LocalPath="$(SourceDirectory)"
        UserName="cruise.control"
        Password="ccnet"
            <
Output TaskParameter="Revision" PropertyName="Revision" />
    </
SvnCheckout>
    <
Message Text="Have got revision: $(Revision)"/>
</
Target>

As with step 1, the username and password should match up to what you created in SVN.

Note: although we get hold of the SVN revision number used for the build, we don't do much with it other than write it into the build log.  I would like to be able to get it onto the front page of our build report and possibly also into some of the assembly properties in our binaries.  For the SVN newbies, the revision number uniquely identifies all the file versions that were used in the build.  It's equivalent to a SourceSafe label.

7. Updating the AssemblyVersionAttribute in AssemblyInfo.cs files
More third party tasks required here - this time we use the AssemblyInfoTask from http://www.gotdotnet.com/codegallery/codegallery.aspx?id=93d23e13-c653-4815-9e79-16107919f93e.  This task loads up an AssemblyInfo.cs file, modifies the assembly-level attributes and then saves it again.  To be honest, it's a little bit sensitive to duplicate attributes in the existing code file but we managed to work around this.  To use the task, download and install the MSI from GotDotNet and insert the following line into your build script:

<Import Project="$(MSBuildExtensionsPath)\Microsoft\AssemblyInfoTask\Microsoft.VersionNumber.targets"/>

We then have our build target as follows:

<Target Name="UpdateCommonFiles">
    <
Copy 
        SourceFiles="$(CommonFileDirectory)\CommonAssemblyInfo.cs" 
        DestinationFiles
="$(ArtifactDirectory)\AssemblyInfo.cs" />
    <
AssemblyInfo AssemblyInfoFiles="$(ArtifactDirectory)\AssemblyInfo.cs"
        AssemblyVersion="$(CCNetLabel)"
        AssemblyFileVersion="$(CCNetLabel)"
        ComVisible="false"
        AssemblyCompany="MyCompany"
        AssemblyConfiguration=""
        AssemblyCopyright="MyProject 2006"
        AssemblyCulture=""
        AssemblyProduct="MyProject"
        AssemblyDelaySign="false"
        AssemblyKeyName=""/>
    <
Copy SourceFiles="$(ArtifactDirectory)\AssemblyInfo.cs" 
        DestinationFolder="$(SourceDirectory)\Common\Properties" />
    <
Copy SourceFiles="$(ArtifactDirectory)\AssemblyInfo.cs" 
        DestinationFolder="$(SourceDirectory)\DataAccess\Properties" />
    <
Copy SourceFiles="$(ArtifactDirectory)\AssemblyInfo.cs" 
        DestinationFolder="$(SourceDirectory)\ReportProcessing\Properties" />
    <
Copy SourceFiles="$(ArtifactDirectory)\AssemblyInfo.cs" 
        DestinationFolder="$(SourceDirectory)\DesktopReporting\Properties" />
</
Target>

You notice how our AssemblyVersion is set to $(CCNetLabel).  Thanks to CC.Net, this is the build label produced by the IterationLabeller we configured in step 2.

For the sake of completeness, here is CommonAssemblyInfo.cs:

using System;
using System.Reflection;
using System.Security.Permissions;
using System.Runtime.InteropServices;

[assembly: ComVisible(false)]
[assembly:
PermissionSet(SecurityAction.RequestMinimum, Name="FullTrust")]
[assembly:
FileIOPermission(SecurityAction.RequestMinimum)]
[assembly:
AssemblyCompany("MyCompany")]
[assembly:
AssemblyConfiguration("")]
[assembly:
AssemblyCopyright("MyCompany 2006")]
[assembly:
AssemblyCulture("")]
[assembly:
AssemblyProduct("MyProject")]
[assembly:
AssemblyTrademark("")]
[assembly:
AssemblyDelaySign(false)]
[assembly:
AssemblyKeyName("")]
[assembly:
CLSCompliant(true)]
[assembly:
AssemblyVersion("1.0.0.0")]
[assembly:
AssemblyFileVersion("1.0.0.0")]

8. The main compilation
This bit is real easy, thanks to the fact that solution and project files are build scripts themselves:

<Target Name="Build">
   <
Message Text="Build solution for build $(CCNetLabel)" />
   <
MSBuild
      Projects="@(SolutionFile)"
      Targets="Build">
         <
Output
            TaskParameter="TargetOutputs"
            ItemName="AssembliesBuiltByChildProjects" />
   </
MSBuild>
</
Target>

9. NCover + Nunit to run unit tests with coverage analysis
Yet more third-party code, this time from http://www.kiwidude.com/blog/2006/07/nant-and-msbuild-tasks-for-ncover.html.  This code also gives us the functionality for step 10 below.  A UsingTask element is needed as follows:

<UsingTask
   
TaskName="MSBuild.NCoverExplorer.Tasks.NCover"
   
AssemblyFile="Tools\NCover\MSBuild.NCoverExplorer.Tasks.dll" />

And then we can actually perform our unit tests, as follows:

<Message Text="Running unit tests with code coverage against @(SolutionFile)" />
<
NCover ToolPath="Tools\NCover\"
    CommandLineExe="Tools\NUnit\nunit-console.exe"
    CommandLineArgs="@(SolutionFile) /xml=D:\Projects\MyProject\Build\SmokeTest\NUnit.xml /labels /nologo"
    CoverageFile="$(CoverageFile)"
    />

10. NCoverExplorer rolled up coverage report
The output from NCover consists of:

  1. A list of code statements that weren't executed
  2. An overall percentage of code that wasn't executed

While these are very useful, it's often nice to get something in between.  A great example is the NCoverExplorer report produced by kiwidude, which is described at http://www.kiwidude.com/blog/2006/07/ncoverexplorer-v134.html.  This one:

Rolled up code coverage report 

To get this, we have already downloaded the code we need (in step 9 above).  So can add in the following UsingTask and then call it as follows:

<UsingTask
   
TaskName="MSBuild.NCoverExplorer.Tasks.NCoverExplorer"
   
AssemblyFile="Tools\NCover\MSBuild.NCoverExplorer.Tasks.dll" />
<NCoverExplorer ProjectName="MyProject" 
    ToolPath="D:\Projects\MyProject\Build\Tools\NCoverExplorer-1.3.4"
    ReportType="4"
    OutputDir="$(ArtefactDirectory)"
    XmlReportName="$(ArtefactDirectory)\CoverageSummary.xml"
    HtmlReportName="$(ArtefactDirectory)\CoverageSummary.html"
    MergeFileName="$(ArtefactDirectory)\CoverageMerge.xml"
    ShowExcluded="True"
    SatisfactoryCoverage="75"
    FailMinimum="False"
    CoverageFiles="$(CoverageFile)"
    Exclusions="Assembly=*.Tests;Namespace=*.Tests*"
    />

You may notice that we're being lenient and not failing the build for a poor code coverage.  I have some philosophical issues about the use of code coverage as enforcement tool - i.e. I think developers should write unit tests to properly execute their code, not just to hit some or other coverage target.

11. FxCop for static code analysis
This step in the process ought to be fairly straightforward.  After all, the MSBuild Community Tasks Project that we downloaded for step 6 from http://msbuildtasks.tigris.org/ includes an FxCop task which looks like it does exactly what we want - run FxCop against our built binaries and save the results into an XML file.  Fabulous, except that the standard FxCop rulesbase is pretty onerous and includes some rules which (a) don't apply to our situation; or (b) we don't feel like satisfying.

Now the authors of FxCop realised this and so all the executables for FxCop include the ability to exclude certain rules.  But the authors of the MSBuild Community Tasks haven't quite gotten this far yet.  So we modified the code and rebuilt the library.  And in the spirit of open source, we submitted our change back to the project.  You can find it at http://msbuildtasks.tigris.org/issues/show_bug.cgi?id=19.

Once we had the revised binaries available, we setup our build process to look like this:

<FxCop 
    TargetAssemblies="@(FxcopTargets)"
    RuleLibraries="@(FxCopRuleAssemblies)" 
    AnalysisReportFileName="D:\Projects\MyProject\Build\SmokeTest\fxcop.xml"
    DependencyDirectories="$(MSBuildCommunityTasksPath);C:\Program Files\Extreme Optimization\Statistics Library for .NET\bin;D:\Projects\MyProject\Build\Tools\log4net-1.2.10\bin\net\2.0\debug;C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0"
    FailOnError="False"
    ApplyOutXsl="False"
    OutputXslFileName="C:\Program Files\Microsoft FxCop 1.35\Xml\FxCopReport.xsl"
    Verbose="False"
    includeSummaryReport="True"
    ExcludeRules="Microsoft.Design#CA2210;Microsoft.Globalization#CA1303"
   
/>

You may notice that again we're being fairly lenient here - an FxCop failure will not break the build.  This is not the situation we want to be in, but our development work had started before we got FxCop into the process.  Consequently, there's this large chunk of code with a number of FxCop violations - we are in the process of working through this list and correcting the issues, but it's a slow process because it's being done in between the main dev tasks.

12. Putting the binaries in the drop folder
All the binaries from successful builds are captured and stored in a drop folder.  This is actually how we get code to our testers - we tell them to pick up build xxx where they will find such-and-such feature.

Copying the binaries to the drop location is really straightforward:

<Message Text="Copying files to $(ReleaseFolder)\v$(CCNetLabel)" />
<
Copy SourceFiles="@(ReleaseFiles)"
   
DestinationFolder="$(ReleaseFolder)\v$(CCNetLabel)" />

13. Merging XML files back into the CC.Net build report
This is made quite easy by CC.Net itself.  All you have to do add the following to the <publishers> section of your ccnet.config file and ensure that the correct XSL files are available within your web dashboard.

<merge>
    <
files>
        <
file>D:\Projects\MyProject\Build\SmokeTest\Nunit.xml</file>
        <
file>D:\Projects\MyProject\Build\SmokeTest\CoverageMerge.xml</file>
        <
file>D:\Projects\MyProject\Build\SmokeTest\CoverageSummary.xml</file>
        <
file>D:\Projects\MyProject\Build\SmokeTest\FXCop.xml</file>
    </
files>
</
merge>

Other changes we made to CC.Net

Replacement and tweaking of fxcop.xsl stylesheet:

The FxCop.xsl stylesheet that ships with CC.Net gives a pretty hard-to-read FxCop report.  We used the alternative stylesheet linked from http://confluence.public.thoughtworks.org/display/CCNETCOMM/XSL+Transforms.

We still weren't entirely happy with this stylesheet since it doesn't do any indentation of results, i.e. as you drill-down into your assembly all the FxCop messages are left-aligned without any additional indentation.  So we modified the stylesheet.  Revised version is attached to this post (with a slightly mangled name, thanks to our blog software).

Reconfiguring the web dashboard:

We pulled all the NAnt and Simian stuff out of the CC.Net dashboard.config file, since it's not relevant to our build.  We renamed the standard "NCover Output" to be "NCover Detail", since it is useful sometimes to find out which specific line number aren't being executed.  We then slotted in "NCover Overview" to be the NCoverExplorer rolled-up summary.

Comments

 

urteaga said:

Great work. There's a lot of very useful information here. I have a question, however. What if I want to commit the changes to the AssemblyInfo.cs files? When I try this, svn says the working copy is locked. I suppose CruiseControl.NET has the files locked. Can I get around this?

October 3, 2006 16:13
 

john.rayner said:

urteaga, I have never tried doing a svn commit from an MS Build script, but the error you are getting seems to be an svn lock and not an OS file lock.  This svn FAQ may be relevant to you - http://subversion.tigris.org/faq.html#wedged-wc.  Please let me know how you get on.

October 4, 2006 14:32
 

John Rayner's Blog said:

Recently I wrote a long post on our continuous build setup and what we had to do to get it all working.

October 5, 2006 13:14
 

John Rayner's Blog said:

I&#39;ve been working on a WiX installer recently and I was asked to integrate it into the project&#39;s

November 17, 2006 14:44
 

Andy McG said:

This is really handy!

Quick question though, int he copy files step, where is the property @(ReleaseFiles) files declared.

I am having issues with pdb files being copied into my output dir, even in RELEASE configurations when I use:

<Output TaskParameter="TargetOutputs"            ItemName="AssembliesBuiltByChildProjects" />

as the source of my copy files.

Just wondered if I was missing something useful!

Thanks

Andy

November 18, 2006 15:10
 

john.rayner said:

Andy,

Thanks for the kind words.  The @(ReleaseFiles) item is something I defined manually in my script as follows:

<ItemGroup>

 <ReleaseFiles Include="$(SourceDirectory)\Reporting\bin\$(Configuration)\**\*.*" />

</ItemGroup>

I didn't really try the TargetOutputs output parameter - we have a complex solution and it was only the output of a single project that I wanted to use.  If you do define your item explicitly then you have a lot of control over what to include or not.  So you'd easily be abe to exclude your PDB files as follows:

<ItemGroup>

 <ReleaseFiles Include="$(SourceDirectory)\Reporting\bin\$(Configuration)\**\*.*" Exclude="*.pdb" />

</ItemGroup>

November 20, 2006 08:59
 

simon said:

Nice work John,

Noticed you wrote that you could not use Cruise Control to get latest code, you can. Just add autoGetSource="true" to the svn element. Make sure you've already done svn checkout to the specified folder maually as cruise control will only do a svn update.

If you prefere to clear the build folder and get the latest code, use SvnExport instead of SvnCheckout, it is much faster, no _svn or .svn folders are created.

I will implement the FxCop stuff right away, thanks.

Simon

November 20, 2006 18:30
 

john.rayner said:

Simon,

Thanks for the compliment.  This was my first project with SVN, so it's interesting to hear your tips.  Be sure to check out my other post re FxCop (http://blogs.conchango.com/johnrayner/archive/2006/10/05/Getting-FxCop-to-break-the-build.aspx) since it wasn't as simple as I was expecting.

Cheers,

John

November 21, 2006 09:23
 

Koob said:

Thanks for this.

To use the xsl with CruiseControl 1.1, you have to change the image locations. Change "images/" into "/ccnet/images/".  I think it is in the file 5 times.

Koob.

December 20, 2006 09:17
 

JesperD said:

Hi John thank you for sharing your experiences. =)

Very helpful.  The fith task, cleaning up the artifacts directory will not work, the delete dask does not accept wildcards. You can create a Itemgroup with the files to delete and use that in the delete task. Look att this blog item for more information.

http://blogs.msdn.com/msbuild/archive/2006/03/09/546588.aspx

March 15, 2007 09:39
 

Steinam's Blog said:

Ein Beitrag zu Cruise Control ccnet

July 29, 2007 21:45
 

NZJon said:

Hi John,

I'm running CC.NET 1.3.0, and have tried to use your FxCopReport.xsl stylesheet in order to get a better FxCop report. However, when I navigate to the FxCop report I get the following error (see below)

My question is: do you know how to enable the XsltSettings.EnableScript property? Is this something an end user can do, or is it something that's more involved in CC.NET?

Thanks,

  Jon

Exception Message

Execution of scripts was prohibited. Use the XsltSettings.EnableScript property to enable it. An error occurred at D:\CCNet\1.3.0\webdashboard\xsl\FxCopReport.xsl(345,4).

Exception Full Details

System.Xml.Xsl.XslTransformException: Execution of scripts was prohibited. Use the XsltSettings.EnableScript property to enable it. An error occurred at D:\CCNet\1.3.0\webdashboard\xsl\FxCopReport.xsl(345,4). at System.Xml.Xsl.Runtime.XmlQueryRuntime.ThrowException(String text) at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current) at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current) at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current) at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current) at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter) at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results) at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, TextWriter results) at ThoughtWorks.CruiseControl.Core.Util.XslTransformer.Transform(String input, String xslFilename, Hashtable xsltArgs) at ThoughtWorks.CruiseControl.Core.Util.HtmlAwareMultiTransformer.Transform(String input, String[] transformerFileNames, Hashtable xsltArgs) at ThoughtWorks.CruiseControl.WebDashboard.Dashboard.PathMappingMultiTransformer.Transform(String input, String[] transformerFileNames, Hashtable xsltArgs) at ThoughtWorks.CruiseControl.WebDashboard.Dashboard.BuildRequestTransformer.Transform(IBuildSpecifier buildSpecifier, String[] transformerFileNames, Hashtable xsltArgs) at ThoughtWorks.CruiseControl.WebDashboard.Dashboard.Actions.XslReportBuildAction.Execute(ICruiseRequest cruiseRequest) at ThoughtWorks.CruiseControl.WebDashboard.MVC.Cruise.ServerCheckingProxyAction.Execute(ICruiseRequest cruiseRequest) at ThoughtWorks.CruiseControl.WebDashboard.MVC.Cruise.BuildCheckingProxyAction.Execute(ICruiseRequest cruiseRequest) at ThoughtWorks.CruiseControl.WebDashboard.MVC.Cruise.ProjectCheckingProxyAction.Execute(ICruiseRequest cruiseRequest) at ThoughtWorks.CruiseControl.WebDashboard.MVC.Cruise.CruiseActionProxyAction.Execute(IRequest request) at ThoughtWorks.CruiseControl.WebDashboard.MVC.Cruise.CachingActionProxy.Execute(IRequest request) at ThoughtWorks.CruiseControl.WebDashboard.MVC.Cruise.ExceptionCatchingActionProxy.Execute(IRequest request)

September 20, 2007 06:06
 

john.rayner said:

NZJon,

This seems to be as a result of the new CC.Net version 1.3 according to http://jira.public.thoughtworks.org/browse/CCNET-936.  They supply a patch on that URL, but it is a source code patch and so will require a recompilation of CC.Net.

Cheers,

John

September 20, 2007 11:31
 

David in NZ said:

How does the build label (from Step 2 inside CCNet) get passed to the versioning task inside MSBuild in Step 7? I must be a noob as I cannot see what is populating the CCNetLabel property.

January 17, 2008 01:40
 

john.rayner said:

@David in NZ,

CC.Net takes care of passing the build label into MSBuild.

January 17, 2008 21:43
 

cloudsin said:

Hey JOHN,

I am trying to make MSI using CCNET. Could you please help me how to involve WiX or any other component to make MSI when CCNET runs. And also do we have any solution for running SQL files on database server.

Thanks in advance.

February 28, 2008 06:51
 

john.rayner said:

@cloudsin,

Please have a read of this post to see if it meets your needs ... http://blogs.conchango.com/johnrayner/archive/2006/11/17/WiX_3A00_-Integrating-into-the-continuous-build.aspx

February 28, 2008 13:05
 

cloudsin said:

Hey John,

Finally I am able to get the MSI using CCNET. Thnx a lot for ur reply.

Now another task for me is to integrate 'fitnesse' to CCNET. I have googled it. But unable to find particula thing tht wht should I add in CCNET config file in order to run FINESSE tests. Please help me out.

Thanks in advance.

February 29, 2008 09:31
 

john.rayner said:

@cloudsin,

I've got no experience with Fitnesse.  Sorry.

February 29, 2008 11:04
 

CodeObsessed said:

March 27, 2008 09:33
 

how to debug xslcompiledtransform said:

April 21, 2008 07:34
 

Ted said:

Hello John,

Please help me. My build machine crashed because of a virus :(.  I have installed CC for.NETintegrated with NAnt ... again but my first build number(label) of the project started from number 1. I need to keep the previous build number(label) for example 2567. Where and what property i have to set so CC .NET to start increment my build number from desired value ?

Thanks in advance.

May 24, 2008 10:20
 

john.rayner said:

@Ted,

Alongside your ccnet.config file, you will see some files with a ".state" extension.  These are safe to open in Notepad and contain the build number.  So stop ccservice, edit the file, save your changes and then restart ccservice.  Your build numbers should then be where you want them to be.

May 28, 2008 14:51
 

Ted said:

Thanks a lot John ! It's work !

May 30, 2008 08:20
 

AlSki.net said:

CruiseControl Setup

August 14, 2008 23:35
Anonymous comments are disabled
Powered by Community Server (Personal Edition), by Telligent Systems