在 TFS 构建期间更新程序集版本






4.59/5 (9投票s)
关于如何修改构建模板以在 TFS 构建过程中为程序集添加版本戳的指南
引言
设置项目的版本号似乎是一件很简单的事情,但在部署到测试环境时却常常被忽略,这使得识别当前运行的确切版本变得困难。
随着向敏捷方法的不断推进,持续部署成为团队努力实现的圣杯,在构建和部署管道中自动为程序集打上版本戳将变得至关重要——否则,识别“何物在何处”的任务将变得极易出错!
本文将快速介绍如何使用开源 TFS Build Extensions 修改 Azure 持续部署生成过程模板,为项目的 AssemblyVersion 添加触发的变更集版本戳。此工作流程的一个显著特点是不会将任何内容检入源代码;我最讨厌的许多现有流程之一就是它们会创建额外的检入操作来将版本推回源代码控制;这里忽略了这一点,因为我们只是将变更集编号添加到程序集的修订版,而不更改其他任何内容。
背景
要使用本文,您确实需要拥有 Visual Studio Online 账户、Azure 账户,以及一个已链接到持续部署的项目。
本文假定您使用的是 Visual Studio 2013(但是,您应该也可以使用 Visual Studio 2012,但结果可能会有所不同)。
准备就绪
在做更多事情之前,我们需要实际设置您的 TFS 实例以便进行自定义。 虽然可以将自定义的生成过程模板加载到单个项目中,但最佳实践是将其集中到一个 TFS 项目中——因为每个控制器只能设置一个自定义程序集路径(用于在生成过程中将其作为源代码管理的一部分进行管理)。
所以,首先在您的 TFS 实例上创建一个名为 TFSCustomisations 的项目。
在此项目中创建一个名为 CustomAssemblies 的文件夹(我倾向于将其放在 BuildProcessTemplates 文件夹下,但这并不重要)。
下载 TFS Build Extensions(http://tfsbuildextensions.codeplex.com/),然后从 Code Activities\VS2013 文件夹中提取程序集。将它们放在您的 CustomAssemblies 文件夹中,并添加到源代码控制。检入它们。
现在来设置生成控制器。在 Visual Studio 中,在 Team Explorer 面板中,转到 Builds。点击 Actions 并选择 Manage Build Controllers。拉出生成控制器的属性窗口,并将“Version control path to custom assemblies”设置为您新的自定义程序集源代码控制文件夹。
既然已经完成了配置,我们就需要开始构建我们的自定义活动了。
设置解决方案
与往常一样,在构建自定义活动或修改生成过程模板时,需要进行一些 housekeeping 任务——尤其是如果您想使用 Visual Studio 中的 GUI 工作流设计器(相信我,如果您是第一次,您绝对需要!)。
创建一个空的解决方案。
基于 Workflow Activity Library 模板创建两个项目——一个命名为 BuildProcessTemplates,另一个命名随意(我称之为 TFSActions——本文将以此名称指代此项目)——如果使用 Visual Studio 2013,两个项目都需要以 .NET 4.5.1 为目标。
现在,在 TFSActions 中添加对所有 Community TFS Build Extension 程序集的引用(您不一定非要这样做,但这会使以后的工作更轻松)。您还需要添加各种 TFS 相关的程序集——这些可以在 C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies 下的三个文件夹之一中找到。您需要添加
Microsoft.TeamFoundation.Build.Client
Microsoft.TeamFoundation.Build.Common
Microsoft.TeamFoundation.Build.Workflow
Microsoft.TeamFoundation.Client
Microsoft.TeamFoundation.Common
Microsoft.TeamFoundation.VersionControl.Client
到您的 BuildProcessTemplates 项目中添加对 TFSActions 项目的引用。
另外,请添加
Microsoft.TeamFoundation.Build.Client
Microsoft.TeamFoundation.Build.Common
Microsoft.TeamFoundation.Build.Workflow
Microsoft.TeamFoundation.Client
Microsoft.TeamFoundation.Common
Microsoft.TeamFoundation.VersionControl.Client
Microsoft.TeamFoundation.VersionControl.Common
Microsoft.TeamFoundation.Deployment.Workflow
Microsoft.TeamFoundation.WorkItemTracking.Client
PresentationFramework(在 Assemblies 列表中)
WindowsBase(在 Assemblies 列表中)
System.Activities.Presentaiton(在 Assemblies 列表中)
您可能会发现需要添加更多,但这基本上足以让设计器正常工作。我们不需要担心此项目是否编译——唯一需要编译的是 TFSActions。
将您现有的生成模板(作为 Add Existing Item 从 BuildProcessTemplates 文件夹中添加)添加到您的解决方案中——希望您现在可以打开它而不会出现任何重大错误!
在您的 BuildProcessTemplates 文件夹中创建此模板的副本(例如,命名为 AzureContinuousDeployment.WithVersion.11.xaml),然后再次使用 Add Existing Item 添加它。
您应该最终得到
现在,让我们实际创建我们的活动!
构建活动
该活动将非常简单——它将接收一些参数,并在生成过程中递归更新解决方案中的 AssemblyInfo 文件。
为此,我们需要传入一些东西
WorkspaceName
BuildDetail
BuildAgent
SourcesDirectory
好消息是,所有这些项目都已在基础生成模板中定义——但是,请注意,有时它们并非如此(例如,如果您有一个自定义模板,或者正在使用新的精简版 2013 模板,您可能需要做一些巧妙的操作才能获得所需的值)。
向项目中添加一个新的 C# Workflow Activity 项。
确保您给它一个有意义的名称,例如 UpdateVersion。
打开此工作流,然后从工具箱中将一个 Sequence 拖到设计器上;如果您不先放置一个 Sequence,则只能指定一个要执行的操作。Sequence,顾名思义,意味着操作将按顺序依次发生。将 Sequence 的名称设置为“Apply Version Information”——正确设置活动名称始终是好习惯,因为它们将被导出到诊断日志中(这有助于您以后!)。
让我们向此工作流添加参数——点击工作流底部的“Arguments”选项,然后添加参数
WorkspaceName string
BuildDetail IBuildDetail(使用搜索!)
BuildAgent IBuildAgent(使用搜索!)
SourcesDirectory string
我们还需要一些本地变量;但是,设置变量时,请注意它们的作用域——点击您的 Sequence,然后点击“Variables”选项。
您会在我的截图里注意到,我在作用域内创建了一个 WorkspaceName 变量;这是因为在我活动的副本中,我为一些特殊的 Workspace 做了额外的处理:)
将 GetWorkspace 活动从工具箱拖到您的 Sequence 上。
将 FindMatchingFiles 活动从工具箱拖到您的 Sequence 上。
将 AssemblyInfo 活动从工具箱拖到您的 Sequence 上。
如果需要,可以通过添加 WriteBuildMessage 活动来添加一些日志记录——您应该得到类似这样的结果
现在来配置活动!
点击 GetWorkspace 活动,然后在 Properties 窗口中查看。
Set
Name => 设置为您定义的 WorkspaceName 参数,或者如果您和我一样,则设置为本地变量
Result => 设置为 workspace 变量
点击 FindMatchingFiles 活动并设置属性为
MatchPattern => string.Format("{0}\\**\\assemblyinfo.cs", SourcesDirectory)
Result => 设置为 assemblyInfoFiles 数组变量
点击 AssemblyInfo 活动并设置属性为
AssemblyFileVersion => "$(current).$(current).$(current)." + BuildDetail.SourceGetVersion.Replace("C", "")
AssemblyVersion => "$(current).$(current).$(current)." + BuildDetail.SourceGetVersion.Replace("C", "")
Files => 设置为 assemblyInfoFiles 数组变量
这里还有很多属性可以设置,但如果您感兴趣,我建议您查看该特定活动的 wiki 页面:http://tfsbuildextensions.codeplex.com/wikipage?title=How%20to%20integrate%20the%20AssemblyInfo%20build%20activity&referringTitle=Documentation
编译您的 TFSActions 项目——您不应该遇到任何错误。
使用活动
所以我们现在有了一个可以正确更新 AssemblyInfo 文件的活动,但这没有用,因为我们还没有更改生成过程模板。
打开您模板的副本(您创建的名称中带有 .WithVersion. 的那个);本文假定您正在查看 Azure Continuous Deployment 模板,但其他模板也相当接近。
向下滚动模板,找到标题为“Try Compile, Test, and Associate Changesets and Work Items”的块。我们希望我们的活动在此之前运行(即在工作区初始化并拉取代码之后)。
将 UpdateVersion 活动从工具箱拖到设计器上,放在“Try Compile ..” Sequence 的正上方。
设置您的活动属性
BuildAgent => BuildAgent
BuildDetail => BuildDetail
SourcesDirectory => SourcesDirectory
WorkspaceName => WorkspaceName
您会注意到,所有这些都被分配给了工作流中已定义的变量。
保存您的模板。
您需要做的最后一件事是将 TFSActions 项目的程序集副本放在您的 CustomAssemblies 文件夹中(例如,将 bin\Debug 或 bin\Release 中的 TFSActions.dll 复制到 CustomAssemblies)。请务必将其添加到源代码控制!这是生成服务器将拾取并使用的副本。
将所有内容检入 TFS。
现在,我们只需要将一个生成指向这个新定义!
配置生成
我将不详细介绍配置新生成的全部内容,因为我假设您知道如何在 TFS 中执行此操作,但我将展示如何指定这个新的(通用)工作流。
当您创建生成并转到 process 部分时,您可能会想“我的工作流在哪里?!”。
不要惊慌。点击下拉列表右侧的 New,然后选择您的 TFSCustomisations 项目,然后点击 browse 来查找您的工作流文件。
就这样!现在您的工作流将出现,您可以自动拥有版本化的生成了!
看,TFS Build 工作流不是很简单吗?
历史
- 2014年1月:新年快乐,我的第一篇文章,第一个版本!