使用SVN修订标签在CCNETbuild立

我正在使用SVN作为源代码控件的示例项目上使用CCNET。 CCNET被configuration为在每次检入时创build一个构build。CCNET使用MSBuild构build源代码。

我想在编译时使用最新的版本号来生成AssemblyInfo.cs。 我怎样才能从颠覆中检索最新版本,并使用CCNET中的值?

编辑:我不使用NAnt – 只有MSBuild。

CruiseControl.Net 1.4.4现在有一个Assembly Version Labeller ,它生成与.Net程序集属性兼容的版本号。

在我的项目中,我把它configuration为:

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

(警告: assemblyVersionLabeller将不会开始生成基于SVN版本的标签,直到发生实际的提交触发构build。

然后使用MSBuildCommunityTasks.AssemblyInfo从我的MSBuild项目中使用这个 :

 <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> 

为了完整性,对于使用NAnt而不是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> 

你基本上有两个select。 要么你写一个简单的脚本,将启动和parsing输出

svn.exe信息 – 修正HEAD

获得修订号(然后生成AssemblyInfo.cs是非常直截了当的),或者只是使用CCNET的插件。 这里是:

SVN Revision Labeller是CruiseControl.NET的一个插件,它允许您根据Subversion工作副本的版本号为您的版本生成CruiseControl标签。 这可以使用前缀和/或主要/次要版本号进行定制。

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

我更喜欢第一个选项,因为它只有大约20行代码:

 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(); } } } 

我写了一个NAnt构build文件来处理分析SVN信息和创build属性。 然后,我将这些属性值用于各种构build任务,包括在构build上设置标签。 我将这个目标与lubos hasko提到的SVN修订标签结合起来,效果很好。

 <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> 

我发现这个项目在谷歌代码。 这是CCNET插件在CCNET生成标签。

DLL使用CCNET 1.3进行testing,但对于我来说,它可以与CCNET 1.4使用。 我成功地使用这个插件来标记我的构build。

现在把它传递给MSBuild

如果你喜欢通过CCNetconfiguration在MSBuild端进行,看起来像MSBuild社区任务扩展的SvnVersion任务可能会有所SvnVersion

我目前通过prebuild-exec任务使用我的cmdnetsvnrev工具“手动”执行它,但如果有人知道更好的ccnet集成方法,我会很高兴听到:-)

定制csproj文件以自动生成AssemblyInfo.cs
http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspx

每次我们创build一个新的C#项目时,Visual Studio都会为我们提供AssemblyInfo.cs文件。 该文件定义汇编元数据,如版本,configuration或生产者。

发现上述技术使用MSBuild自动生成AssemblyInfo.cs。 很快就会发布样本。

我不确定这是否与CCNET一起工作,但是我为CodePlex上的Build Version Increment项目创build了一个SVN版本插件 。 这个工具非常灵活,可以设置为使用svn修订版为你自动创build一个版本号。 它不需要编写任何代码或编辑XML,所以耶!

我希望这是帮助!

我的方法是使用上述ccnet的插件和nant的echo任务来生成一个VersionInfo.cs包含版本属性的VersionInfo.cs文件。 我只需要将VersionInfo.cs文件包含到构build中

回声任务只是输出我给它一个文件的string。

如果有类似的MSBuild任务,则可以使用相同的方法。 以下是我使用的小型任务:

 <target name="version" description="outputs version number to VersionInfo.cs"> <echo file="${projectdir}/Properties/VersionInfo.cs"> [assembly: System.Reflection.AssemblyVersion("$(CCNetLabel)")] [assembly: System.Reflection.AssemblyFileVersion("$(CCNetLabel)")] </echo> </target> 

尝试这个:

 <ItemGroup> <VersionInfoFile Include="VersionInfo.cs"/> <VersionAttributes> [assembly: System.Reflection.AssemblyVersion("${CCNetLabel}")] [assembly: System.Reflection.AssemblyFileVersion("${CCNetLabel}")] </VersionAttributes> </ItemGroup> <Target Name="WriteToFile"> <WriteLinesToFile File="@(VersionInfoFile)" Lines="@(VersionAttributes)" Overwrite="true"/> </Target> 

请注意,我对MSBuild不是非常亲密,所以我的脚本可能无法正常工作,需要更正…

基于skolimas解决scheme,我更新了NAnt脚本以更新AssemblyFileVersion。 感谢skolima的代码!

 <target name="setversion" description="Sets the version number to current 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(); // replace assembly version string replacement = "[assembly: AssemblyVersion(\"" + Project.Properties["label"] + "\")]"; contents = Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replacement); // replace assembly file version replacement = "[assembly: AssemblyFileVersion(\"" + Project.Properties["label"] + "\")]"; contents = Regex.Replace(contents, @"\[assembly: AssemblyFileVersion\("".*""\)\]", replacement); StreamWriter writer = new StreamWriter(Project.Properties["filename"], false); writer.Write(contents); writer.Close(); } } ]]> </code> </script> <foreach item="File" property="filename"> <in> <items basedir="${srcDir}"> <include name="**\AssemblyInfo.cs"></include> </items> </in> <do> <setversion-task /> </do> </foreach> </target> 

不知道我在哪里find这个。 但是我在互联网上发现了这个“某处”。

在构build发生之前,这将更新所有AssemblyInfo.cs文件。

奇迹般有效。 我所有的exe和dll都显示为1.2.3.333(如果“333”是当时的SVN修订版)(并且AssemblyInfo.cs文件中的原始版本被列为“1.2.3.0”)


$(ProjectDir)(我的.sln文件所在的地方)

$(SVNToolPath)(指向svn.exe)

是我的自定义variables,它们的声明/定义没有在下面定义。


http://msbuildtasks.tigris.org/和/或https://github.com/loresoft/msbuildtasks具有(FileUpdate和SvnVersion)任务。;


  <Target Name="SubVersionBeforeBuildVersionTagItUp"> <ItemGroup> <AssemblyInfoFiles Include="$(ProjectDir)\**\*AssemblyInfo.cs" /> </ItemGroup> <SvnVersion LocalPath="$(MSBuildProjectDirectory)" ToolPath="$(SVNToolPath)"> <Output TaskParameter="Revision" PropertyName="MySubVersionRevision" /> </SvnVersion> <FileUpdate Files="@(AssemblyInfoFiles)" Regex="(\d+)\.(\d+)\.(\d+)\.(\d+)" ReplacementText="$1.$2.$3.$(MySubVersionRevision)" /> </Target> 

编辑————————————————- –

SVN修订版号达到65534或更高版本后,上述操作可能会失败。

看到:

closures警告CS1607

这是解决方法。

 <FileUpdate Files="@(AssemblyInfoFiles)" Regex="AssemblyFileVersion\(&quot;(\d+)\.(\d+)\.(\d+)\.(\d+)" ReplacementText="AssemblyFileVersion(&quot;$1.$2.$3.$(SubVersionRevision)" /> 

这样的结果应该是:

在Windows /资源pipe理器/ /文件/属性……。

程序集版本将是1.0.0.0。

如果333是SVN版本,则文件版本将为1.0.0.333。

小心。 用于构build数字的结构只是一个简短的说法,因此您可以对修订版本的高度有一个限制。

在我们的情况下,我们已经超出了限制。

如果您尝试input内部版本号99.99.99.599999,文件版本属性实际上会出现为99.99.99.10175。