Build,Release and Continous Integration-Part2

Posted: August 12, 2008 in Architecture Series
This is a continuation of the previous post .If you have not read the previous post,please read it here :-
 
In short we are creating a build,release and CI with .NET  Solution and in this post I will demonstrate how to use MSbuild to perform our build and the CCnet task for the same.
The Solution we ll be using is named BuildingSolution and the working location is placed in C:\BuildingSolution .
My Test folder is BuildingTest and BL folder would be BuildingBL and So on  all inside C:\BuildingSolution.You can structure your Folder as you like but better follow any industry standard for this.
 
The layering for this would be like the following:-
UI[Web and Win both,I have 2 projects 1 Web and another Win]–>Proxy–>Servicehost–>Services–>BL–>DAL–>DB
You can have few more layers for Example :- facade and presentation specific or Service specific layers .Since the intention of this post is around B&R and CI,I am not going to write more about the layering.Only I point I would like to mention is if you might need VS05Sp1 or WebApplication project if you are working with a WebSite and yet like to treat this as Project like .NEt 1.1.
 
Let us now create the msbuild project file and CCNET config  file wich were the essence of our B&R
 
Here is the simplest example how your CCNET.config will look like:-
 

<cruisecontrol>

  <project>

    <name>BuildSolution</name>

    <triggers>

  <intervalTrigger seconds=”900″  buildCondition=”IfModificationExists”/>

    </triggers>

    <sourcecontrol type=”svn”>

      <trunkUrl>ur TrunkUrl here</trunkUrl>

      <workingDirectory>Ur Working Directory here</workingDirectory>

      <executable>c:\program files\subversion\bin\svn.exe</executable>

      <username>Ur username </username>

      <password>Ur passwod</password>

      <autoGetSource>true</autoGetSource>

      <tagOnSuccess>false</tagOnSuccess>

      <timeout>12000000</timeout>

    </sourcecontrol>

 

<!– Note:- If you want to use any other repository like VSS use the ccnetconfig tool to create a SourceControl section for ccnet.config–>

    <triggers />

    <tasks>

      <msbuild>

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

        <workingDirectory>C:\BuildingSolution</workingDirectory>

        <projectFile>webandWin.proj</projectFile>

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

        <targets>MainTarget</targets>

        <timeout>900</timeout>

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

      </msbuild>

    </tasks>

   

<!– Note:- If you want to use any other version like .NET 3.5,please point the appropritae framework’s msbuiild.exe also the Configuration you can keep for Release as well as debug in Build Args–>

    <publishers>

      <merge>

        <files>

          <file>c:\builds\buildingsolution\BuildingTest.dll-results.xml</file>

          <file>c:\builds\buildingsolution\Coverage.xml</file>

          <file>c:\builds\buildingsolution\fxcop-results.xml</file>

        </files>

      </merge>

<!– we are merging the results of Test,Fxcop and CodeCoverage,You can merge other results as and when you want–>

      <xmllogger>

        <logDir>log</logDir>

      </xmllogger>

      <email from=”user1@urcompany.com”              mailhost=”relaymail.urcompany.com”            includeDetails=”TRUE”>

        <users>

          <user name=”user1″ group=”group1″      address=”user1@urcompany.com”/>

        </users>

        <groups>

          <group name=”group1″ notification=”always”/>

        </groups>

            </email>

 

    </publishers>

  </project>

</cruisecontrol> 

 

 

 Now that we saw what our CCNET.config looks like let jump into the MSBUILD project file.Below is the MSBUILD project file tasks wih description:-

 

Continuous Integration using MSBuild and msbuild community tasks

In the msbuild based approach, we will add the executable to be invoked as msbuild.exe in the ccnet.config file. Here we will provide the different targets to be executed in the corresponding .proj file. These targets will get executed in a sequential order.

 

Different steps, tools and associated tasking are as listed below.

Invoking the Svn Cleanup on a particular project, which is in svn source control.

 

<PropertyGroup>

<SvnExePhysicalPath>c:\program files\subversion\bin\svn.exe</SvnExePhysicalPath>

    <SvnUpdatePath>C:\BuildingSolution</SvnUpdatePath>

</PropertyGroup>

 

<Target Name=”SvnCleanup”>

<Exec Command=”$(SvnExePhysicalPath) cleanup $(SvnUpdatePath)”/>

</Target>

Get latest code from the source control(svn)

<PropertyGroup>

<SvnExePhysicalPath>c:\program files\subversion\bin\svn.exe</SvnExePhysicalPath>

    <SvnUpdatePath>C:\BuildingSolution</SvnUpdatePath>

    <SvnUri>ur SVN URI </SvnUri>

</PropertyGroup>

 

<Target Name=”SvnCheckout”>

<Exec Command=”$(SvnExePhysicalPath) checkout $(SvnUri) $(SvnUpdatePath)”/>

</Target>

Versioning

Creating a task which generates the version.

 

<PropertyGroup>

    <Major>1</Major>

    <Minor>0</Minor>

    <Build>0</Build>

    <Revision>0</Revision>

</PropertyGroup>

 

<Target Name=”Version”>

<Message Text=”Version: $(Major).$(Minor).$(Build).$(Revision)”/>

    <AssemblyInfo CodeLanguage=”CS” 

      OutputFile=”Source\MSBuild.Community.Tasks\Properties\AssemblyInfo.cs”

      AssemblyTitle=”MSBuild Community Tasks”

      AssemblyDescription=”Collection MSBuild Tasks”

      AssemblyCompany=”http://msbuildtasks.tigris.org/&#8221;

      AssemblyProduct=”MSBuild.Community.Tasks”

      AssemblyCopyright=” ”     

      ComVisible=”false”

      CLSCompliant=”true”

      Guid=”ur Guid here”

      AssemblyVersion=”$(Major).$(Minor).$(Build).$(Revision)”

      AssemblyFileVersion=”$(Major).$(Minor).$(Build).$(Revision)”

      Condition=”$(Revision) != ‘0’ “/>

</Target>

Cleanup, Compilation(msbuild)

Compiling the project after cleaning up the previous compilation output files.

 

<PropertyGroup>

<BuildOutputFolder>c:\builds\buildingsolution</BuildOutputFolder>

</PropertyGroup>

<Target Name=”Clean”>

    <Exec Command=”del $(BuildOutputFolder)Latest\*”/>

</Target>

 <Target Name=”Compile” DependsOnTargets=”Version”>

    <MSBuild    Projects=”C:\BuildingSolution\BuildingSolution.sln”

             Properties=”Configuration=Debug” />

</Target>

Note: – Though we can compile source code using devenv.exe, it requires Visual Studio to be installed on the machine.

 

Cleanup, Unit Testing(NUnit)

Unit testing the project after cleaning up the previous unit test log files.

 

<PropertyGroup>

<BuildOutputFolder>c:\builds\buildingsolution</BuildOutputFolder>

</PropertyGroup>

 

<Target Name=”ClenUpTestFiles”>

    <Exec Command=”del $(BuildOutputFolder)buildlogs\test.xml”/>

</Target>

 

<Target Name=”Test” DependsOnTargets=”Compile”>

    <NUnit Assemblies=”C:\BuildingSolution\Bui     ldingTest\bin\Release\BuildingTest.dll “

            ToolPath=”C:\Program Files\NUnit 2.4.8\bin”

                        WorkingDirectory=”C:\BuildingSoluti           on”

OutputXmlFile=”$(BuildOutputFolder)buildlogs \test.xml”

            ContinueOnError=”true”>

      <Output TaskParameter=”ExitCode”      ItemName=”NUnitExitCodes”/>

    </NUnit>

</Target>

Cleanup, Code coverage(NCover)

Code coverage tool invocation for checking the code coverage statistics after cleaning up the previous code coverage log files.

 

<PropertyGroup>

<NCoverExe>”C:\Program Files\NCover\NCover.Console.exe”</NCoverExe>

    <WorkingDirectory>”C:\BuildingSolution\BuildingTest\bin\Release”</WorkingDirectory>

    <ProfiledAssemblies>”BuildingTest”</ProfiledAssemblies>

    <LogFile>”Coverage.log”</LogFile>

    <CoverageHtmlDirectory>”C:\BuildingSolution”</CoverageHtmlDirectory>

<AppToProfileExe>”C:\Program Files\NUnit 2.4.8\bin\nunit-console.exe”</AppToProfileExe>

    <AppToProfileArgs>”BuildingTest.dll”</AppToProfileArgs>

    <BuildOutputFolder>c:\builds\buildingsolution</BuildOutputFolder>

</PropertyGroup>

 

<Target Name=”ClenUpCoverageFiles”>

<Exec Command=”del $(BuildOutputFolder)buildlogs\coverage.xml”/>

</Target>

 

<Target Name=”Coverage” DependsOnTargets=”Test”>

<Exec Command=”$(NCoverExe) //w $(WorkingDirectory) //reg //a $(ProfiledAssemblies) //l $(LogFile) //h $(CoverageHtmlDirectory) $(AppToProfileExe) $(AppToProfileArgs)” />

</Target>

Cleanup, Code quality(FxCop)

Code quality tool invocation for checking the quality and coding standards of the project after cleaning up the previous code quality log files.

 

<PropertyGroup>

<BuildOutputFolder>c:\builds\buildingsolution</BuildOutputF   older>

</PropertyGroup>

 

<Target Name=”ClenUpFxcopFiles”>

<Exec Command=”del $(BuildOutputFolder)buildlogs\fxcop-results.xml”/>

</Target>

 

<Target Name=”Reporting” DependsOnTargets=”Compile”> >

<Exec Command=”FxCopCmd.exe   /project:C:\BuildingSolution\Buildi   ngSolution.FxCop        /out: $(BuildOutputFolder)buildlogs \fxcop-          results.xml” WorkingDirectory=”C:\Program Files\Microsoft             FxCop 1.35″ />

</Target>

 Database creation and population of data(such as adding tables, views, stored procedures etc using sql)

Tasks which execute .sql files to create a database connection; and adding up tables, views and stored procedures to the database.

 

<PropertyGroup>

    <dbserver>ur Server</dbserver>

    <dbinstance>\SQLEXPRESS</dbinstance>

    <dbuser>dbusername</dbuser>

    <dbpassword>dbpassword</dbpassword>

    <dbname>BuildingSolutionDB</dbname>

 </PropertyGroup>

 

<Target Name=”Create_db” DependsOnTargets=”Reporting”>

    <Exec Command=”osql.exe -S $(dbserver)$(dbinstance) -U $(dbuser) -P $(dbpassword) -b -n -i C:\BuildingSolution\Database\createDB.sql” />

</Target>

 

<!–This is a try to iterate through the sql files as in nant, but was unsuccessful–>

<ItemGroup>

<tablesqlfiles Include=”C:\BuildingSolution\Database\Tables\*.sql” />

</ItemGroup>

<ItemGroup>

<viewssqlfiles Include=”C:\BuildingSolution\Database\Views\*.sql” />

</ItemGroup>

<ItemGroup>

<procssqlfiles Include=”C:\BuildingSolution\Database\StoredProcedures\*.sql” />

</ItemGroup>

 

<Target Name=”Create_tables” DependsOnTargets=”Create_db”>

    <Message Text=”Creating Tables”/>

    <Message Text=”Iterate for each item (for-each):  %(tablesqlfiles.Identity)”/>

<Exec Command=”sqlcmd -S $(dbserver)$(dbinstance) -U $(dbuser) -P $(dbpassword) -i %(tablesqlfiles.Identity)”/>

</Target>

 

<Target Name=”Create_views” DependsOnTargets=”Create_tables”>

    <Message Text=”Creating Views”/>

    <Exec Command=”sqlcmd -S $(dbserver)$(dbinstance) -U $(dbuser) -P $(dbpassword) -i %(viewssqlfiles.Identity)”/>

</Target>

 

<Target Name=”Create_procs” DependsOnTargets=”Create_views”>

    <Message Text=”Creating Stored procedures”/>

    <Exec Command=”sqlcmd -S $(dbserver)$(dbinstance) -U $(dbuser) -P $(dbpassword) -i %(procssqlfiles.Identity)”/>

</Target>

 

 

Once you have this ready ,you can now browse to your CCNET ,using http://urbuildserver/ccnet and See the Dashboard buildign your solution with each Change in the codebase in Source control repository.The Next post We will discuss NANT based approach and extensibility as well as other tools and frameworks commonly used:-

 

Part1 Link  Read part3. ,Part4 as well

 

Drop me  a line if you found this post useful.

 

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s