常见依赖概念
此页面基于示例给出了 TeamCity 中依赖关系如何工作的一般概念。 有关依赖项的描述,请参见 构建配置依赖项。
在许多情况下,将一个构建的输出用在另一个构建中,以及在同一源代码上顺序或并行运行多个构建都非常便利。 考虑一个典型的例子:您有一个需要在 Windows 和 macOS 下测试的跨平台项目,然后才能得到生产构建。 对于这种简单的情况,最佳的工作流程将是:
编译您的项目。
在同一源码上同时在 Windows 和 macOS 下运行测试。
在相同的源码上构建一个发布版本,当然,如果在两个操作系统下的测试都已通过。
您可以通过在 TeamCity 中配置您的构建配置之间的依赖关系来轻松实现这一点,就像这样:

其中, 编译、 测试(win)、 测试(mac)和 打包设置是构建配置,自然地,测试 依赖于 编译,这意味着它们应等待编译完成。
常见概念
在 TeamCity 中,一系列相互关联的构建配置称为 构建链。 在详细了解其工作原理之前,让我们先澄清这里提供的图表(包括介绍中的图表)背后的图例:
| 一种构建配置。 |
| 快照依赖性在2个构建配置之间。 请注意,箭头显示的是触发构建配置的顺序,即 build chain 的流程,这意味着 B 在 A 之前执行。 然而,依赖项的配置是相反的方向(A 快照依赖于 B)。 箭头是这样绘制的,因为在 TeamCity UI 中,您可以找到构建链的视觉表示,它们总是根据构建链流程显示的。 |
| 构件依赖性。 箭头显示了构件的流动,依赖项则在反方向配置。 |
正如您注意到的,在 TeamCity 中有两种类型的依赖: 工件 依赖和 快照 依赖。 用两个词来说,第一个允许在另一个中使用一个构建的输出,而第二个可以在特定的顺序中从几个构建配置触发构建,但是源是相同的。
这两种依赖性通常会一起配置,因为制品依赖并不影响触发构建的方式,而快照依赖本身并不重用制品,有时您可能只需要其中的一个。
依赖项在 Build Configuration Settings的专用页面上配置。
现在,让我们看看您可以如何运用 artifact 和 snapshot 依赖,以及它们的具体工作原理。
构件依赖性
一个 工件依赖项 允许在另一个构建中重用一个构建(或其一部分)的输出。
![]()
如果构建配置 A 对 B 有工件依赖,那么 B 的工件会在 A 的构建开始之前下载到构建代理。 请注意,您可以灵活调整 artifact rules ,以配置应取哪些构件及应将它们放置在何处。
如果由于某种原因,您需要将构件依赖信息与您的代码库一起存储,而不是在 TeamCity 中,您可以配置 Ivy Ant tasks 以在您的构建脚本中获取构件。
如果同时配置了快照和构件依赖性,且在构件依赖性设置中选择了 '来自相同链的构建 ' 选项,TeamCity 将确保从同一源构建下载构件。
快照依赖
快照依赖是两个构建配置之间的一种依赖关系,允许从两个构建配置中启动构建 以特定顺序 ,并确保它们使用 相同的源快照 (对应于同一时刻的源修订)。
当您有多个通过快照依赖互相关联的构建时,它们会形成一个 构建链。
何时创建构建链
最常见的创建 build chain 的应用场景是在不同的平台上运行您的项目的相同测试套件。 例如,您可能需要进行发布构建,并希望确保在不同的平台和环境中正确运行测试。 为了实现这个目标,您可以指示 TeamCity 首先运行一个集成构建,如果集成构建成功,再进行发布构建。
另一个情况是,当您的测试运行时间过长,因此您需要将它们提取到一个单独的构建配置中,但是您还需要确保它们使用相同的源快照。
在 TeamCity UI 中构建链
一旦定义了快照依赖并触发了至少一个 构建链, 构建链 选项卡会出现在 项目主页 页面以及相关构建配置的 主页 页面上,提供所有构建链的可视化表示,并可以手动重新运行任何链步骤,使用最初拉取的同一组源。

快照依赖性如何工作
为了理解快照依赖性是如何工作的,您可以将其想象为模块依赖性,因为这些概念是相似的。 然而,让我们从基础开始。 我们假设,我们有一个 build chain:
![]()
如果触发了 A1 的构建,则整个构建链 A1...AN 会被添加到 构建队列中,但 而不是反过来!——如果触发了 AN 的构建,它不会影响构建链中的其他内容,仅运行 AN。
构建运行 从 AN 到 A1 依次开始。 构建 A(k-1) 不会开始,除非构建 Ak 成功完成。
链中的所有构建将使用相同的源快照,也就是说,会明确指定源代码的修订版本,该修订版本是在构建链被添加到队列时计算的。
现在让我们详细介绍并提供一些例子。
示例 1
假设我们有以下的 构建链 ,没有额外的选项 - 纯快照依赖。
![]()
当构建A被触发时会发生什么
TeamCity 解析整个构建链并对所有构建进行排队 - A ,B 和 C 。 TeamCity 知道构建需要以严格的顺序运行,因此在构建 B 完成之前不会运行构建 A,在构建 C 完成之前不会运行构建 B。
当构建被添加到队列中时,TeamCity 开始检查整个构建链中的更改并同步它们——所有构建都必须从相同的源快照开始。
请注意,如果通过快照依赖项连接的构建配置 共享相同的 VCS 根集合 ,则所有构建都将在相同的源上运行。 否则,如果 VCS 根是不同的,VCS 中的更改将对应于相同的时间点。
一旦构建 C 完成,构建 B 就开始,依此类推。 如果构建 C 失败,TeamCity 默认不会继续执行链中的其他构建,但这种行为是 可以配置的。
当触发构建B时会发生什么
相同的过程将适用于构建链 B → C。 构建 A 不会受影响,也不会运行。
示例 2

当最终构建 A 被触发时,TeamCity 解析构建链并总共排队三个构建:A、B1 和 B2。 构建 A 在 B1 和 B2 都准备好之前不会启动。
在这种情况下,无论 B1 或 B2 哪个先启动都无关紧要;如果至少有两个空闲的兼容代理,这些构建可以并行运行。 就像第一个例子中一样,当所有构建都被添加到队列中时,TeamCity会检查整个构建链中的更改,并将它们进行同步。
高级快照依赖设置
重复使用构建
所有属于 构建链的构建都被放置在 队列中。 但是,TeamCity 可以检查是否已经有适当的构建,即使用了所需源快照的已完成构建,而不是强制从构建链运行所有构建。 匹配的排队构建将不会运行并且会从队列中 删除 ,而 TeamCity 将会把依赖性链接到 适当的构建。 要启用此功能,请在配置快照依赖项选项时选择 '如果有合适的构建,不执行新的构建'。
另一个可以让您控制如何重用构建的选项被称为 "只从合适的构建中使用成功的构建 ",当有合适的构建,但并未成功时,它可能会有所帮助。 通常,当链中出现构建失败时,TeamCity 不会继续执行链中的其余部分。 然而,启用此选项后,TeamCity会在这些源上再运行一次这个失败的构建。 这有何用处? 例如,当构建失败是由于连接到 VCS 时出现问题时。
关闭了强制修订同步
如果您在创建快照依赖性时禁用“ 执行版本同步 ”选项,那么在将构建从一个部分提升到另一部分时,TeamCity 将能够为链的各个部分使用不同的修订版本(在 构建链中阅读更多信息)。
让我们来探讨一下 deployment chain 的例子:
![]()
与以下构建配置一起:
D: 编译
C: 集成测试
B: 系统测试
A:部署
在这里,构建 B 的快照依赖项中 "强制执行修订同步" 选项被禁用,而 C 和 A 的快照依赖项中此选项得到启用(默认状态)。 根据这些设置,TeamCity 将在 D 和 C 之间,以及 B 和 A 之间同步修订版,但是可以对链条部分 D-C 和 B-A 使用不同的修订版。
在我们的例子中,D 和 C 的修订版本为 1,B 的修订版本为 2,而 A 的修订版本为 3。
如果您想要运行旧版编译构建 D,并使用最新的部署配置 A,同时跳过集成测试 C,您可以直接将构建 D 提升至 B。 TeamCity 将使用修订版 1 运行 D;然后,它将以 A 的较新修订版同步 B,并使用修订版 3 运行 B 和 A。
通过启用和禁用不同构建配置链的依赖项的此选项,您可以对您的设置进行更多控制并使其更灵活。
为了防止修订版本之间的冲突,避免配置这样的链,其中依赖构建(A)必须与其几个直接依赖构建(B)和(C)同步修订版本,而这些构建在他们对其他某些构建(D)的快照依赖项中的 "Enforce Revisions Synchronization" 选项有不同的状态。
请改为使用以下有效的链:
同步已经被启用于 D-B-A 构建流程,但在 D-C-A 中被禁用。

已为 D-B 和 D-C 启用同步,但 B-A 和 C-A 的同步被禁用。

在同一代理上运行构建
这个选项设计用于此类情况:构建链中的一个构建修改了系统环境,并且下一个构建依赖于该系统状态,因此必须在同一构建代理上运行。
如果依赖项失败,构建行为
如果其依赖项失败,您可以 配置最终构建行为的可能性。
在快照依赖性发生变化时触发
VCS 构建触发器还有另一个 选项 ,可以改变构建链的触发行为。 启用此选项后,即使在依赖项中检测到更改,而不是在最终构建中,整个构建链也将被触发。
让我们从示例中取出一个构建链: pack 设置—— 依赖于 ——测试—— 依赖于 ——编译。

在 pack 设置 配置中设置了 VCS 触发器后,当 TeamCity 检测到在 pack 设置 中的变更时,整个构建链通常会被触发;在 编译 中的变更只会触发 编译 ,而不会触发整个链条。 如果您希望在 编译 中的 VCS 更改触发整个链,将带有 "在快照依赖中的更改上触发" 选项 的 VCS 触发器添加到链的最终构建配置 pack 设置。 这不会改变构建执行的顺序,但只有在任何快照依赖项发生变化时,才会触发整个构建链。 在此设置中, 编译 或 测试 构建配置不需要 VCS 触发器。
依赖项的更改
对于具有快照依赖项的构建配置,您可以在 版本控制 的 构建配置设置部分中切换 显示快照依赖项更改选项。

启用此设置后,上游构建配置的更改将显示在 更新日志 和 待处理的更改 选项卡中,以及在构建历史和问题日志中。 此设置还允许构建配置触发器在提交到上游配置的更改时自动启动新构建。
显示 shapshot 依赖项的更改 选项指定默认行为。 无论此设置如何,用户都可以在查看构建更改列表时切换相应的复选框,以包含或排除源自其他配置/存储库的更改。

依赖构建中的参数
TeamCity 提供了使用当前构建所依赖的构建(通过快照或者工件依赖)所提供的属性的能力。 当构建 A 依赖于构建 B 时,您可以将构建 B 的属性传递给构建 A ,即属性只能按照构建链流向传递,而不能反向传递。
有关如何使用链中前一个构建的参数的详细信息,请参考 依赖性属性 部分。
并行运行构建
一个构建链可以有无限数量的并行和顺序连接。 如果满足以下条件,构建将会并行运行:
这些构建中的每一个都对同一依赖构建具有自己的快照依赖性。 这些构建将能够在依赖构建完成后立即开始。
服务器上有足够的免费构建代理。 如果代理繁忙,TeamCity 将会按照代理负载的顺序,依次执行这些构建。
保护配置
TeamCity 支持通过快照和工件依赖项链接配置,从而实现复杂的多项目构建链。 然而,这也意味着外部项目的开发人员可以使用依赖项触发构建并从其他团队拥有的配置中导入工件。
如果您的项目包含敏感或资源密集型配置,您可以通过以下方式保护它们:
设置严格的 用户权限。 任何具有 项目查看器 角色的用户都可以在其自己的配置中创建到此项目的依赖项。 这允许外部用户利用您的配置,即使他们没有直接运行它们的权限。
使用 构建审批 功能。 通过这种方式,其他团队仍然可以向您的配置添加依赖项,但新构建将在获得您指定团队成员的批准之前保持排队状态。
在 项目隔离 选项卡的 项目设置中设置细粒度的访问权限。 您可以允许来自任何项目的工件和快照依赖项,或将其限制为允许列表。 如果项目不在列表中,其配置构建将无法启动。 有关此选项的更多信息,请参见下面的 项目隔离 部分。
项目隔离
项目隔离选项可在 项目设置的相应选项卡中找到。

仅受信任的项目 模式将目标项目及其子项目隔离,防止其他(外部)项目拥有的构建配置通过快照和工件依赖项访问此隔离分支。
- 默认信任关系
将项目切换到 仅受信任的项目 模式会生成一个隔离的项目分支,其中所有子项目相互信任。
例如,考虑以下项目层次结构:
Root Project │ ├── Project A │ │ │ ├── Project A1 │ └── Project A2 │ └── Project B ("Only trusted projects" enabled) │ ├── Project C └── Project D │ ├── Project D1 └── Project D2项目 B 处于“仅受信任项目”模式,这会隔离“B → C,D → D1,D2”分支。 如果所有其他项目都处于限制较少的“所有项目”模式,则此设置意味着以下内容:
“B → C,D → D1,D2”链中的所有配置可以相互依赖。 这包括自上而下和自下而上的依赖关系。
// Horizontal dependency object C_BuildConfig : BuildType({ name = "Configuration from Project C" dependencies { // Configurations from sibling projects C and D snapshot(D_BuildConfig) {} } }) // Top-down dependency object C_BuildConfig : BuildType({ name = "Configuration from Project C" dependencies { // Projects trust their direct and indirect parents snapshot(D1BuildConfig) {} } }) // Bottom-up dependency object D1BuildConfig : BuildType({ name = "Configuration from Project D1" dependencies { // Projects trust their direct and indirect children snapshot(B_BuildConfig) {} } })您可以通过将子项目切换到“仅受信任项目”模式来限制自上而下的依赖关系。 例如,如果项目 D 处于此模式,则“D → D1,D2”链将进一步隔离,防止“B → D”依赖关系。
从项目 A、A1 和 A2 到任何隔离项目的依赖关系将失败。 您可以通过将外部项目添加到允许列表来解决此问题。
object A2BuildConfig : BuildType({ name = "Configuration from Project A2" dependencies { // A2 cannot trigger isolated D1, the build will fail snapshot(D1BuildConfig) {} } })反之则不成立:由于 A 未被隔离,项目 B、C、D、D1 和 D2 的配置可以依赖于 A、A1 和 A2。
object D1BuildConfig : BuildType({ name = "Configuration from Project D1" dependencies { // D1 can trigger non-isolated A2 snapshot(A2BuildConfig) {} } })
- 受信任项目列表
要允许隔离分支外的项目对这些隔离项目具有依赖关系,请点击 添加新的受信任项目 并将所需项目添加到列表中。 项目会将其允许列表传播到所有直接和间接的子项目。 在上述示例中,如果项目 D 信任项目 A,则后者可以对项目 D、D1 和 D2 拥有的配置具有快照和工件依赖关系。
项目隔离 页面将受信任的依赖项分为两张表:一张是明确声明在此项目级别的,另一张是从父项目继承的。

由于子项目从其父项目继承受信任项目列表,我们建议将受信任项目添加到隔离分支的最顶层项目(上述示例中的项目 B)。 这样做可以让您保持一个清晰且易于维护的设置。
当您将项目切换到 仅受信任的项目 模式时,TeamCity 会警告您,依赖于此项目(及其子项目)的构建将失败,除非您将其项目添加到允许列表。 勾选 将当前依赖的项目添加到受信任项目中 复选框,让 TeamCity 扫描当前项目层次结构并预填此列表。
- 设置继承
如果项目没有父项目强制隔离, 项目隔离 页面提供两种模式: 所有项目 和 仅受信任的项目。
否则,如果任何直接或间接父项目使用第二种模式, 所有项目 选项将被 从父项目继承设置 替代。

在这种继承模式下,项目信任:
其直接和间接的子项目;
其直接和间接的父项目(直到其继承隔离的父项目);
父项目允许列表中的项目。 每个子项目还可以额外定义自己的受信任项目列表(有关更多信息,请参见 受信任项目列表)。
- 项目隔离和版本化设置
信任模式设置和受信任项目列表不会存储在 版本化设置中。 同时,使用禁用 允许通过 UI 编辑项目设置 选项的版本化设置不会阻止 TeamCity UI 中的 项目隔离 设置。
这确保了信任策略只能通过 TeamCity UI 由项目管理员修改,而不能通过对远程配置文件的更改(这些文件可能对普通项目开发人员可访问)来修改。
关于使用依赖项的杂项注解
构建链和清理
默认情况下,TeamCity 会保留清理过程中链的一部分的构建,但您可以关闭此选项。 参阅 清理 描述以获取更多详情。
Artifact 依赖及清理
如果其他构建下载了工件,并且这些构建尚未清理,那么可能无法 清理这些构件。 对于具有配置的工件依赖关系的构建配置,您可以指定此配置从其他构建下载的工件是否可以被清理。 这个设置可以在 清理策略 页面上找到。
在链中运行个人构建
如果您运行的个人构建是 构建链 的一部分,那么所有依赖于它的构建也将作为个人构建运行。
然而,如果您在依赖设置中启用了 合适构建的复用 ,TeamCity 将尽可能优化该链。 如果运行个人依赖构建没有带来任何价值,或者与检出规则相冲突,那么 TeamCity 将使用已完成的非个人构建替代。