<p>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.</p>

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

<p>Edit: I'm not using NAnt - only MSBuild.</p>

[{'answer_id': 1164, 'author': 'Michael Stum', 'author_id': 91, 'author_profile': 'https://Stackoverflow.com/users/91', 'pm_score': 2, 'selected': False, 'text': '<p>I am currently "manually" doing it through a prebuild-exec Task, using my <a href="http://www.stum.de/various-tools/cmdtools/" rel="nofollow noreferrer">cmdnetsvnrev</a> tool, but if someone knows a better ccnet-integrated way of doing it, i\'d be happy to hear :-)</p>\n'}, {'answer_id': 1168, 'author': 'hitec', 'author_id': 120, 'author_profile': 'https://Stackoverflow.com/users/120', 'pm_score': 2, 'selected': False, 'text': '<p>I found <a href="http://code.google.com/p/svnrevisionlabeller" rel="nofollow noreferrer">this</a> project on google code. This is <code>CCNET</code> plugin to generate the label in <code>CCNET</code>.</p>\n\n<p>The <code>DLL</code> is tested with <code>CCNET 1.3</code> but it works with <code>CCNET 1.4</code> for me. I\'m successfully using this plugin to label my build.</p>\n\n<p>Now onto passing it to <code>MSBuild</code>...</p>\n'}, {'answer_id': 1169, 'author': 'lubos hasko', 'author_id': 275, 'author_profile': 'https://Stackoverflow.com/users/275', 'pm_score': 4, 'selected': False, 'text': '<p>You have basically two options. Either you write a simple script that will start and parse output from</p>\n\n<p><strong>svn.exe info --revision HEAD</strong></p>\n\n<p>to obtain revision number (then generating AssemblyInfo.cs is pretty much straight forward) or just use plugin for CCNET. Here it is:</p>\n\n<blockquote>\n  <p><strong>SVN Revision Labeller</strong> is a plugin for\n  CruiseControl.NET that allows you to\n  generate CruiseControl labels for your\n  builds, based upon the revision number\n  of your Subversion working copy. This\n  can be customised with a prefix and/or\n  major/minor version numbers.</p>\n  \n  <p><a href="http://code.google.com/p/svnrevisionlabeller/" rel="nofollow noreferrer">http://code.google.com/p/svnrevisionlabeller/</a></p>\n</blockquote>\n\n<p>I prefer the first option because it\'s only roughly 20 lines of code:</p>\n\n<pre><code>using System;\nusing System.Diagnostics;\n\nnamespace SvnRevisionNumberParserSample\n{\n    class Program\n    {\n        static void Main()\n        {\n            Process p = Process.Start(new ProcessStartInfo()\n                {\n                    FileName = @"C:\\Program Files\\SlikSvn\\bin\\svn.exe", // path to your svn.exe\n                    UseShellExecute = false,\n                    RedirectStandardOutput = true,\n                    Arguments = "info --revision HEAD",\n                    WorkingDirectory = @"C:\\MyProject" // path to your svn working copy\n                });\n\n            // command "svn.exe info --revision HEAD" will produce a few lines of output\n            p.WaitForExit();\n\n            // our line starts with "Revision: "\n            while (!p.StandardOutput.EndOfStream)\n            {\n                string line = p.StandardOutput.ReadLine();\n                if (line.StartsWith("Revision: "))\n                {\n                    string revision = line.Substring("Revision: ".Length);\n                    Console.WriteLine(revision); // show revision number on screen                       \n                    break;\n                }\n            }\n\n            Console.Read();\n        }\n    }\n}\n</code></pre>\n'}, {'answer_id': 1172, 'author': 'Rytmis', 'author_id': 266, 'author_profile': 'https://Stackoverflow.com/users/266', 'pm_score': 2, 'selected': False, 'text': '<p>If you prefer doing it on the <code>MSBuild</code> side over the <code>CCNet</code> config, looks like the <code>MSBuild</code> Community Tasks extension\'s <a href="http://msbuildtasks.tigris.org/" rel="nofollow noreferrer"><code>SvnVersion</code></a> task might do the trick.</p>\n'}, {'answer_id': 1216, 'author': 'hitec', 'author_id': 120, 'author_profile': 'https://Stackoverflow.com/users/120', 'pm_score': 2, 'selected': False, 'text': '<blockquote>\n  <p><strong>Customizing csproj files to autogenerate AssemblyInfo.cs</strong><br>\n  <a href="http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspx" rel="nofollow noreferrer">http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspx</a></p>\n  \n  <p>Every time we create a new C# project,\n  Visual Studio puts there the\n  AssemblyInfo.cs file for us. The file\n  defines the assembly meta-data like\n  its version, configuration, or\n  producer.</p>\n</blockquote>\n\n<p>Found the above technique to auto-gen AssemblyInfo.cs using MSBuild. Will post sample shortly.</p>\n'}, {'answer_id': 1235, 'author': 'Justin Walgran', 'author_id': 173, 'author_profile': 'https://Stackoverflow.com/users/173', 'pm_score': 2, 'selected': False, 'text': '<p>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.</p>\n\n<pre><code>&lt;target name="svninfo" description="get the svn checkout information"&gt;\n    &lt;property name="svn.infotempfile" value="${build.directory}\\svninfo.txt" /&gt;\n    &lt;exec program="${svn.executable}" output="${svn.infotempfile}"&gt;\n        &lt;arg value="info" /&gt;\n    &lt;/exec&gt;\n    &lt;loadfile file="${svn.infotempfile}" property="svn.info" /&gt;\n    &lt;delete file="${svn.infotempfile}" /&gt;\n\n    &lt;property name="match" value="" /&gt;\n\n    &lt;regex pattern="URL: (?\'match\'.*)" input="${svn.info}" /&gt;\n    &lt;property name="svn.info.url" value="${match}"/&gt;\n\n    &lt;regex pattern="Repository Root: (?\'match\'.*)" input="${svn.info}" /&gt;\n    &lt;property name="svn.info.repositoryroot" value="${match}"/&gt;\n\n    &lt;regex pattern="Revision: (?\'match\'\\d+)" input="${svn.info}" /&gt;\n    &lt;property name="svn.info.revision" value="${match}"/&gt;\n\n    &lt;regex pattern="Last Changed Author: (?\'match\'\\w+)" input="${svn.info}" /&gt;\n    &lt;property name="svn.info.lastchangedauthor" value="${match}"/&gt;\n\n    &lt;echo message="URL: ${svn.info.url}" /&gt;\n    &lt;echo message="Repository Root: ${svn.info.repositoryroot}" /&gt;\n    &lt;echo message="Revision: ${svn.info.revision}" /&gt;\n    &lt;echo message="Last Changed Author: ${svn.info.lastchangedauthor}" /&gt;\n&lt;/target&gt;\n</code></pre>\n'}, {'answer_id': 505990, 'author': 'R. Martinho Fernandes', 'author_id': 46642, 'author_profile': 'https://Stackoverflow.com/users/46642', 'pm_score': 2, 'selected': False, 'text': '<p>My approach is to use the aforementioned plugin for ccnet and a nant echo task to generate a <code>VersionInfo.cs</code> file containing nothing but the version attributes. I only have to include the <code>VersionInfo.cs</code> file into the build</p>\n\n<p>The echo task simply outputs the string I give it to a file.</p>\n\n<p>If there is a similar MSBuild task, you can use the same approach. Here\'s the small nant task I use:</p>\n\n<pre><code>&lt;target name="version" description="outputs version number to VersionInfo.cs"&gt;\n  &lt;echo file="${projectdir}/Properties/VersionInfo.cs"&gt;\n    [assembly: System.Reflection.AssemblyVersion("$(CCNetLabel)")]\n    [assembly: System.Reflection.AssemblyFileVersion("$(CCNetLabel)")]\n  &lt;/echo&gt;\n&lt;/target&gt;\n</code></pre>\n\n<p>Try this:</p>\n\n<pre><code>&lt;ItemGroup&gt;\n    &lt;VersionInfoFile Include="VersionInfo.cs"/&gt;\n    &lt;VersionAttributes&gt;\n        [assembly: System.Reflection.AssemblyVersion("${CCNetLabel}")]\n        [assembly: System.Reflection.AssemblyFileVersion("${CCNetLabel}")]\n    &lt;/VersionAttributes&gt;\n&lt;/ItemGroup&gt;\n&lt;Target Name="WriteToFile"&gt;\n    &lt;WriteLinesToFile\n        File="@(VersionInfoFile)"\n        Lines="@(VersionAttributes)"\n        Overwrite="true"/&gt;\n&lt;/Target&gt;\n</code></pre>\n\n<p>Please note that I\'m not very intimate with MSBuild, so my script will probably not work out-of-the-box and need corrections...</p>\n'}, {'answer_id': 508342, 'author': 'Dan', 'author_id': 54852, 'author_profile': 'https://Stackoverflow.com/users/54852', 'pm_score': 1, 'selected': False, 'text': "<p>Be careful.  The structure used for build numbers is only a short so you have a ceiling on how high your revision can go.</p>\n\n<p>In our case, we've already exceeded the limit.</p>\n\n<p>If you attempt to put in the build number 99.99.99.599999, the file version property will actually come out as 99.99.99.10175.</p>\n"}, {'answer_id': 975299, 'author': 'skolima', 'author_id': 3205, 'author_profile': 'https://Stackoverflow.com/users/3205', 'pm_score': 7, 'selected': True, 'text': '<p>CruiseControl.Net 1.4.4 has now an <a href="http://confluence.public.thoughtworks.org/display/CCNET/Assembly+Version+Labeller" rel="noreferrer">Assembly Version Labeller</a>, which generates version numbers compatible with .Net assembly properties.</p>\n\n<p>In my project I have it configured as:</p>\n\n<pre><code>&lt;labeller type="assemblyVersionLabeller" incrementOnFailure="true" major="1" minor="2"/&gt;\n</code></pre>\n\n<p>(Caveat: <code>assemblyVersionLabeller</code> won\'t start generating svn revision based labels until an actual commit-triggered build occurs.)</p>\n\n<p>and then consume this from my MSBuild projects with <a href="http://msbuildtasks.tigris.org/" rel="noreferrer">MSBuildCommunityTasks.AssemblyInfo</a> :</p>\n\n<pre><code>&lt;Import Project="$(MSBuildExtensionsPath)\\MSBuildCommunityTasks\\MSBuild.Community.Tasks.Targets"/&gt;\n&lt;Target Name="BeforeBuild"&gt;\n  &lt;AssemblyInfo Condition="\'$(CCNetLabel)\' != \'\'" CodeLanguage="CS" OutputFile="Properties\\AssemblyInfo.cs" \n  AssemblyTitle="MyTitle" AssemblyCompany="MyCompany" AssemblyProduct="MyProduct"\n  AssemblyCopyright="Copyright ©  2009" ComVisible="false" Guid="some-random-guid"\n  AssemblyVersion="$(CCNetLabel)" AssemblyFileVersion="$(CCNetLabel)"/&gt;\n&lt;/Target&gt;\n</code></pre>\n\n<p>For sake of completness, it\'s just as easy for projects using NAnt instead of MSBuild:</p>\n\n<pre><code>&lt;target name="setversion" description="Sets the version number to CruiseControl.Net label."&gt;\n    &lt;script language="C#"&gt;\n        &lt;references&gt;\n            &lt;include name="System.dll" /&gt;\n        &lt;/references&gt;\n        &lt;imports&gt;\n            &lt;import namespace="System.Text.RegularExpressions" /&gt;\n        &lt;/imports&gt;\n        &lt;code&gt;&lt;![CDATA[\n             [TaskName("setversion-task")]\n             public class SetVersionTask : Task\n             {\n              protected override void ExecuteTask()\n              {\n               StreamReader reader = new StreamReader(Project.Properties["filename"]);\n               string contents = reader.ReadToEnd();\n               reader.Close();\n               string replacement = "[assembly: AssemblyVersion(\\"" + Project.Properties["CCNetLabel"] + "\\")]";\n               string newText = Regex.Replace(contents, @"\\[assembly: AssemblyVersion\\("".*""\\)\\]", replacement);\n               StreamWriter writer = new StreamWriter(Project.Properties["filename"], false);\n               writer.Write(newText);\n               writer.Close();\n              }\n             }\n             ]]&gt;\n        &lt;/code&gt;\n    &lt;/script&gt;\n    &lt;foreach item="File" property="filename"&gt;\n        &lt;in&gt;\n            &lt;items basedir=".."&gt;\n                &lt;include name="**\\AssemblyInfo.cs"&gt;&lt;/include&gt;\n            &lt;/items&gt;\n        &lt;/in&gt;\n        &lt;do&gt;\n            &lt;setversion-task /&gt;\n        &lt;/do&gt;\n    &lt;/foreach&gt;\n&lt;/target&gt;\n</code></pre>\n'}, {'answer_id': 1414774, 'author': 'galaktor', 'author_id': 140607, 'author_profile': 'https://Stackoverflow.com/users/140607', 'pm_score': 2, 'selected': False, 'text': '<p>Based on skolimas solution I updated the NAnt script to also update the AssemblyFileVersion. Thanks to skolima for the code!</p>\n\n<pre><code>&lt;target name="setversion" description="Sets the version number to current label."&gt;\n        &lt;script language="C#"&gt;\n            &lt;references&gt;\n                    &lt;include name="System.dll" /&gt;\n            &lt;/references&gt;\n            &lt;imports&gt;\n                    &lt;import namespace="System.Text.RegularExpressions" /&gt;\n            &lt;/imports&gt;\n            &lt;code&gt;&lt;![CDATA[\n                     [TaskName("setversion-task")]\n                     public class SetVersionTask : Task\n                     {\n                      protected override void ExecuteTask()\n                      {\n                       StreamReader reader = new StreamReader(Project.Properties["filename"]);\n                       string contents = reader.ReadToEnd();\n                       reader.Close();                     \n                       // replace assembly version\n                       string replacement = "[assembly: AssemblyVersion(\\"" + Project.Properties["label"] + "\\")]";\n                       contents = Regex.Replace(contents, @"\\[assembly: AssemblyVersion\\("".*""\\)\\]", replacement);                                        \n                       // replace assembly file version\n                       replacement = "[assembly: AssemblyFileVersion(\\"" + Project.Properties["label"] + "\\")]";\n                       contents = Regex.Replace(contents, @"\\[assembly: AssemblyFileVersion\\("".*""\\)\\]", replacement);                                        \n                       StreamWriter writer = new StreamWriter(Project.Properties["filename"], false);\n                       writer.Write(contents);\n                       writer.Close();\n                      }\n                     }\n                     ]]&gt;\n            &lt;/code&gt;\n        &lt;/script&gt;\n        &lt;foreach item="File" property="filename"&gt;\n            &lt;in&gt;\n                    &lt;items basedir="${srcDir}"&gt;\n                            &lt;include name="**\\AssemblyInfo.cs"&gt;&lt;/include&gt;\n                    &lt;/items&gt;\n            &lt;/in&gt;\n            &lt;do&gt;\n                    &lt;setversion-task /&gt;\n            &lt;/do&gt;\n        &lt;/foreach&gt;\n    &lt;/target&gt;\n</code></pre>\n'}, {'answer_id': 2619371, 'author': 'grimus', 'author_id': 74346, 'author_profile': 'https://Stackoverflow.com/users/74346', 'pm_score': 2, 'selected': False, 'text': '<p>I\'m not sure if this work with CCNET or not, but I\'ve created an <a href="http://happyturtle.codeplex.com/" rel="nofollow noreferrer">SVN version plug-in</a> for the <a href="http://autobuildversion.codeplex.com/" rel="nofollow noreferrer">Build Version Increment</a> project on CodePlex.  This tool is pretty flexible and can be set to automatically create a version number for you using the svn revision.  It doesn\'t require writing any code or editing xml, so yay!</p>\n\n<p>I hope this is helps!</p>\n'}, {'answer_id': 12481921, 'author': 'granadaCoder', 'author_id': 214977, 'author_profile': 'https://Stackoverflow.com/users/214977', 'pm_score': 2, 'selected': False, 'text': '<p>No idea where I found this.  But I found this on the internet "somewhere".</p>\n\n<p>This updates all the AssemblyInfo.cs files before the build takes place.</p>\n\n<p>Works like a charm.  All my exe\'s and dll\'s show up as 1.2.3.333 (If "333" were the SVN revision at the time.) (And the original version in the AssemblyInfo.cs file was listed as "1.2.3.0")</p>\n\n<hr>\n\n<p>$(ProjectDir)   (Where my .sln file resides)</p>\n\n<p>$(SVNToolPath)  (points to svn.exe)</p>\n\n<p>are my custom variables, their declarations/definitions are not defined below.</p>\n\n<hr>\n\n<p><a href="http://msbuildtasks.tigris.org/" rel="nofollow noreferrer">http://msbuildtasks.tigris.org/</a>\nand/or\n<a href="https://github.com/loresoft/msbuildtasks" rel="nofollow noreferrer">https://github.com/loresoft/msbuildtasks</a>\nhas the ( FileUpdate and SvnVersion ) tasks.</p>\n\n<hr>\n\n<pre><code>  &lt;Target Name="SubVersionBeforeBuildVersionTagItUp"&gt;\n\n    &lt;ItemGroup&gt;\n      &lt;AssemblyInfoFiles Include="$(ProjectDir)\\**\\*AssemblyInfo.cs" /&gt;\n    &lt;/ItemGroup&gt;\n\n    &lt;SvnVersion LocalPath="$(MSBuildProjectDirectory)" ToolPath="$(SVNToolPath)"&gt;\n      &lt;Output TaskParameter="Revision" PropertyName="MySubVersionRevision" /&gt;\n    &lt;/SvnVersion&gt;\n\n    &lt;FileUpdate Files="@(AssemblyInfoFiles)"\n            Regex="(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"\n            ReplacementText="$1.$2.$3.$(MySubVersionRevision)" /&gt;\n  &lt;/Target&gt;\n</code></pre>\n\n<p>EDIT --------------------------------------------------</p>\n\n<p>The above may start failing after your SVN revision number reaches 65534 or higher.</p>\n\n<p>See:</p>\n\n<p><a href="https://stackoverflow.com/questions/13414409/turn-off-warning-cs1607/13751833#13751833">Turn off warning CS1607</a></p>\n\n<p>Here is the workaround.</p>\n\n<pre><code>&lt;FileUpdate Files="@(AssemblyInfoFiles)"\nRegex="AssemblyFileVersion\\(&amp;quot;(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"\nReplacementText="AssemblyFileVersion(&amp;quot;$1.$2.$3.$(SubVersionRevision)" /&gt;\n</code></pre>\n\n<p>The result of this should be:</p>\n\n<p>In Windows/Explorer//File/Properties…….</p>\n\n<p>Assembly Version will be 1.0.0.0.  </p>\n\n<p>File Version will be 1.0.0.333 if 333 is the SVN revision.</p>\n'}]
['https://Stackoverflow.com/questions/1160', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/120/']