Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / XML

Versioning your .NET Application with Nant and Subversion

4.33/5 (4 votes)
30 Sep 2014CPOL2 min read 14.8K  
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)