我在使用SVN作为源代码控制的示例项目中使用CCNET。 CCNET配置为在每次签入时创建构建.CCNET使用MSBuild构建源代码。
我想在编译时使用最新版本号生成AssemblyInfo.cs
。
如何从subversion中检索最新版本并使用CCNET中的值?
编辑:我没有使用NAnt - 只有MSBuild。
答案 0 :(得分:45)
CruiseControl.Net 1.4.4现在有Assembly Version Labeller,它生成与.Net程序集属性兼容的版本号。
在我的项目中,我将其配置为:
<labeller type="assemblyVersionLabeller" incrementOnFailure="true" major="1" minor="2"/>
(警告:assemblyVersionLabeller
在发生实际的提交触发构建之前,不会开始生成基于svn修订版的标签。)
然后使用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>
答案 1 :(得分:14)
你基本上有两种选择。您可以编写一个简单的脚本来启动并解析
的输出svn.exe信息--revision HEAD
获取修订版号(然后生成AssemblyInfo.cs非常简单)或者只是使用CCNET插件。这是:
SVN Revision Labeller 是一个插件 CruiseControl.NET允许你 为您生成CruiseControl标签 根据修订号编译 您的Subversion工作副本。这个 可以使用前缀和/或自定义 主要/次要版本号。
我更喜欢第一个选项,因为它只有大约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();
}
}
}
答案 2 :(得分:4)
我在Google代码上找到了this项目。这是CCNET
插件,用于在CCNET
生成标签。
DLL
已使用CCNET 1.3
进行了测试,但它适用于CCNET 1.4
。我成功地使用这个插件来标记我的构建。
现在将其传递给MSBuild
...
答案 3 :(得分:4)
如果您希望在MSBuild
配置的CCNet
侧进行此操作,看起来MSBuild
社区任务扩展程序的SvnVersion
任务可能会起作用。
答案 4 :(得分:4)
我编写了一个NAnt构建文件,用于处理解析SVN信息和创建属性。然后,我将这些属性值用于各种构建任务,包括在构建上设置标签。我将这个目标与lubos hasko提到的SVN Revision Labeller结合使用,效果很好。
<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>
答案 5 :(得分:3)
我目前正在“手动”使用我的cmdnetsvnrev工具通过prebuild-exec任务执行此操作,但如果有人知道更好的ccnet集成方式,我会很高兴听到: - )
答案 6 :(得分:3)
自定义csproj文件以自动生成AssemblyInfo.cs
http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspx每次我们创建一个新的C#项目时, Visual Studio放在那里 AssemblyInfo.cs文件给我们。文件 定义程序集元数据 它的版本,配置或 生产者。
使用MSBuild发现上述技术自动生成AssemblyInfo.cs。将很快发布样品。
答案 7 :(得分:3)
我不确定这是否适用于CCNET,但我已为CodePlex上的SVN version plug-in项目创建Build Version Increment。此工具非常灵活,可以设置为使用svn修订版自动为您创建版本号。它不需要编写任何代码或编辑xml,所以耶!
我希望这有帮助!
答案 8 :(得分:2)
我的方法是使用前面提到的ccnet插件和一个nant echo任务来生成一个只包含版本属性的VersionInfo.cs
文件。我只需要将VersionInfo.cs
文件包含在构建
echo任务只输出我将它提供给文件的字符串。
如果存在类似的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不是很亲密,因此我的脚本可能无法开箱即用,需要更正......
答案 9 :(得分:2)
基于skolimas解决方案,我更新了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>
答案 10 :(得分:2)
不知道我在哪里找到了这个。但我在互联网上“在某处”发现了这一点。
这会在构建之前更新所有AssemblyInfo.cs文件。
像魅力一样工作。我的所有exe和dll都显示为1.2.3.333(如果“333”是当时的SVN修订版。)(并且AssemblyInfo.cs文件中的原始版本被列为“1.2.3.0”)
$(ProjectDir)(我的.sln文件所在的位置)
$(SVNToolPath)(指向svn.exe)
是我的自定义变量,它们的声明/定义未在下面定义。
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>
EDIT ---------------------------------------------- ----
在您的SVN修订号达到65534或更高版本后,上述内容可能会失败。
请参阅:
这是解决方法。
<FileUpdate Files="@(AssemblyInfoFiles)"
Regex="AssemblyFileVersion\("(\d+)\.(\d+)\.(\d+)\.(\d+)"
ReplacementText="AssemblyFileVersion("$1.$2.$3.$(SubVersionRevision)" />
结果应该是:
在Windows /资源管理器中//文件/属性......。
汇编版本将为1.0.0.0。
如果333是SVN版本,则文件版本将为1.0.0.333。
答案 11 :(得分:1)
小心点。用于构建号码的结构只有很短的一段时间,因此您可以了解修订版本的高度。
在我们的案例中,我们已超出限制。
如果您尝试输入内部版本号99.99.99.599999,则文件版本属性实际上将为99.99.99.10175。