Build,Release and Continous Integration-Part3

Posted: August 13, 2008 in Architecture Series

This post is a Continuation from earlier posts Where as I started with what CI is and What Toolset you might need .I would recommend you to read the Part1and Part2 before  continue reading this post.

The goal for this post is to create a CI using NANT instead of Msbuild:-

In the target list only one target has been added, which is the build target. This target is responsible for calling other tasks through <call target=”” /> command. These targets are invoked in the order they are written, so the script should take care of the dependencies between the tasks while calling them sequentially. The corresponding script is listed below.

<target name=”Mainbuild” description=”compiles the source code”>

    <call target=”svn.cleanup”/>    <call target=”code.svn.get”/>    <call target=”clean”/>    <call target=”compile”/>    <call target =”create_db”/>

    <call target =”create_tables”/>    <call target =”create_views”/>    <call target =”create_procs”/>    <call target=”runUnitTests”/>

    <call target=”runFxCop”/>    <call target=”RunCodecoverage”/> 

</target>

Here different targets such as “svn.cleanup”, “compile” etc are getting called as per the dependency among them.

Clean up the source control(svn)

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

<property name = “svn.exe.physical.path” value=”c:\program       files\subversion\bin\svn.exe” />

<property name = “Svn.Update.Path”     value=”C:\BuildingSolution”/>

<target name=”svn.cleanup”>

<exec program=”${svn.exe.physical.path}” commandline=’ cleanup “${Svn.Update.Path}”‘ failonerror=”false” verbose=”true” />

</target>

Get latest code from the source control(svn)

Getting the latest code for a particular project using Svn Checkout.

<property name = “svn.uri”        value=”Trunk URL ” />

<property name = “Svn.Update.Path”     value=”C:\BuildingSolution”/>

<target name=”code.svn.get”>

    <svn-checkout      destination=”${Svn.Update.Path}” uri=”${svn.uri}” verbose=”true” username=”username” password=”password” />

</target>

  Versioning

Creating a task which generates the version.

<asminfo output=”AssemblyInfo.cs” language=”CSharp”>

    <imports>

      <import namespace=”System” />

      <import namespace=”System.Reflection” />

     </imports>

    <attributes>

      <attribute type=”ComVisibleAttribute” value=”false” />

      <attribute type=”CLSCompliantAttribute” value=”true” />

      <attribute type=”AssemblyVersionAttribute” value=”1.0.0.0″ />

      <attribute type=”AssemblyTitleAttribute” value=”My assembly” />

<attribute type=”AssemblyDescriptionAttribute” value=”ur description” />

<attribute type=”AssemblyCopyrightAttribute” value=”ur copyright info />

<attribute type=”ApplicationNameAttribute” value=”myAssembly” />

    </attributes>

    <references>

      <include name=”System.EnterpriseServices.dll” />

    </references>

</asminfo>

Cleanup, Compilation(msbuild)

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

In the “compile” target, we are using <msbuild> task to compile the project since compilation through nant for web-based projects are not as successful as msbuild based compilation. See the script snippet below.

<property name=”Build.OutputFolder”   value=”c:\builds\buildingsolution\”/>

<target name=”clean” description=”remove all generated files”>

    <delete>

      <fileset basedir=”${Build.OutputFolder}Latest\”>

        <includes name=”*.*”/>

      </fileset>

    </delete>

</target>

 

<target name=”compile” description=”Compiles using the AutomatedDebug Configuration”>

<loadtasks assembly=”C:\Softwares\nant-0.85-bin\nant-0.85\bin\nant.exe” />

<!–We are using msbuild task for compiling is bcoz nant may not be successfull in building the web applications–>

<msbuild project=”C:\projects\BuildingSolution\BuildingSolution.sln”>

<property name=”Configuration” value=”Debug” verbose=”true”/>

    </msbuild>

</target>

Note: – Though we can compile source code using devenv.exe, it requires Visual Studio to be installed on the machine. This is the reason why we are using MSBuild instead.

 Cleanup, Unit Testing(NUnit)

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

<property name=”Build.OutputFolder”   value=”c:\builds\buildingsolution\”/>

<target name=”cleanuptestfiles”>

    <delete>

      <fileset basedir=”${Build.OutputFolder}buildlogs\”>

        <includes name=”test.xml”/>

      </fileset>

    </delete>

</target>

<target name=”runUnitTests” description=”Runs unit tests on       specified dlls”>

              <nunit2 failonerror=”false” verbose=”true”>

<formatter outputdir=”${Build.OutputFolder}\” usefile=”true” type=”Xml” extension=”.xml”/>

               <test>

<assemblies basedir=”C:\BuildingSolution\BuildingTest\bin\Debug”>

                            <includes name=”*Test.dll”/>

                          </assemblies>

              </test>

  </nunit2>

</target>

Cleanup, Code coverage(NCover)

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

<property name=”Build.OutputFolder”   value=”c:\builds\buildingsolution\”/>

<target name=”cleanupcover”>

    <delete>

      <fileset basedir=”${Build.OutputFolder}buildlogs\”>

        <includes name=”coverage.xml”/>

      </fileset>

    </delete>

</target>

<target name=”RunCodecoveragefiles” description=”Generate code coverage using NCover”>

    <exec program=”C:\Program Files\NCover\NCover.Console.exe”>

      <arg value=”//w &quot;C:\projects\BuildingSolution&quot;” />

<arg value=”//x &quot; ${Build.OutputFolder}buildlogs \coverage.xml&quot;” />

<arg value=”&quot;C:\projects\BuildingSolution\BuildingUI\bin\Debug\BuildingUI.exe&quot;” />

      <arg value=”BuildingTest.dll” />

    </exec>

</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.

<property name=”Build.OutputFolder”   value=”c:\builds\buildingsolution\”/>

<target name=”cleanupfxcopfiles”>

    <delete>

      <fileset basedir=”${Build.OutputFolder}buildlogs\”>

        <includes name=”fxcop-results.xml”/>

      </fileset>

    </delete>

</target>

<target name=”runFxCop”>

<exec program=”C:\Program Files\Microsoft FxCop 1.35\fxcopcmd.exe”

      commandline=”/p:${nant.project.basedir}\${nant.project.name}.fxcop /o:${Build.OutputFolder}\fxcop-results.xml” failonerror=”false”/>

</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.

<property name = “db.server” value=”UrDBServer” />

<property name = “db.instance” value=”\SQLEXPRESS” />

<property name = “db.user” value=”sa” />

<property name = “db.password” value=”sa” />

<property name = “db.name” value=”BuildingSolutionDB” />

<target name=”create_db” description=”Create DB”>                

              <echo message=”Creating Database….”/>

              <exec program=”osql.exe” commandline=”-S ${db.server}${db.instance} -U ${db.user} -P ${db.password} -b -n -i Database\createDB.sql” verbose=”true”/>

              <echo message=”Database Created successfully….”/>

</target>

 

<target name=”create_tables” description=”Create Tables”>                    

                        <echo message=”Creating Tables”/>

                        <foreach item=”File” property=”filename”>

                                    <in>

                                                <items>

<include name=”Database\Tables\*.sql”></include>

                                                </items>

                                    </in>

                                    <do>

<regex pattern=”^(?’path’.*(\\|/)|(/|\\))(?’file’.*)$” input=”${filename}” />

<exec program=”sqlcmd” verbose =”true” commandline=’-S ${db.server}${db.instance} -U ${db.user} -P ${db.password} -i “${filename}”‘/>

                                    </do>

                        </foreach>

</target>

 

<target name=”create_views” description=”Create Views”>

    <echo message=”Creating Views”/>

    <foreach item=”File” property=”filename”>

      <in>

        <items>

          <include name=”Database\Views\*.sql”></include>

        </items>

      </in>

      <do>

        <regex pattern=”^(?’path’.*(\\|/)|(/|\\))(?’file’.*)$” input=”${filename}” />

<exec program=”sqlcmd” verbose =”true” commandline=’-S ${db.server}${db.instance} -U ${db.user} -P ${db.password} -i “${filename}”‘/>

      </do>

    </foreach>

</target>

 

<target name=”create_procs” description=”Create Stored Procs”>

    <echo message=”Creating Stored Procedures”/>

    <foreach item=”File” property=”filename”>

      <in>

        <items>

<include name=”Database\StoredProcedures\*.sql”></include>

        </items>

      </in>

      <do>

        <regex pattern=”^(?’path’.*(\\|/)|(/|\\))(?’file’.*)$” input=”${filename}” />

<exec program=”sqlcmd” verbose =”true” commandline=’-S ${db.server}${db.instance} -U ${db.user} -P ${db.password} -i “${filename}”‘/>

      </do>

    </foreach>

</target>

  CCNet.Config File:-The Only Chnages here from the MSbuild approach will be ,We ll be calling Nant Task Like the following:-

<tasks>

      <nant>

        <executable>C:\Softwares\nant-0.85-bin\nant-0.85\bin\nant.exe</executable>

        <baseDirectory>C:\BuildingSolution</baseDirectory>

        <buildFile>BuildingSolution.build</buildFile>

        <targetList>

          <target>Mainbuild</target>

        </targetList>

        <buildTimeoutSeconds>1200</buildTimeoutSeconds>

      </nant>

    </tasks>

 

Now That we discussed both Nant as well as Msbuild based approaches,Let discuss few important extensibility points before moving out to tools like CIfactory and TeamCity.In part-4 We ll be covering Extensibilty and in Part-5 we ll be covering CI factory and TeamCity and I will rpovide important links on the Concluding Post.

 

Part4 Link

Part5 Link soon

 

Drop me a line if you found this post useful.

 

Advertisements
Comments
  1. Paul says:

    Great work… but how do you ensure the procs are created in the correct order?

  2. Shreeman says:

    Paul there are couple of ways to handle the sproc dependency:- one arrange in Alphabetical order the script file names and second is to handle the dependency at script level.Also I am going to update the post to include few more details around VS Unit Test and other script artifacts.

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