Click here to Skip to main content
15,886,137 members
Articles / Programming Languages / XML
Tip/Trick

Versioning your .NET Application with Nant and Subversion

Rate me:
Please Sign up or sign in to vote.
4.33/5 (4 votes)
30 Sep 2014CPOL2 min read 14.3K   6   3
Versioning your .NET application with Nant and Subversion

Introduction

If you have used Nant previously to build your applications, then you may want to consider versioning them using Nant. This ensures that your entire build process is contained within your build script, so the same script that builds your application is also responsible for versioning it.

If you use Subversion (SVN) as your version control system, then you can stamp your assembly using the revision number that the assembly was built from and therefore give traceability as to the origins of your deployed assemblies. For example, if your assembly is stamped with the version number 123 then you know that it was built from revision 123 from your SVN repository.

The assembly is stamped with MAJOR.MINOR version numbers. The major version number is set manually in the build script, and this will need to be incremented with each major release of the application. As this will change less frequently than your minor version number, then this should not pose a problem. The minor version number is the SVN revision number and will change with each build of the application. You will see these version numbers when you right-click on your assembly and view Properties.

Background

It is assumed that the reader is familiar with Nant syntax.

Although I created the Nant script to build a Visual Studio application, the concepts described here can be equally applied to other languages / environments.

Script Setup

Below are the Nant setup statements that set the required properties that will be used by the UpdateAssemblyInfo and GetLatestRevisionNumber targets. Place these statements at the top of your build script (before you invoke either of the targets).

XML
<!--These can all be set at the top of your build script-->
<property name="verbose" value="true" />
<property name="build.dir" value="${directory::get-current-directory()}" />
<property name="startup.project.dir"        value="MyProjectFolder" />
<property name="solution.name"              value="MySolution.sln" />
<property name="application.name"           value="The name of my application" />
<tstamp verbose="${verbose}">
  <formatter property="year" pattern="yyyy" />
</tstamp>

<!--AssemblyInfo.cs properties-->
<!--The major version number is specified here-->
<property name="version.number"      value="1.0" />
<property name="company.name"        value="MyCompany" />
<property name="copyright.notice"
    value="Copyright © ${company.name}" />
<property name="assemblyinfo.file"
    value="${build.dir}\${startup.project.dir}\Properties\assemblyinfo.cs" />

<!--SVN properties -->
<property name="svn.file"
    value="c:\subversion\bin\svn.exe" />
<property name="svn.repository.path"
    value="https://subversion/svn/MyRepository/" />

Getting the Latest Revision Number from SVN

The Nant target GetLatestRevisionNumber gets the latest revision number from Subversion and sets the property svn.latest.revision.number with this number.

XML
<target name="GetLatestRevisionNumber">
  <!--Get the latest SVN revision and use this as the minor version number-->
  <echo message="Task execution started at :
      ${script::format-to-string(datetime::now())}" />

  <exec program="${svn.file}"
      failonerror="true" verbose="${verbose}"
      commandline='info "${svn.repository.path}" --xml'
      output="svninfo.xml" />
  <xmlpeek failonerror="true" verbose="${verbose}"
      file="svninfo.xml"
      xpath="/info/entry/commit/@revision"
      property="svn.latest.revision.number"/>
  <delete file="svninfo.xml" failonerror="true" verbose="${verbose}" />

  <echo message="Task execution finished at : ${script::format-to-string(datetime::now())}" />
</target>

Versioning Your Assembly

Once you have determined the latest SVN revision number, you can stamp your assembly with it as in the Nant target UpdateAssemblyInfo below.

XML
<target name="UpdateAssemblyInfo" depends="GetLatestRevisionNumber" >
  <!-- Brands the assemblyInfo.cs file with version number etc -->
  <echo message="Task execution started at :
      ${script::format-to-string(datetime::now())}" />

    <asminfo output="${assemblyinfo.file}"
             language="CSharp"
             failonerror="true"
             verbose="${verbose}">
      <imports>
        <import namespace="System" />
        <import namespace="System.Reflection" />
        <import namespace="System.Runtime.InteropServices" />
      </imports>
      <attributes>
        <attribute type="AssemblyVersionAttribute"
          value="${version.number}" />
        <attribute type="AssemblyFileVersionAttribute"
          value="${version.number}.${svn.latest.revision.number}" />
        <attribute type="AssemblyCompanyAttribute"
          value="${company.name}" />
        <attribute type="AssemblyCopyrightAttribute"
          value="${copyright.notice} ${year}" />
        <attribute type="AssemblyConfigurationAttribute"
          value="RELEASE" />
        <attribute type="AssemblyDescriptionAttribute"
          value="${application.name}" />
      </attributes>
    </asminfo>

  <echo message="Task execution finished at : ${script::format-to-string(datetime::now())}" />
</target>

Summary

Hopefully, I have given sufficient information for you to be able to version your .NET applications using your Nant build script in conjunction with Subversion. Feel free to leave a comment if you would like me to further elaborate on anything within this tip.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead Gold-Vision CRM
United Kingdom United Kingdom
I am a professional software engineer and technical architect with over twenty years commercial development experience with a strong focus on the design and development of web and mobile applications.

I have experience of architecting scalable, distributed, high volume web applications that are accessible from multiple devices due to their responsive web design, including architecting enterprise service-oriented solutions. I have also developed enterprise mobile applications using Xamarin and Telerik Platform.

I have extensive experience using .NET, ASP.NET, Windows and Web Services, WCF, SQL Server, LINQ and other Microsoft technologies. I am also familiar with HTML, Bootstrap, Javascript (inc. JQuery and Node.js), CSS, XML, JSON, Apache Cordova, KendoUI and many other web and mobile related technologies.

I am enthusiastic about Continuous Integration, Continuous Delivery and Application Life-cycle Management having configured such environments using CruiseControl.NET, TeamCity and Team Foundation Services. I enjoy working in Agile and Test Driven Development (TDD) environments.

Outside of work I have two beautiful daughters. I am also an avid cyclist who enjoys reading, listening to music and travelling.

Comments and Discussions

 
QuestionGreat Pin
louhy8-Apr-15 5:37
louhy8-Apr-15 5:37 
GeneralMy vote of 3 Pin
ThanhTrungDo1-Oct-14 7:28
professionalThanhTrungDo1-Oct-14 7:28 
GeneralRe: My vote of 3 Pin
Dominic Burford1-Oct-14 9:22
professionalDominic Burford1-Oct-14 9:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.