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).
<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>
<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" />
<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.
<target name="GetLatestRevisionNumber">
<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.
<target name="UpdateAssemblyInfo" depends="GetLatestRevisionNumber" >
<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.