如何在 TFS 2015 中链接构建?

How to chain builds in TFS 2015?

TFS 2015 中有没有一种方法可以有两个构建,以便在第一个构建完成(成功)时触发第二个构建? are solutions 用于旧的基于 XAML 的构建系统,但没有用于新的基于脚本的系统,这正是我正在使用的。

这个问题时常出现。官方文档literally say "not yet" (see the last Q&A entry). There's also an ancient suggestion on UserVoice,从今年3月开始就处于Planned状态。这很有前途,让我希望这将首先在 vNext 构建系统中实现。

此答案仅适用于

  • 您使用 Git 和 TFS2015
  • 您想在超级项目下链构建子模块
  • 所有有问题的构建都是持续集成构建。

如果是这种情况,那么你可以"chain-build"作弊(对我有用):

  1. 在每个子模块中添加一个批处理文件(提交给源代码管理),其中包含一个脚本,该脚本将此子模块的分支(正在构建)上的最新提交重新添加到其超级项目中。 这样做的预期(副作用)是在超级项目的状态中引入 "change",足以触发该超级项目的 CI 构建。
  2. 在每个子模块的构建定义中,添加一个 "Batch Script" vNext step。
  3. 将该步骤指向相应子模块的批处理文件。
  4. 此构建步骤需要是构建的最后一步,以确保它仅在构建成功时执行,然后执行 "mod" 并触发超级项目上的 CI 构建。

要开始使用,请参阅下面的示例脚本。此特定脚本仅适用于文件系统中 "nested" 彼此内部的子模块 - matreshka 样式。否则,每个子模块都需要一个自定义脚本。

请注意,它包含一些解决方法,解决了我在让它执行我需要它执行的操作时遇到的一些问题(即 clone/init 在将更改推送到本地之前,我机器上的子模块服务器,然后整理文件)。

如果需要更多评论,请告诉我。

REM Name of your submodule repository...
set subRepo=%1
REM Name of your superproject (with respect to this submodule) repository...
set superRepo=%2
REM Name of the folder into which the content of submodule will be cloned ...
REM Without this alias the folder will be called the same as the repo you are cloning.
set subAlias=%3
REM Branch to link to, given by $(Build.SourceBranchName) in the parameters you pass 
REM to the "Run Batch" build step (that will be executing this batch file)...
set branch=%4

REM Repositories' URLs - ONLY SAMPLE URLS - Please use your own !!!
set superUrl="http://<YourTfsServerName>:8080/tfs/DefaultCollection/_git/%superRepo%"
set subUrl="http://<YourTfsServerName>:8080/tfs/DefaultCollection/<YourSuperProjectName>/_git/%subRepo%"

REM Get the latest commit on current branch...
git log -1 --pretty=format:"%%h" > Output.txt
for /f %%i in (Output.txt) do set commit=%%i

IF NOT EXIST %superRepo% GOTO NOWINDIR

cd %superRepo%
REM Handle the .git directory specifically...
cd .git
for /F "delims=" %%i in ('dir /b') do (rmdir "%%i" /s/q || del "%%i" /s/q)
cd ..
rmdir .git
REM Remove the rest of files and folders...
for /F "delims=" %%i in ('dir /b') do (rmdir "%%i" /s/q || del "%%i" /s/q)
cd ..
rmdir %superRepo%

:NOWINDIR
REM Clone superproject and checkout the required branch *********************************************
git clone %superUrl%
cd %superRepo%
git checkout %branch%
git pull origin %branch%
git submodule update --init --recursive -f
cd %subAlias%
git checkout %commit% 
cd ..

git add %subAlias%

git commit %subAlias% -m "Updated %subRepo% reference to %commit% as %subAlias%"
git push origin %branch%

我通过创建自定义 BuildTask 实现了 "chaining" 构建,它基本上只是对 TFS REST Api 进行适当的调用。然后它允许我定义一个构建定义(按名称),我想触发并在顶部添加一些条件(例如检查是否有这个定义的构建已经排队或检查某个定义的最后一个构建是否成功).

有兴趣的我把源码上传到github

您可以使用 tfx 将任务上传到您的 TFS see details here
简而言之,只需从 github 获取文件,通过节点安装 tfx 并 运行

tfx build tasks upload --task-path ./triggerbuildtask

在此之后,您可以 select 触发新的构建任务并对其进行配置:

希望这可以帮助一些试图实现同样目标的人。

编辑
我将任务打包并发布在 Marketplace 上,因此在您的环境中可以轻松使用该任务:
Trigger Build Task