使用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标签。 这可以使用前缀和/或主要/次要版本号进行定制。
我更喜欢第一个选项,因为它只有大约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
…
如果你喜欢通过CCNet
configuration在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,它们的声明/定义没有在下面定义。
<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\("(\d+)\.(\d+)\.(\d+)\.(\d+)" ReplacementText="AssemblyFileVersion("$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。