Automated build for my ASP.NET project using NAnt

As I’ve promised – I share with you my experience with NAnt while attempting to automate my build process for my ASP.NET project. After reading a lot on the subject, I must admit that the documentation is quite poor and the “open source” examples are not exactly what I’m looking for. Before I’ll start, if you don’t know what is NAnt or NAnt contrib, now will be a good time to do some reading, I’ll wait…


Requirements (What do you need to install before you can start):



  1. Download and install NAnt.
  2. Add the nant\bin directory path to your PATH variable (“System Variables”).
  3. Download and install NAnt contrib.
  4. Integrate between NAnt and NAnt contrib using these steps:

    1. Copy nant-contrib\bin\*.dll to nant\bin\ directory.
    2. Create the folder nant\bin\tasks\net (manually).
    3. Copy nant-contrib\bin\*.dll to nant\bin\taks\net directory.

  5. Download NAnt.UtilityTasks.dll and put it in nant\bin directory.

Let’s Start:

OK, now we’re ready to start the build process; So here is my solution structure:


MySolution
   – WebProject (ASP.NET project)
      – *AssemblyInfo.cs
      – Other files and directories (& porno, of course)
   – BusinessLayer (Class Library)
   – DataAccessLayer (Class Library)
   – EntitiesLayer (Class Library)
   – *SolutionInfo.cs
  – etc..


* Before I continue about the process itself, I must mention that I’m using “Link File” option in order to share my AssemblyVersion attribute in my ClassLibraries projects. In a perfect world, ASP.NET projects would be able to “Link File” as well, but (surprisingly) it’s not; So I have 2 places which hold the AssemblyVersion:
1. MySolution\SolutionInfo.cs (This file is being linked in all of my class libraries).
2. MySolution\WebProject\AssemblyInfo.cs.


Great, we can carry on –
I’ve discussed about the proper build process with my friends A&A (The Amir’s aka “The markowitz” and “The Engel”) and we’ve agreed that we require 2 processes – “Build”(complete new version) and “Rebuild”(rebuild the current version, it’s required after the Build process failed for some reason).

The desired processes work flow
:
Note: you don’t need to copycat my process, you’re a free human being, consider me as your Build mentor :-o

1. “Build” process –
   1.1 Increment my build version (SolutionInfo.cs & AssemblyInfo.cs)
         In order to do that, I’m using a great code snippet I found during my last weekend searches to 
         create a new version number. Afterwards, I’m checking-out the SolutionInfo.cs file and imprint the 
         new AssemblyVersion using <asminfo> task.
         Eventually I’m checking-in the SolutionInfo.cs file.

         * I’m using some properties – ${property_name} – for easy maintenance, you can see it in the 
            file I’ve upload (way over down).


   <vsscheckout username=“${vss.username}” password=“${vss.password}” 
      localpath=“${slndir}” recursive=“false” writable=“true” dbpath=“${vss.dbpath}” 
      path=“${vss.slnpath}/SolutionInfo.cs” failonerror=“true” />

   <asminfo output=“${slndir}\SolutionInfo.cs” language=“CSharp”>
      <imports>
         <import namespace=“System” />
         <import namespace=“System.Reflection”/>
         <import namespace=“System.Runtime.CompilerServices”/>
      </imports>
      <attributes>
         <attribute type=“AssemblyVersionAttribute” value=“${build.version}” />
         <attribute type=“AssemblyCompanyAttribute” value=“${company}” />
         <attribute type=“AssemblyProductAttribute” value=“${product}” />
         <attribute type=“AssemblyCopyrightAttribute” value=“Copyright (c) 2005, ${company}.” />
         <attribute type=“AssemblyTrademarkAttribute” value=“Trademark by ${company}” />
         <attribute type=“AssemblyDelaySignAttribute” value=“false” />
         <attribute type=“AssemblyKeyFileAttribute” value=“..//..//..//key.snk” />
         <attribute type=“AssemblyKeyNameAttribute” value=“” />
      </attributes>
   </asminfo>

   <vsscheckin username=“${vss.username}” password=“${vss.password}” 
      localpath=“${slndir}\SolutionInfo.cs” recursive=“false” writable=“true” 
      dbpath=“${vss.dbpath}” path=“${vss.slnpath}/SolutionInfo.cs”
      comment=“change build version: ${build.version}” />


         I use the same code (with minor changes) to update my AssemblyInfo.cs file as well.

   1.2 Put a label on the VSS with the current new version.
         This is even easier, I just use <vsslabel>(NAnt contrib) task:


      <vsslabel
           username=“${vss.username}”
           password=“${vss.password}”
           dbpath=“${vss.dbpath}”
           path=“${vss.slnpath}”
           comment=“New build version: ${build.version}”
           label=“${build.version}”
      />


   1.3 Get the files from the VSS to my local directory recursively using <vssget>(NAnt contrib) task.
      <vssget
           username=“${vss.username}”
           password=“${vss.password}”
           localpath=“${vss.outdir}”
           recursive=“true”
           replace=“true”
           writable=“false”
           dbpath=“${vss.dbpath}”
           path=“${vss.slnpath}”
      />


   1.4 If I’m required to (by property) – generate the projects pdb’s.
        This is great for release mode, I can pull the pdb’s for the version at the Production environment 
        and make some extreme production debugging using the pdb’s as symbols – 
        I must give the credit to “The markowitz” for the idea !
      


        The code is quite simple – build the solution in Debug mode and copy the *.pdb files
        to my “version_directory”\pdb\WebProject.
        You can see the code in the attached file.


   1.5 Build the solution.
         I’m using <solution> task and <webmap> for easy build.
         Again, nothing fancy, look in the attached file.

   1.6 Copy the web project output to my MySolution\Builds\[version_number] directory for 
        an easy XCOPY deployment. I’m using <copywebproject> task in order to do 
        this magic, it’s working like a charm.  
   <copywebproject project=“${slndir}\WebApp\WebApp.csproj” 
      todir=“${outdir}\WebApp” configuration=“${config}” />


   
2. “Rebuild” process – 
      Call steps 1.3 to 1.6.


TIPS:
I recommend that you’ll download VSTweak and let the VS.NET treat your .build file as .xml file.


TODO:
I’m going to add a NAnt task which will get all the *.js\*.htc files from the web project (.csproj) and format them
via Jazmin – this will cut down the size of the files(by removing comments and other not-required characters) for performance improvement (the smaller the file is, the faster the client will download it).


CREDIT:
If you’re using my file as your “template”, I would appreciate if you’ll add a comment and let me know about it, including new features you’ve added or planning to add. I’ve dedicated my time to share with you, please do the same grace with me. Thanks !


My (template) build file:
default.zip (3 KB)

How to run the build file ?
You’ll need to configure the default.build file I’ve attached (5 minutes max).
Go to your solution directory and copy the “default.build” file into it.
Now, activate “cmd” and navigate to that directory.
Type “nant build” and Voila !