Automated Subversion Tagging With MSBuild

February 23, 2007 - 3 minute read -
subversion xml msbuild

I've written previously about using MSBuild With Nunit as well as a bit of a Manifesto on Relentless Build Automation. I believe that automating the build and deployment process is a necessary step to ensure the reliable delivery of quality software.

Release Management

One of the things that we as software developers have to do is regularly make releases, either to QA or to a customer. When we make releases we need to be able to continue to develop the software to add new features and fix bugs. Tagging is a safety process that we use in a version control system to allow us to easily get to the code that we used to build a specific release. When you Tag, you can always rebuild that release. So, if weeks or months down the road you need to fix a critical bug, but don't want to release new features, you can get back to the Tag, create a Branch, fix the bug and release the new build to your users.

How Do We Ensure We Can Recreate Releases

How can we ensure that we will be able to recreate a release that we make to either QA or a customer? Use Automation to Tag your builds when you create them of course.

I've contributed a new SvnCopy Task to the MSBuild Community Tasks project which was just accepted and committed. It is currently in the Subversion repository for the project but should be available shortly in an official build. This will allow you to easily automate the process of Tagging or Branching your builds when your release. Subversion uses the Copy metaphor for both Branching and Tagging operations which is different from some other version control systems.

Example:

<Target Name="GetRemoteRevisionNumber">
    <SvnInfo RepositoryPath="$(SvnRemoteRoot)">
        <Output TaskParameter="LastChangedRevision"
             PropertyName="RemoteSvnRevisionNumber"  />
    </SvnInfo>
    <Message Text="Revision: $(RemoteSvnRevisionNumber)"/>
</Target></p>
<p><Target Name="Tag" DependsOnTargets="GetRemoteRevisionNumber">
    <Error Condition="$(SvnUserName)==''"
        Text="You must set your Subversion Username."/>
    <Error Condition="$(SvnPassword)==''" Text="You must set your Subversion Password."/>
    <SvnCopy RepositoryPath="$(SvnRemoteRoot)/trunk"
        DestinationPath="$(SvnRemoteRoot)/tags/REV-$(RemoteSvnRevisionNumber)"
        Message="Auto-tagging Revision: $(RemoteSvnRevisionNumber)"
        Username="$(SvnUserName)" password="$(SvnPassword)"/>
    <Message Text="Tagged: REV-$(RemoteSvnRevisionNumber)"/>
</Target>

You can then integrate the process of creating a Tag every time you generate a build by tying together Tasks with dependencies. In the example below, the GenerateTestBuild calls GenerateCabFiles and Tag to automatically build the installer and Tag Subversion with the current revisions number.

<Target Name="GenerateCabFiles" DependsOnTargets="Build">
    <Exec WorkingDirectory="."
        Command="devenv "$(SolutionFileName)" /build $(Configuration) /project  $(ConfigCabFileProject)"/>
    <Exec WorkingDirectory="."
        Command="devenv "$(SolutionFileName)" /build $(Configuration) /project  $(UiCabFileProject)"/>
</Target></p>
<p><Target Name="DeployCabFiles" DependsOnTargets="GenerateCabFiles">
    <MakeDir Directories="$(DestRoot)\$(BuildFolderPrefix)$(SvnRevisionNumber)"/>
    <MakeDir Directories="$(DestRoot)\$(BuildFolderPrefix)$(SvnRevisionNumber)\FormXmls"/>
    <Copy SourceFiles="@(CabFiles)"
        DestinationFolder="$(DestRoot)\Build$(SvnRevisionNumber)"/>
    <Copy SourceFiles="$(AutoUpdaterConfigFile)"
        DestinationFolder="$(DestRoot)\Build$(SvnRevisionNumber)"/>
    <Copy SourceFiles="$(AutoUpdaterConfigFile)" DestinationFolder="$(DestRoot);"/>
    <Copy SourceFiles="@(FormXmlFiles)"
        DestinationFolder="$(DestRoot)\$(BuildFolderPrefix)$(SvnRevisionNumber)\FormXmls"/>
</Target>
<Target Name="GenerateTestBuild" DependsOnTargets="DeployCabFiles;Tag"/>

Hopefully this will help you get started on some more automation.

Update: MSBuild Community Tasks version 1.2 has been released containing this code. You can get it here.

Resources

MSBuild Community Tasks Subversion