如何链接 TFS 构建?

发布于 2024-07-29 11:35:48 字数 173 浏览 9 评论 0 原文

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

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

I have a scenario where I want to call one TFS build from another, the first one does the build and the second one does staging. This will allow me do multiple custom staging for the same solution.

I know, I can pull this off with an exec task in the second build and call tfsbuild.exe to queue a build from the first build definition. But was wondering if someone knew of a better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

如歌彻婉言 2024-08-05 11:35:48

这取决于你想做什么。

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

如果是这样,那么您基本上就走在正确的道路上了。 我不会 > 不过,运行一个全新的构建会产生大量开销,而且我不确定潜在的副作用是什么。 相反,我会使用 > 任务来执行暂存脚本中定义的 msbuild 任务。

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

如果是这样,那么:

  • 创建一个新的构建定义用于暂存,
  • 将一些代码添加到原始构建定义中,使用 Team Build API 对[一个/多个]新构建定义进行排队。 示例代码
  • 从原始构建定义中删除与核心构建无关的任何内容
  • 确保新的“暂存”定义没有任何自动触发器(时间间隔、签入事件等)

It depends what you are trying to do.

1) Do you want the build + staging to run as one operation? So that you end up with one consolidated build report, one log file, one job in the server's build queue, every step executed sequentially by the same Build Agent that executed the previous step?

If so, then you are on basically the right path. I wouldn't <Exec> out to tfsbuild.exe though -- running an entire new build has a lot of overhead, and I'm not sure what the potential side effects are. Instead, I would use the <Call> task to execute msbuild tasks defined in your staging script(s).

2) Do you want the "build build" to actually queue a separate "staging build"? Separate reports, log files, & spots in the queue? Opportunity to be executed in parallel if you have multiple Build Agents?

If so, then:

  • create a new build definition(s) for staging
  • add some code to your original build definition that queues [one/several] of the new build definitions using the Team Build API. Sample code.
  • remove anything not related to the core build from the original build definition
  • make sure the new "staging" definitions don't have any automatic triggers (time intervals, checkin events, etc)
何以笙箫默 2024-08-05 11:35:48

这是我完成此操作的方法(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 中要在其中创建暂存构建定义文件的新文件夹。

现在让我们创建一个最小的 TFSBuild.proj 文件,该文件使用新的 MSBuild 任务并覆盖 EndToEndIteration 目标。 这将是我们的暂存构建定义,它将触发 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“>

    <CallTarget Targets=“Custom_PreBuild“/>    

  </Target>

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

    <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—>
<Import Project="EmptyCustom.Target" Condition="'$(CustomTarget)'==''"/> 

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

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

Here is how I accomplished this (http://sajojacob.com/2009/08/how-to-chain-tfs-builds/)

How to Chain TFS Builds?
Posted on August 5, 2009 by Sajo — No Comments ↓

One of my colleagues @gdurzi recently asked me this question. Sounds straightforward enough to be supported out of the box with TFS right? Too many quirks with this. And I recommended using the ever faithful MSBuild task to make a call to TFSBuild.exe to queue a new build from the first TFSBuild.proj with something like this

TFSBuild.exe start /queue %TFSSVR% %TEAMPROJECT% %BUILDTYPE%

An issue with using TFSBuild.exe is that you cannot pass Build agents as a command line argument which was a deal breaker for us.

There are several approaches that you can take based on your particular scenario so let’s define the scenario here, you have a Main_Build TFS build definition that builds your core project and you want the ability to have multiple staging builds running the same Main_Build for compilation/building, but be custom staged for deployment based on who calls Main_Build. Very useful when you have a product which rolls out to multiple clients with a need for custom pre-build and post-build actions per client. So here is one way to do Build Chaining with TFS 2008.

Step 1: Let’s create a custom MSBuild task using the Team Foundation object model which queues a build using the default build agent associated with the Build definition file.

Sample code for Queuing: 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);

Step 2: Now copy the QueueTFS.dll to a new folder in TFS where you want to create the staging Build definition file.

Now let’s create a minimal TFSBuild.proj file which uses our new MSBuild task and overrides the EndToEndIteration target. This will be our Staging build definition which will trigger the Main_Build build. Note that you will have to create this TFSBuild.proj by hand and simply point the project file location from the Build definition UI to the new folder.

Sample code for a minimal 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>

Step 3: Edit your Main_Build TFSBuild.proj file with the pre-build and post-build target calls.

  <Target Name=“BeforeCompile“>

    <CallTarget Targets=“Custom_PreBuild“/>    

  </Target>

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

    <CallTarget Targets=“Custom_PostBuild“/>

  </Target>

We wanted the ability to run Main_Build by itself as well, to support this we add conditional imports in our Main_Build TFSBuild.proj to import a default targets file with empty Custom_PreBuild and Custom_PostBuild targets. $(CustomTarget) is what you would pass as a command line argument in Step 1 for request.CommandLineArguments

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

Step 4: Now create your targets file Custom.Target and EmptyCustom.Target with Custom_PreBuild and Custom_PostBuild targets and you are done.

I added support for updating build steps and a few other minor things which outside the scope of this blog post, but this should hopefully get you started.

月朦胧 2024-08-05 11:35:48

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

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

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/

Here are other helpful links. It might help others.

Create another Build Definition and call other build definitions to be triggered.

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/

Passing Arguments to Child Builds.

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

TFS Build Extension to Queue another Build Definition

http://tfsbuildextensions.codeplex.com/

一指流沙 2024-08-05 11:35:48

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

Are you trying to deploy your solution to your staging environment? If so a good method is to use TFSDeployer from codeplex which will run a diferent PowerShell script based on the build quality that you select...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文