Team System

Team Build 2008 自定义

Brian A. Randell

内容

属性
获取信息内容的多少
更改
自定义任务

在 11 月 2008 专栏上Team Foundation Build 2008我讨论了哪些 Team Build 2008 是,为什么关心、 如何创建一个的版本以及使用新的 API 来程序 Team Build 服务的如何。在本专栏,我将介绍如何您可以修改默认行为的 Team Build、 扩展生成与自定义的任务和进行使用作为工作组的一部分添加增强功能构建 2008 SP 1。

在开始自定义生成之前,但是,很重要记住 Microsoft 构建在 Microsoft 生成引擎 (MSBuild),Microsoft.NET Framework 2.0 的一个核心组件之上的 Team Build。而我将提供与如何 MSBuild 执行生成一些次要的刷新点,您应该有一个正式的了解,以及执行。一个很好的评审可以阅读 2006 年 6 月 MSDN 文章 MSBuild,"The Microsoft 生成引擎编译应用程序您的方式使用自定义任务."

如前所述了之前,我鼓励您要浏览团队系统自定义,并在这种情况下团队生成,非生产环境中第一次。当然,一种很好的方法是使用 Microsoft 提供评估虚拟机之一。我更新之前圣诞 2008,图像,因此您会发现新的可用,以及其他更新程序安装了 SP 1。图像可用虚拟 PC 和超 V。您可以上找到链接和更多详细信息,Pluralsight 的博客.

许多移动部件参与执行生成。图 1 MSDN 文章"中Team Foundation Build 概述") 提供了所有代码段的图示视图。此外,我会介绍我以前的专栏中发生的情况中的一般步骤。我们此处最关心时 MSBuild 获取涉及。团队生成服务 (TFSBuildService.exe) 将创建一个传递名为 TFSBuild.tbrsp 一个文件的位置下的 MSBuild 过程。可以生成代理的工作目录下 BuildType 子文件夹中找到该文件。

fig01.gif

图 1 生成组件概述

Team Build 2008 SP 1 服务动态生成 TFSBuild.tbrsp。该文件包含存储在 Team Build 数据库、 团队的版本控制参数和内容 (如果有) 生成的 TFSBuild.rsp 文件中的数据。图 2 是测试生成我创建的示例。

图 2 Example 测试生成的

### Begin Team Build Generated Arguments ###

/nodeReuse:false
/m:1
/nologo
/noconsolelogger
/dl:BuildLogger,"C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\
  PrivateAssemblies\Microsoft.TeamFoundation.Build.Server.Logger.dll";
"BuildUri=vstfs:///Build/Build/45;
TFSUrl=http://tfsrtm08:8080/;
TFSProjectFile=C:\Builds\ExploreTeamBuild\Sysinfo\BuildType\TFSBuild.proj;ServerUICulture=1033;
LogFilePerProject=False;
"*BuildForwardingLogger,"C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\
  PrivateAssemblies\Microsoft.TeamFoundation.Build.Server.Logger.dll";
"BuildUri=vstfs:///Build/Build/45;TFSUrl=http://tfsrtm08:8080/;
TFSProjectFile=C:\Builds\ExploreTeamBuild\Sysinfo\BuildType\TFSBuild.proj;ServerUICulture=1033;"
/fl /flp:logfile=BuildLog.txt;encoding=Unicode;
/p:BuildDefinition="Sysinfo" 
/p:BuildDefinitionId="3" 
/p:DropLocation="\\localhost\Drops" 
/p:BuildProjectFolderPath="$/ExploreTeamBuild/TeamBuildTypes/Sysinfo" 
/p:BuildUri="vstfs:///Build/Build/45" 
/p:TeamFoundationServerUrl="http://tfsrtm08:8080/" 
/p:TeamProject="ExploreTeamBuild" 
/p:SourcesSubdirectory="Sources" 
/p:BinariesSubdirectory="Binaries" 
/p:TestResultsSubdirectory="TestResults" 
/p:SourceGetVersion="C244" 
/p:LastGoodBuildLabel="Sysinfo_20090104.2@$/ExploreTeamBuild" 
/p:LastBuildNumber="Sysinfo_20090104.2" 
/p:LastGoodBuildNumber="Sysinfo_20090104.2" 
/p:NoCICheckInComment="***NO_CI***" 
/p:IsDesktopBuild="false" 
/p:TeamBuildRefPath="C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies" 
/t:EndToEndIteration

TFSBuild.proj

### End Team Build Generated Arguments ###

### Begin Checked In TfsBuild.rsp Arguments ###

# This is a response file for MSBuild
# Add custom MSBuild command line options in this file

### End Checked In TfsBuild.rsp Arguments ###

如果您创建在 Team Build 2005,将大部分生成数据存储在一组在固定位置的版本控制下的文件。 这些文件的最有趣的是成,符合 MSBuild 项目文件架构的 XML 文件。 您创建使用 Team Foundation Server 2008,Team Build 2008 将存储的大部分您提供在 TFS 数据库的信息。 但是,您自定义生成过程而不考虑的版本相同: 编辑成文件,并编写自定义 MSBuild 任务 (如果需要)。

在团队生成 2008 SP 1 中, 可以通过右键单击团队资源管理器窗口中一个内部定义的名称,然后选择视图生成配置访问成文件。 在为 SP 1 之前的版本,您打开源代码管理资源管理器,,在将手动将其定位运行生成定义向导时您指定的位置到。

生成定义存储在数据库中定义应生成哪些和时间。 该成文件定义如何 Team Build 应执行生成。 您将从我以前列想起您创建新的内部定义中,或可以指向现有的文件已经实施了版本控制可以创建一个新的成文件。 为其神奇功能与不同团队生成程序集,结合的 MSBuild 需要知道要生成什么顺序以及有关任何其他任务。 如果您查看 图 2 ,您会注意 Team Build 将成传递作为 MSBuild 应处理的项目文件的名称。 MSBuild 视为全局属性的所有 / p 参数。

如果您检查生成单个解决方案生成一个团队生成 2008 成文件 (同时调试和发布配置类型) 和 does 不运行任何的测试您可以找到的节的编号。 此 XML 文件与 Visual Basic 或 C# 项目文件非常相似。 XML 文件定义生成属性,将作为生成过程和要执行的操作的一部分的项目。 文件组属性的结合到 <propertygroup> 元素。 它跟踪如 <itemgroup> 元素中的解决方案的项目。 此外,它描述了它应通过 <target> 元素一起执行的操作。

目标有一个 name 属性,并且这些组一起按特定顺序的任务。 在 CLR 依赖于中定义的任务创建实现 ITask,或者从抽象基继承的公共类的程序集类任务 (或任何其他派生的类型,(如 ToolTask)。 ITask、 任务,和 ToolTask Live Microsoft.build.utilities.dll 集中。 在成文件中与 XML 声明之后可以找到根 <project> MSBuild 所需的元素:

<Project DefaultTargets="DesktopBuild" 
xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

DefaultTargets 属性指定 MSBuild 应使用 DesktopBuild 目标。 但是,此会只发生如果执行直接使用 MSBuild 生成。 如果返回 图 2 您看到的 Team Build 告诉 MSBuild 考虑 EndToEndIteration 目标作为其主入口点。 因此,MSBuild 将忽略 DefaultTargets 属性由 Team Build 启动时。

在 <project> 元素之后您会发现 <import> 元素。 <import> 元素告知 MSBuild 以使用另一个项目文件,除了正在处理的一个。 Team Build 点 <import> 元素特定于版本的 Team Build 目标文件:

<!-- Do not edit this -->
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets" />

此目标文件是核心和 soul 的 Team Build 如何执行其神奇功能。 仔细检查该文件将提供您深入了解团队会生成过程也,如何 MSBuild 工作。 一个单词的警告: 您不应该编辑此的目标文件。 这样做因此会影响所有在特定生成生成代理 (但仅该代理)。 此外,如果 Microsoft 提供了一个 Service Pack、 修补程序或更新 Team Build,所做的更改将会丢失。 最后,并不在 Microsoft 支持操作。 应使用内置的机制而调整 Team Build 的行为,您要了解在本专栏的内容。

作为其预处理,MSBuild 创建目标执行的树。 项目文件定义目标的顺序是不相关的。 MSBuild 执行基于入口点目标的目标,并假定没有错误任何 DependsOn 属性会出现。 此外,MSBuild 将只执行一个名为的目标版本。 它使用目标定义的最后一个版本时。 Team Build 利用此团队生成目标文件中定义为空的目标数。 这些目标的大多数名称中具有之前或之后的前缀。 MSBuild 进程在团队中定义的目标因 <import> 元素首先生成目标文件。

您,反过来,可以重写这些目标之一通过创建具有相同名称成文件中的目标。 但是,几个附加项还影响目标顺序。 首先,根 <project> 元素支持可以包含以分号分隔的列表执行在 DefaultTargets 或命令行上指定的一个或多个目标的一个 InitialTargets 元素。 第二个,目标可以指定这在通过 DependsOnTargets 属性取决一个或多个目标。 MSBuild 执行顺序在其中声明的 DependsOnTargets 属性中列出的目标。 许多团队生成目标实现。 第三个,目标可以指定其执行一个条件。 是例如许多团队生成目标执行只有生成不桌面生成。 因此,运行 Team Build 时,初始的目标集,执行的是第一个 CanonicalizePaths,然后使用 CheckSettingsForEndToEndIteration。

因为该目标文件定义了它为 InitialTargets 项,MSBuild 首先执行 CanonicalizePaths。 CheckSettingsForEndToEnd­iteration 将是下一步,因为很 depends­OnTargets 为 EndToEndIteration,由 Team Build MSBuild 的命令行中指定的目标指定的列表中第一个目标。 请注意 MSBuild 仅执行从 EndToEndIteration 链中的目标。

到目前为止您知道足以开始。 此列的一个部分中,我创建团队项目 MSDNMag,与自定义工作区。 我将继续下面的示例中用于此团队项目。 我已选择在所有 $ MSDNMag / 主 / src / TeamSystem / C10 下我示例解决方案 /。 名为 MSDNMag 我自定义工作区将我的团队项目 $ MSDNMag 树干映射到 C:\Work\MSDNMag 以便轻松使用解决方案,以及生成文件中。 最后,如我之前提到的我所涉及所有这些 Microsoft 提供的虚拟机的团队的系统 2008 SP 1 版本中。

首次启动使用团队生成自定义时, 需要注意两件事。 一个,您将能编辑 XML 文件创建自定义。 第二个,调试今天往往是有关 printf 和分析日志文件的所有信息。 请 When 您考虑自定义自己的版本来调整其行为,有三种常规方法,以继续。 首先,更改已知属性的值。 第二个,调用预定义的任务。 第三个,编写您自己的自定义任务。

MSBuild 和团队生成公开了许多用于定义影响目标执行的条件的属性。 是例如 Team Build 提供了一个 IsDesktopBuild 属性,它用来确定是否应执行特定的目标。 MSBuild 公开与平台、 编译器选项、 处理器结构和多个相关的属性。 此外,Team Build 有了许多可以更改要打开或关闭功能的属性。 实际上,代码分析是一个可以调整的项目。

如果您检查您的成文件,您会发现一些 XML 类似下面的代码。 通过更改 <runcodeanalysis> 属性的值,您更改如何 MSBuild evalutes 代码分析设置您的项目:

<!--  CODE ANALYSIS
Set this property to enable/disable running code analysis. Valid values for this property are Default, Always and Never.

     Default—Perform code analysis as per the individual project settings
     Always —Always perform code analysis irrespective of project settings
     Never —Never perform code analysis irrespective of project settings
 -->
<RunCodeAnalysis>Never</RunCodeAnalysis>

Team Build 还使用属性来控制的测试运行。 这包括多个 XML 片段。 首先,将 <Run­Test> 属性设置为 True。 然后您可以使用测试列表或具有要运行的测试的 Team Build 扫描。 如果想要使用测试列表,您需要定义 <metadatafile> 属性与一个或多个 <testlist> 项目可以在此处看到:

<!--Set this flag to enable/disable running tests as a post-compilation build step.-->
<RunTest>true</RunTest>
<MetaDataFile Include=
  "$(BuildProjectFolderPath)/../../Main/src/SysInfo/SysInfo.vsmdi">
  <TestList>All Unit Tests</TestList>
</MetaDataFile>

下面是一个操作中的属性的更多示例。 标准生成执行,期间 Team Build 从版本控制中检索的所有项目的标签。 如果您不希望重新,您只需要将 SkipLabel 属性设置为 True。 可以执行此操作通过多种方式。 首先,如果您只希望为您生成的特定运行,您可以传递 /p:SkipLabel = true MSBuild 命令行参数中的 (请参见 图 3 )。 注意,是否只传递 SkipLabel 将得到生成错误 Team Build 尝试生成的变更集的列表和更新工作项时。 要避免此错误,您需要添加 SkipGetChangesetsAndUpdateWork­items = true。 您可以生成报告摘要一节中找到显示在命令行参数。

fig03.gif

图 3 传递到 MSBuild 命令行参数

在命令行之外,您可以使用相同的语法但而不是使用对话框编辑 TFSBuild.rsp 文件可以找到的并行与成文件在版本控制中。 最后,您可以将属性添加到您的成文件中。 您需要签出版本控制您成文件。 如果双击该文件,它将打开 Visual Studio XML 编辑器中。

您可以添加使用 XML 打开和关闭与现有属性组元素的文本为 True 的元素标记每个属性,也可以创建自己的属性组,甚至将到目前为止为添加条件参数,以便可以将它打开和关闭通过命令行如下所示。 现在可以传递 /p:QuickBuild = True 以执行快速生成:

<PropertyGroup Condition="$(QuickBuild)=='True'">
    <SkipLabel>true</SkipLabel>
    <SkipGetChangesetsAndUpdateWorkItems>true</SkipGetChangesetsAndUpdateWorkItems>
</PropertyGroup>

获取信息内容的多少

如您开始 futz 与您的版本,并指出正在运行的内容确实您通常需要输出其他状态信息。 在执行之前,请记住默认情况下 Team Build 生成详细的日志。 您可以通过使用 fileLoggerParameters (flp) 来调整此日志的详细参数 (Team Build 2005 使用 / v 参数)。 Microsoft.NET Framework 3.5 中, 默认日志记录从普通的详细级别更改为诊断。 因此,如果希望较小的日志文件,您将要添加 /flp:verbosity TFSBuild.rsp 文件 = normal。

如果没有找到要查找内容的详细日志中,可以启动该日志文件写入您自己的邮件。 为了记录消息,您将需要定义一个目标。 在的目标中可以使用内置的消息任务。 </project>是例如"我的自定义邮件"以及 SkipLabel 属性的值,编写出字符串,可将以下 XML 添加到成文件之前关闭元素:

<Target Name="MyMessageLogger">
        <Message Text="My Custom Message" />
        <Message Text="SkipLabel Status= $(SkipLabel)" />
</Target>

但是,如果您执行此操作,并运行您的版本,反应。 回想一下 Team Build 调用 EndToEndIteration 作为其入口点。 MSBuild 只执行目标的执行链中的目标。 如果要获取您要执行的任务,您需要挂接到此链的您的目标。 一种简单的方法是将目标添加到团队生成目标文件。 但是,您不这样做是因为,请记住,已被警告您"不,!" 实际上有两个非常合理的替代方案,Microsoft 支持甚至鼓励。 是修改目标的 DependsOn 属性依赖关系链中插入自定义的目标。

如前所述,Team Build 的目标文件定义了空的目标数。 Microsoft 创建那些目标明确使您可以替代它们。 可以在 MSDN 文章中找到列表" 自定义 Team Foundation Build 目标."

团队生成过程具有可以轻松地获取要执行自定义操作的 Team Build 超过 20 个的点。 第一个目标可以重写是 BeforeEndToEndIteration。 这实际上是 MSBuild 执行的第四个目标。 若要将以前的 XML 片断,运行您需要从 MyMessageLogger 的 name 属性更改为 BeforeEndToEndIteration。 如果希望您团队生成报告中显示的消息,请将一个进一步,可以使用团队提供内置 BuildStep 任务而不是对消息任务中示:

<Target Name="BeforeEndToEndIteration">
    <BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
           BuildUri="$(BuildUri)"
           Name="MyBuildStep"
           Message="BeforeEndToEndIteration override is executing."
           Status="Succeeded"
           >
    </BuildStep>
</Target>

不是所有对 Team Build 由 Microsoft 在 2005 更新到 2008 时更改已看到与 praise 的歌曲。 我,一个,frowned 在此更改: 默认,Team Build 2008 标记生成成功,如果它不会在生成过程中遇到错误。 这将忽略部分成功生成的概念。 Team Build 生成的状态,以这种状态,如果编译成功但某些其他,如一个单元测试失败的集。 相反,Team Build 2005 失败生成如果测试失败。

不用说此更改未什么每个人都希望。 若要避开团队生成 2008 不带 SP 1 中的此问题,可以使用由 Aaron Hallberg 发布 Microsoft 技术一个或多个测试失败时无法生成。 图 4 列出了您需要添加到成文件的 XML。 此目标首先获取 TestSuccess 属性。 它然后更改属性失败如果 TestSuccess 等于 False 的 CompilationStatus。 令人欣慰的是,Microsoft 侦听的反馈。 解决此问题的团队生成 2008 SP 1 中添加了一个属性。 只需将 <treattestfailureasbuildfailure> 设置为 True,并且您是好转。

图 4 必须被添加到成文件的 XML

<Target Name="AfterTest">

  <!-- Refresh the build properties. -->
  <GetBuildProperties TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
                      BuildUri="$(BuildUri)"
                      Condition=" '$(IsDesktopBuild)' != 'true' ">
    <Output TaskParameter="TestSuccess" PropertyName="TestSuccess" />
  </GetBuildProperties>

  <!-- Set CompilationStatus to Failed if TestSuccess is false. -->
  <SetBuildProperties TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
                      BuildUri="$(BuildUri)"
                      CompilationStatus="Failed"
                      Condition=" '$(IsDesktopBuild)' != 'true' and '$(TestSuccess)' != 'true' ">

</Target>

自定义任务

到目前为止,您已经更改的方式 MSBuild 和团队生成操作通过更改成中的 XML。 但是,如果您想要在生成完成后,将一个 Web 项目部署到 IIS? 如果要打包到 MSI 文件在二进制文件? 一种解决方案是创建自定义的任务,但还有一个丰富的 MSBuild 和 Team Build 任务库已提供您的使用 Internet,并其中的大多数提供完整的源代码代码。

应首先采用的两个主要库位于 CodePlex。 还有, SDC 任务超过 300 个任务。 此外,还有在 MSBuild 扩展包超过 250 个任务。 每个库都有各种任务,并同时提供源。 使用这些库时,要求在代理计算机,然后添加到成文件的相应的 XML 片段生成安装程序集。

Microsoft 创建团队生成 2008 是极其灵活。 获取从最开头了解工作原理的而用 MSBuild 交互。 使用该知识库和一些 XML 编辑,您可以轻松地更改其行为。 社区的借助可以更进一步,并将全新的功能添加到 Team Build。 最后,如果找不到任务以执行您只希望,可以创建自己的自定义任务。

将您的问题和意见发送 Brian 到 mmvsts@Microsoft.com.

Brian A.Randell 是 MCW Technologies LLC 的一名高级顾问。 他将花费其时间、 讲授,和有关 Microsoft 技术写作。 Brian Pluralsight 的应用 Team 系统课程的作者且为 Microsoft MVP。 与 Brian 在他的博客 mcwtech.com/cs/blogs/brianr.