Click here to Skip to main content
Email Password   helpLost your password?

Introduction

I was recently introduced to CruiseControl.Net and have been using it for my team's build automation. Let me explain my development environment before proceeding into the details of configuration. Ours is a Visual Studio 2005 Web Application project. It follows a three tiered (Presentation Layer, Business Layer, Data Access Layer) architecture. I usually follow the Build-> Publish <Web Site> option of Visual Studio IDE to build the project and pass the build to the testing department. This option allows to publish the application to a specific disk path, set through the Publish Web dialog box.

Background

With CruiseControl.Net, I needed a way to automate this process. In this article, I explain how I managed to do it using MSBuild, Microsoft's build engine. Here, I would like to add a disclaimer that this may not be the best way of automating a build. I am just describing my way of doing it and it works for me. Hope it sounds meaningful and will be of help to someone.

Description

The following are the contents of my MSBuild script:

<Project DefaultTargets="DoPublish" 
	xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <SourceFileRootFolder>$(CCNetWorkingDirectory)</SourceFileRootFolder>
    <WebFolder>MyProject.Web</WebFolder>
    <ReleaseFolder>c:\TestDeploy\v$(CCNetLabel)</ReleaseFolder>
  </PropertyGroup>
  <PropertyGroup Condition ="$(CCNetWorkingDirectory) == ''">
    <SourceFileRootFolder>c:\testcc</SourceFileRootFolder>
    <ReleaseFolder>c:\TestDeploy\v</ReleaseFolder>
  </PropertyGroup>
  <ItemGroup>
    <DefaultBinFiles Include="$(SourceFileRootFolder)\DefaultBinFiles\*.*"/>
    <ProjectBinFiles Include="$(SourceFileRootFolder)\$(WebFolder)\bin\*.*"/> 
  </ItemGroup>
  <Target Name="CleanSource">
    <Message Text="Removing all source files from $(ReleaseFolder)" />
    <RemoveDir Directories="$(ReleaseFolder)" />
  </Target> 
  <Target Name="DoPublish">
    <MSBuild Projects="$(SourceFileRootFolder)\MyProject.sln" Targets="Clean;Build" />
    <CallTarget Targets="CleanSource"/>
    <MSBuild Projects="$(SourceFileRootFolder)\$(WebFolder)\MyProject.Web.csproj" 
Targets="_CopyWebApplication;_BuiltWebOutputGroupOutput" 
	Properties="OutDir=$(ReleaseFolder)\" ></MSBuild>
    <Copy SourceFiles="@(DefaultBinFiles)" 
	DestinationFolder="$(ReleaseFolder)\$(WebFolder)\bin\"></Copy>
    <Copy SourceFiles="@(ProjectBinFiles)" 
	DestinationFolder="$(ReleaseFolder)\$(WebFolder)\bin\"></Copy>
  </Target>
</Project>

I keep a separate folder "DefaultBinFiles" whose contents I want to be placed in the bin files of the build. This may have a copy of any third party assemblies registered in the cache or other com references being used in the project. The ProjectBinFiles have the assemblies created in the project's bin folder. 

The MSBuild element performs a clean build of the solution. CleanSource deletes the release folder. The next MSBuild command instructs to execute _CopyWebApplication and _BuildWebOutputGroupOutput targets. These targets can be found in Program Files\MSBuild\Microsoft\VisualStudio\v8.0\WebApplications\Microsoft.WebApplication.targets. This also requires a tweak in the web csproj file. Add the following section to the csproj file anywhere between the Project tags. Note that csproj file is actually an MSBuild script.

<PropertyGroup>
    <WebProjectOutputDir>$(OutDir)\$(MSBuildProjectName)</WebProjectOutputDir>
  </PropertyGroup>

By default, the build outputs are placed under _PublishedWebsites subfolder. The above section eliminates this and places the build right under the custom folder set in the ReleaseFolder tag. The next two copy elements in the script recursively copy the contents of the DefaultBinFiles and ProjectBinFiles folders to the bin folder of the ReleaseFolder.

Add the following XML to the ccnet.config file:

<msbuild>
  <executable>C:\WinNT\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>
  <workingDirectory>c:\TestCC\</workingDirectory>
  <projectFile>MSBuild.xml</projectFile>
  <targets>DoPublish</targets>
  <timeout>300</timeout>
  <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,
		ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>

As can be seen, CruiseControl.Net is instructed to use msbuild to carry out the build task provided in c:\TestCC\MSBuild.xml. DoPublish is the target to execute.

Conclusion

Following the above MSBuild configuration would place the build output of an ASP.NET Web application project to a specific folder on disk and linking it to CruiseControl automates the whole build process. Information for setting up CruiseControl.Net can be found at How to Setup CruiseControl.NET for Starters

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralMy vote of 2
GilesHinton
3:11 30 Nov '09  
Author not totally informed - there are easier ways of doing this.
It's also nothing to do with CC.Net!
GeneralRe: My vote of 2
Michael Collns
10:20 26 Dec '09  
Can you provide some examples of the correct way that you're suggesting? I'd be interested to know what you think is wrong with this approach.
AnswerStatement about tweaking web project is unnecessary
GilesHinton
3:10 30 Nov '09  
You don't need to change the web project's csproj file to change the output directory.
You can specify this as part of the msbuild project properties.

The following line will perform the build (where ProjectFile is the path to the project you're building and DeploymentDir is the directory where you're publishing files to:

<MSBuild Projects="$(ProjectFile)" StopOnFirstFailure="true" Targets="ResolveReferences;_CopyWebApplication;_BuiltWebOutputGroupOutput" Properties="WarningLevel=0;DefineConstants=TRACE;Configuration=Release;Platform=AnyCPU;Optimize=true;DebugSymbols=false;OverwriteReadOnlyFiles=true;WebProjectOutputDir=$(DeploymentDir)\;OutDir=$(DeploymentDir)\bin\;DocumentationFile=;"/>
GeneralResolve project dependencies
ByteGuru
2:52 4 Mar '09  
Great article, thanks. It saved me a lot of time.
Just a slight addition to it; my application had Language Resource DLLs and other binary dependencies. By adding the ResolveReferences targets, they also get copied over to the output folder.

My XML is included below:

<Project DefaultTargets="Publish"
     xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
      <SourceFileRootFolder>$(CCNetWorkingDirectory)</SourceFileRootFolder>
      <WebFolder>Euro.UI</WebFolder>
      <ReleaseFolder>E:\ccnet\projects\Euro\Euro.UI.Deployment\v$(CCNetLabel)</ReleaseFolder>
   </PropertyGroup>
   <PropertyGroup Condition ="$(CCNetWorkingDirectory) == ''">
      <SourceFileRootFolder>c:\testcc</SourceFileRootFolder>
      <ReleaseFolder>E:\ccnet\projects\Euro\Euro.UI.Deployment</ReleaseFolder>
   </PropertyGroup>
   <ItemGroup>
      <DefaultBinFiles Include="$(SourceFileRootFolder)\DefaultBinFiles\*.*"/>
      <ProjectBinFiles Include="$(SourceFileRootFolder)\$(WebFolder)\bin\*.*"/>
   </ItemGroup>
   <Target Name="CleanSource">
      <Message Text="Removing all source files from $(ReleaseFolder)" />
      <RemoveDir Directories="$(ReleaseFolder)" />
   </Target>
   <Target Name="Publish">
      <MSBuild Projects="$(SourceFileRootFolder)\$(WebFolder)\Euro.UI.csproj" Targets="Clean;Build" />
      <CallTarget Targets="CleanSource"/>
      <MSBuild Projects="$(SourceFileRootFolder)\$(WebFolder)\Euro.UI.csproj" Targets="ResolveReferences;_CopyWebApplication;_BuiltWebOutputGroupOutput"
Properties="OutDir=$(ReleaseFolder)\bin\;WebProjectOutputDir=$(ReleaseFolder)\;" ></MSBuild>
      <Copy SourceFiles="@(DefaultBinFiles)"
     DestinationFolder="$(ReleaseFolder)\$(WebFolder)\bin\"></Copy>
      <Copy SourceFiles="@(ProjectBinFiles)"
     DestinationFolder="$(ReleaseFolder)\$(WebFolder)\bin\"></Copy>
   </Target>
</Project>
Generalbuild project Visual Studio IDE vs msbuild.exe
pghn
8:31 6 Nov '08  
Hi. Anyone notice differences in the publish directory, building a sln project from the IDE vs msbuild? I’m getting some dll’s in different locations (with msbuild is in the root and with the IDE is in bin).
QuestionAutomatically creates a _PublishedWebsites folder.
VS2008Developer
5:18 12 Jul '08  
I have followed the MSBuild script exactly as you have it laid out. Unfortantly when cc.net runs the script it makes a subfolder under the OUTDIR called _PublishedWebsites\ProjectName. Within that folder is where it publishes the application. What I would like is the web app to be published right to the OUTDIR instead. Has anyone else experienced this and if so how did you correct it?
AnswerRe: Automatically creates a _PublishedWebsites folder.
Judy Vinu
20:57 16 Jul '08  
I suspect if you have tweaked the .proj file correctly. Can you tell, where did you add the
<PropertyGroup>
<WebProjectOutputDir>$(OutDir)\$(MSBuildProjectName)</WebProjectOutputDir>
</PropertyGroup> tag?

Also, please check the casing of "OutDir".


Last Updated 21 Jul 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010