Home » Questions » Computers [ Ask a new question ]

Use SVN Revision to label build in CCNET

Use SVN Revision to label build in CCNET

"I am using CCNET on a sample project with SVN as my source control. CCNET is configured to create a build on every check in. CCNET uses MSBuild to build the source code.

I would like to use the latest revision number to generate AssemblyInfo.cs while compiling.
How can I retrieve the latest revision from subversion and use the value in CCNET?

Edit: I'm not using NAnt - only MSBuild."

Asked by: Guest | Views: 77
Total answers/comments: 4
Guest [Entry]

"CruiseControl.Net 1.4.4 has now an Assembly Version Labeller, which generates version numbers compatible with .Net assembly properties.

In my project I have it configured as:

<labeller type=""assemblyVersionLabeller"" incrementOnFailure=""true"" major=""1"" minor=""2""/>

(Caveat: assemblyVersionLabeller won't start generating svn revision based labels until an actual commit-triggered build occurs.)

and then consume this from my MSBuild projects with MSBuildCommunityTasks.AssemblyInfo :

<Import Project=""$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets""/>
<Target Name=""BeforeBuild"">
<AssemblyInfo Condition=""'$(CCNetLabel)' != ''"" CodeLanguage=""CS"" OutputFile=""Properties\AssemblyInfo.cs""
AssemblyTitle=""MyTitle"" AssemblyCompany=""MyCompany"" AssemblyProduct=""MyProduct""
AssemblyCopyright=""Copyright © 2009"" ComVisible=""false"" Guid=""some-random-guid""
AssemblyVersion=""$(CCNetLabel)"" AssemblyFileVersion=""$(CCNetLabel)""/>
</Target>

For sake of completness, it's just as easy for projects using NAnt instead of MSBuild:

<target name=""setversion"" description=""Sets the version number to CruiseControl.Net label."">
<script language=""C#"">
<references>
<include name=""System.dll"" />
</references>
<imports>
<import namespace=""System.Text.RegularExpressions"" />
</imports>
<code><![CDATA[
[TaskName(""setversion-task"")]
public class SetVersionTask : Task
{
protected override void ExecuteTask()
{
StreamReader reader = new StreamReader(Project.Properties[""filename""]);
string contents = reader.ReadToEnd();
reader.Close();
string replacement = ""[assembly: AssemblyVersion(\"""" + Project.Properties[""CCNetLabel""] + ""\"")]"";
string newText = Regex.Replace(contents, @""\[assembly: AssemblyVersion\("""".*""""\)\]"", replacement);
StreamWriter writer = new StreamWriter(Project.Properties[""filename""], false);
writer.Write(newText);
writer.Close();
}
}
]]>
</code>
</script>
<foreach item=""File"" property=""filename"">
<in>
<items basedir="".."">
<include name=""**\AssemblyInfo.cs""></include>
</items>
</in>
<do>
<setversion-task />
</do>
</foreach>
</target>"
Guest [Entry]

"You have basically two options. Either you write a simple script that will start and parse output from

svn.exe info --revision HEAD

to obtain revision number (then generating AssemblyInfo.cs is pretty much straight forward) or just use plugin for CCNET. Here it is:

SVN Revision Labeller is a plugin for
CruiseControl.NET that allows you to
generate CruiseControl labels for your
builds, based upon the revision number
of your Subversion working copy. This
can be customised with a prefix and/or
major/minor version numbers.

http://code.google.com/p/svnrevisionlabeller/

I prefer the first option because it's only roughly 20 lines of code:

using System;
using System.Diagnostics;

namespace SvnRevisionNumberParserSample
{
class Program
{
static void Main()
{
Process p = Process.Start(new ProcessStartInfo()
{
FileName = @""C:\Program Files\SlikSvn\bin\svn.exe"", // path to your svn.exe
UseShellExecute = false,
RedirectStandardOutput = true,
Arguments = ""info --revision HEAD"",
WorkingDirectory = @""C:\MyProject"" // path to your svn working copy
});

// command ""svn.exe info --revision HEAD"" will produce a few lines of output
p.WaitForExit();

// our line starts with ""Revision: ""
while (!p.StandardOutput.EndOfStream)
{
string line = p.StandardOutput.ReadLine();
if (line.StartsWith(""Revision: ""))
{
string revision = line.Substring(""Revision: "".Length);
Console.WriteLine(revision); // show revision number on screen
break;
}
}

Console.Read();
}
}
}"
Guest [Entry]

"I have written a NAnt build file that handles parsing SVN information and creating properties. I then use those property values for a variety of build tasks, including setting the label on the build. I use this target combined with the SVN Revision Labeller mentioned by lubos hasko with great results.

<target name=""svninfo"" description=""get the svn checkout information"">
<property name=""svn.infotempfile"" value=""${build.directory}\svninfo.txt"" />
<exec program=""${svn.executable}"" output=""${svn.infotempfile}"">
<arg value=""info"" />
</exec>
<loadfile file=""${svn.infotempfile}"" property=""svn.info"" />
<delete file=""${svn.infotempfile}"" />

<property name=""match"" value="""" />

<regex pattern=""URL: (?'match'.*)"" input=""${svn.info}"" />
<property name=""svn.info.url"" value=""${match}""/>

<regex pattern=""Repository Root: (?'match'.*)"" input=""${svn.info}"" />
<property name=""svn.info.repositoryroot"" value=""${match}""/>

<regex pattern=""Revision: (?'match'\d+)"" input=""${svn.info}"" />
<property name=""svn.info.revision"" value=""${match}""/>

<regex pattern=""Last Changed Author: (?'match'\w+)"" input=""${svn.info}"" />
<property name=""svn.info.lastchangedauthor"" value=""${match}""/>

<echo message=""URL: ${svn.info.url}"" />
<echo message=""Repository Root: ${svn.info.repositoryroot}"" />
<echo message=""Revision: ${svn.info.revision}"" />
<echo message=""Last Changed Author: ${svn.info.lastchangedauthor}"" />
</target>"
Guest [Entry]

"I found this project on google code. This is CCNET plugin to generate the label in CCNET.

The DLL is tested with CCNET 1.3 but it works with CCNET 1.4 for me. I'm successfully using this plugin to label my build.

Now onto passing it to MSBuild..."