16

我有一个场景,我想从另一个调用一个 TFS 构建,第一个执行构建,第二个执行暂存。这将允许我为同一个解决方案执行多个自定义登台。

我知道,我可以在第二个构建中使用 exec 任务完成此任务,并调用 tfsbuild.exe 将第一个构建定义中的构建排队。但是想知道是否有人知道更好的方法?

4

4 回答 4

7

这取决于你想要做什么。

1)您希望构建 + 登台作为一个操作运行吗?因此,您最终会得到一份整合的构建报告、一个日志文件、服务器构建队列中的一个作业,每个步骤都由执行上一步的同一构建代理按顺序执行?

如果是这样,那么你基本上是在正确的道路上。不过,我不会<Exec> 使用 tfsbuild.exe —— 运行一个全新的构建会产生很多开销,而且我不确定潜在的副作用是什么。相反,我会使用<Call> 任务来执行在您的暂存脚本中定义的 msbuild 任务。

2)您是否希望“构建构建”实际排队一个单独的“暂存构建”?单独的报告、日志文件和队列中的位置?如果您有多个构建代理,是否有机会并行执行?

如果是这样,那么:

  • 为暂存创建新的构建定义
  • 将一些代码添加到您的原始构建定义中,使用 Team Build API 将 [一个/几个] 新构建定义排队。 示例代码
  • 从原始构建定义中删除与核心构建无关的任何内容
  • 确保新的“暂存”定义没有任何自动触发器(时间间隔、签入事件等)
于 2009-07-24T20:19:36.903 回答
5

以下是我是如何做到这一点的(http://sajojacob.com/2009/08/how-to-chain-tfs-builds/

如何链接 TFS 构建?由 Sajo 发表于 2009 年 8 月 5 日 — 无评论 ↓

我的一位同事@gdurzi 最近问了我这个问题。听起来很简单,可以通过 TFS 开箱即用地支持,对吧?这方面的怪癖太多了。我建议使用永远忠实的 MSBuild 任务来调用 TFSBuild.exe 以将来自第一个 TFSBuild.proj 的新构建加入队列,如下所示

TFSBuild.exe 启动/队列 %TFSSVR% %TEAMPROJECT% %BUILDTYPE%

使用 TFSBuild.exe 的一个问题是您不能将构建代理作为命令行参数传递,这对我们来说是一个交易破坏者。

您可以根据您的特定场景采取多种方法,因此让我们在此处定义场景,您有一个 Main_Build TFS 构建定义来构建您的核心项目,并且您希望能够让多个暂存构建运行相同的 Main_Build 以进行编译/构建,但要根据谁调用 Main_Build 自定义分阶段进行部署。当您的产品推广到多个客户并且需要为每个客户定制预构建和构建后操作时,它非常有用。因此,这是使用 TFS 2008 进行构建链接的一种方法。

第 1 步:让我们使用 Team Foundation 对象模型创建一个自定义 MSBuild 任务,该模型使用与构建定义文件关联的默认构建代理对构建进行排队。

队列示例代码:QueueTFS.cs

using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Build.Client;

// Get the team foundation server. 
TeamFoundationServer _tfsServer = TeamFoundationServerFactory.GetServer(_tfs); 

// Get the IBuildServer 
IBuildServer buildServer = (IBuildServer)_tfsServer.GetService(typeof(IBuildServer)); 

// Get the build definition for which a build is to be queued. 
IBuildDefinition definition = buildServer.GetBuildDefinition(teamProject, buildDefinition); 

// Create a build request for the build definition. 
IBuildRequest request = definition.CreateBuildRequest(); 
request.CommandLineArguments = "Pass any custom command line args here"; // Ex: Custom Targets file

// Queue the build. 
buildServer.QueueBuild(request, QueueOptions.None);

第 2 步:现在将 QueueTFS.dll 复制到 TFS 中您要在其中创建暂存构建定义文件的新文件夹。

现在让我们创建一个最小的 TFSBuild.proj 文件,它使用我们的新 MSBuild 任务并覆盖 EndToEndIteration 目标。这将是我们的 Staging 构建定义,它将触发 Main_Build 构建。请注意,您必须手动创建此 TFSBuild.proj,并将项目文件位置从构建定义 UI 指向新文件夹。

最小 TFSBuild.proj 的示例代码:

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> 
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets" /> 
  <UsingTask TaskName="MyNewCustomTFSTask" AssemblyFile="QueueTFS.dll"/> 
  <Target Name="EndToEndIteration"> 
    <Message Text="About to trigger main build" Importance="high"/> 
    < MyNewCustomTFSTask TFS="http://TFSServer.com:8080/" TeamProject="TeamProject" BuildDefinition="Main_Build" TargetsFile="Custom.Target" XYZ="XYZ" /> 
    <!-- When everything is done, change the status of the task to "Succeeded" --> 
    <SetBuildProperties TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildUri="$(BuildUri)" TestStatus="Succeeded" CompilationStatus="Succeeded"/> 
  </Target> 
</Project>

第 3 步:使用构建前和构建后目标调用编辑 Main_Build TFSBuild.proj 文件。

  <Target Name=“BeforeCompile“&gt;

    <CallTarget Targets=“Custom_PreBuild“/>    

  </Target>

  <Target Name=“AfterDropBuild“ Condition=“‘$(BuildBreak)’!=’true’“&gt;    

    <CallTarget Targets=“Custom_PostBuild“/>

  </Target>

我们还希望能够自行运行 Main_Build,为了支持这一点,我们在 Main_Build TFSBuild.proj 中添加条件导入,以导入具有空 Custom_PreBuild 和 Custom_PostBuild 目标的默认目标文件。$(CustomTarget) 是您将在步骤 1 中作为命令行参数传递给 request.CommandLineArguments 的内容

<Import Project="$(CustomTarget)" Condition="'$(CustomTarget)'!=''"/>
<!--Import CustomContoso.Target if no partner is passed in—&gt;
<Import Project="EmptyCustom.Target" Condition="'$(CustomTarget)'==''"/> 

第 4 步:现在使用 Custom_PreBuild 和 Custom_PostBuild 目标创建目标文件 Custom.Target 和 EmptyCustom.Target,您就完成了。

我添加了对更新构建步骤和其他一些超出本博文范围的小事的支持,但这应该可以帮助您入门。

于 2009-08-05T18:26:59.377 回答
1

以下是其他有用的链接。它可能会帮助其他人。

创建另一个构建定义并调用其他构建定义来触发。

http://blogs.objectsharp.com/post/2012/02/04/Create-a-Master-Build-that-c​​alls-other-Builds.aspx

http://blog.stangroome.com/2011/09/06/queue-another-team-build-when-one-team-build-succeeds/

将参数传递给子构建。

http://blog.stangroome.com/2014/02/19/queue-a-team-build-from-another-and-pass-parameters/

TFS 构建扩展以排队另一个构建定义

http://tfsbuildextensions.codeplex.com/

于 2014-04-24T19:41:15.330 回答
0

您是否正在尝试将您的解决方案部署到您的暂存环境?如果是这样一个好方法是使用来自 codeplex 的 TFSDeployer,它将根据您选择的构建质量运行不同的 PowerShell 脚本......

于 2009-07-27T07:23:25.877 回答