2009-07-24 55 views
14

我有一个场景,我想从另一个TFS构建中调用,第一个构建和第二个构建。这将允许我为同一解决方案执行多个自定义分段。如何链接TFS构建?

我知道,我可以在第二个构建中使用exec任务来解决这个问题,并调用tfsbuild.exe来从第一个构建定义中排队构建。但想知道是否有人知道更好的方法?

+1

我们切换到CC.NET - 这很容易支持这种方案的。 – Sneal 2009-07-24 15:41:01

+0

我也是用CC.NET做过这么多次的事情,我认为必须要有一个整洁的方式来做和TFS一样的事情! – user22242 2009-07-24 15:44:02

回答

5

这里是我做到了这一点(http://sajojacob.com/2009/08/how-to-chain-tfs-builds/

如何串连TFS构建? 发表于2009年8月5日由Sajo - 没有评论↓

我的一个同事@gdurzi最近问我这个问题。听起来很简单,TFS支持开箱即用吗?太多怪癖了。我建议使用永远忠实的MSBuild任务来打电话给TFSBuild.exe从第一个TFSBuild.proj排队一个新的版本,像这样的东西

TFSBuild.exe start/queue%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要创建分段构建定义文件的新文件夹。

现在让我们创建一个使用我们新的MSBuild任务并覆盖EndToEndIteration目标的最小TFSBuild.proj文件。这将是我们的Staging构建定义,它将触发Main_Build构建。请注意,您必须手动创建此TFSBuild.proj,并将项目文件位置从Build definition 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“> 

    <CallTarget Targets=“Custom_PreBuild“/>  

    </Target> 

    <Target Name=“AfterDropBuild“ Condition=“‘$(BuildBreak)’!=’true’“>  

    <CallTarget Targets=“Custom_PostBuild“/> 

    </Target> 

我们想跑,以支持这一点,我们在我们的Main_Build TFSBuild.proj添加条件进口引入缺省目标空Custom_PreBuild和Custom_PostBuild目标文件的功能本身Main_Build为好,。 $(CustomTarget)是你会通过什么样的命令行参数在步骤1中request.CommandLineArguments

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

第4步:现在创建你的目标文件Custom.Target和EmptyCustom.Target与Custom_PreBuild和Custom_PostBuild目标和你完成。

我增加了对更新构建步骤和本博客文章范围之外的其他一些小事情的支持,但是这应该有助于您开始。

7

这取决于你正在尝试做什么。

1)您是否希望build + staging作为一个操作运行?这样你最终得到一个整合构建报告,一个日志文件,服务器构建队列中的一个作业,每个步骤都由执行上一步骤的相同构建代理按顺序执行?

如果是这样,那么你基本上是正确的道路。我不会<Exec> out到tfsbuild.exe - 虽然 - 运行一个完整的新版本有很多开销,我不确定潜在的副作用是什么。相反,我会使用<Call>任务来执行在临时脚本中定义的msbuild任务。

2)你是否希望“构建构建”实际排队一个单独的“临时构建”?单独的报告,日志文件,队列中的&点?如果您有多个Build Agent,则可以并行执行机会?

如果是这样的话:

  • 创造分期
  • 一些代码添加到您的原生成定义一个新的构建定义(s)表示队列[一个/多个]的使用新的生成定义团队建设API。 Sample code
  • 去除不相关的核心东西从原来的构建定义构建
  • 确保新的“升级”的定义没有任何自动触发(时间间隔,签入事件等)
+0

最好是第1步,但任务不能像你所建议的那样使用。在这种情况下,暂存版本需要成为构建的驱动程序。它调用核心构建,然后进行自定义分段。 使用Minimal tfsbuild proj文件的问题在于,通过UI创建的TFSBuild定义文件会根据挑选的解决方案设置所有路径属性(因为我们同意,分段构建定义不应该重建解决方案)很难让路径配置为调用正确的核心TFSBuild.proj文件而不对它们进行硬编码。 – user22242 2009-07-27 03:50:34

0

是您是否试图将解决方案部署到临时环境?如果是一个很好的方法是使用TFSDeployer从CodePlex上,这将运行基于您选择构建质量diferent PowerShell脚本...

1

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

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

http://blogs.objectsharp.com/post/2012/02/04/Create-a-Master-Build-that-calls-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/