合成构建配置
复合构建配置是一种"无步骤"的配置,旨在触发多个常规构建配置,并在一个地方跟踪结果。
复合配置不执行任何实际的构建程序。
复合配置聚合了其所有依赖项的信息,并以集中的方式进行呈现。
复合构建不占用构建队列插槽,也不需要代理运行。
要切换构建配置类型,请导航到 配置设置 | 常规 选项卡。
在本教程中,您将创建多个构建配置,将它们绑定在一个单一的构建链中,并了解如何从将链的最顶部构建配置转化为复合配置中获益。
note
在此步骤中,您将创建一个带有空白构建配置的项目,并创建一个带有五个构建配置的子项目,这五个构建配置将在不同平台下构建、测试并发布 .NET / .NET Framework 项目。

从以下的 GitHub 仓库(或其分支)创建一个项目: TeamCity DotNet Samples。 导入项目时,选择 不要导入设置,从头创建项目 选项。
将构建配置名称设置为 "Build All"。
在 TeamCity 扫描存储库后,不要选择其建议的任何步骤。 我们将在不同的配置中执行实际的构建任务,而这个初始创建的配置稍后将被用来一次性触发所有的任务。
打开 项目设置。
单击 创建子项目。 这个子项目应该定位到与第1步中相同的 GitHub 仓库。
由于您的子项目使用的是与根项目相同的存储库,TeamCity 建议两个项目共享同一 VCS root ,而不是创建一个副本。 在提示同意时,单击 使用此项。
在您的新 “构建配置” 子项目中, 创建五个构建配置。 所有配置都应指向步骤1中的相同仓库,并使用共享的 VCS 根(参见步骤5)。
运行测试(Linux) — 一个配置,包含一个 .NET 运行器,用于在 .NET SDK 容器 中测试 Linux 上的 "Clock.Tests" C# 项目。
运行测试(Windows) — 一个配置,包含一个 .NET 运行器,用于在安装了所需 .NET SDK 的 Windows 代理上测试 "Clock.Tests" C# 项目。
构建桌面 (Windows) — 一个配置,包含一个 .NET 运行器,用于对 "Clock.Desktop" 和 "Clock.Desktop.Uwp" 项目执行 "msbuild" 命令。
构建控制台 & 网页(win-x64)——一个包含两个 .NET 步骤的配置。
一步执行 "Clock.Console" 项目上的 "publish" 命令,并使用 "win-x64" 运行时选项。 此步骤的输出目录被设置为 "bin/Clock.Console/win-x64"。
另一步执行 "Clock.Web" 项目上的 "publish" 命令。 此步骤的 运行时 选项为 "win-x64", 输出目录 为 "bin/Clock.Web/win-x64"。
构建控制台 & 网页(linux-x64) — 与之前的配置相同,但 .NET 步骤的 运行时 和 输出目录 设置分别为 "linux-x64" 和 "bin/<ProjectName>/linux-x64"。
由于这些构建配置将成为单一 构建链的一部分,因此无需自动添加 构建触发器 ,以便在 TeamCity 检测到远程仓库中的变更时独立启动所有五个构建配置。 转到 构建配置设置 | 触发器 ,禁用或删除所有配置的触发器(最顶层项目拥有的 "Build All" 配置除外)。
两种 "Build console & web" 配置都应该发布他们的 "bin" 文件夹。 为了做到这一点,需要在这些配置中指定
bin => bin
artifact paths。 发布的构件将稍后由 deployment configurations 使用。
您应该最终得到五个独立的构建配置,这些配置执行构建步骤,以及一个空的 "Build All" 配置。 运行每个配置以确保它们成功完成。 以下的 Kotlin 代码演示了全部五个构建配置及其父级 TeamCity 项目的设置。
project {
buildType(Building_1)
subProject(Building)
}
object Building_1 : BuildType({
id("Building")
name = "Build All"
vcs {
root(DslContext.settingsRoot)
showDependenciesChanges = true
}
triggers {
vcs {
}
}
})
object Building : Project({
name = "Building Configurations"
buildType(Building_BuildConsoleWebLinuxX64)
buildType(Building_BuildConsoleWebWinX64)
buildType(Building_BuildDesktopWindows)
buildType(Building_RunTestsLinux)
buildType(Building_RunTestsWindows)
})
object Building_RunTestsLinux : BuildType({
name = "Run Tests (Linux)"
vcs {
root(DslContext.settingsRoot)
}
steps {
dotnetTest {
name = "Tests (Linux)"
projects = "Clock.Tests/Clock.Tests.csproj"
dockerImage = "mcr.microsoft.com/dotnet/sdk:7.0"
dockerImagePlatform = DotnetTestStep.ImagePlatform.Linux
}
}
triggers {
vcs {
enabled = false
}
}
requirements {
matches("teamcity.agent.jvm.os.family", "Linux")
}
})
object Building_RunTestsWindows : BuildType({
name = "Run Tests (Windows)"
vcs {
root(DslContext.settingsRoot)
}
steps {
dotnetTest {
name = "Test (Win)"
projects = "Clock.Tests/Clock.Tests.csproj"
sdk = "7"
}
}
triggers {
vcs {
enabled = false
}
}
requirements {
matches("teamcity.agent.jvm.os.family", "Windows")
}
})
object Building_BuildDesktopWindows : BuildType({
name = "Build Desktop (Windows)"
artifactRules = """
bin/Clock.Desktop/win/**/*.* => bin/Clock.Desktop.zip
bin/Clock.Desktop.Uwp/win/**/*.* => bin/Clock.Desktop.Uwp.zip
""".trimIndent()
params {
param("system.PublishDir", "../bin/Clock.Desktop/win/")
param("system.AppxPackageDir", "../bin/Clock.Desktop.Uwp/win/")
}
vcs {
root(DslContext.settingsRoot)
}
steps {
dotnetMsBuild {
name = "Build Desktop (Win)"
projects = """
Clock.Desktop/Clock.Desktop.csproj
Clock.Desktop.Uwp/Clock.Desktop.Uwp.csproj
""".trimIndent()
version = DotnetMsBuildStep.MSBuildVersion.V17
targets = "Restore;Rebuild;Publish"
sdk = "7"
}
}
triggers {
vcs {
enabled = false
}
}
requirements {
matches("teamcity.agent.jvm.os.family", "Windows")
}
})
note
系统属性在此构建配置中指定了“Publish”任务应将输出放置的目录。 了解详情:
object Building_BuildConsoleWebWinX64 : BuildType({
name = "Build console & web (win-x64)"
artifactRules = "bin => bin"
vcs {
root(DslContext.settingsRoot)
}
steps {
dotnetPublish {
name = "Build Console (win-x64)"
projects = "Clock.Console/Clock.Console.csproj"
runtime = "win-x64"
outputDir = "bin/Clock.Console/win-x64"
}
dotnetPublish {
name = "Build web"
projects = "Clock.Web/Clock.Web.csproj"
runtime = "win-x64"
outputDir = "bin/Clock.Web/win-x64"
}
}
triggers {
vcs {
enabled = false
}
}
requirements {
exists("DotNetCoreSDK7.0_Path")
exists("DotNetCoreRuntime7.0_Path")
}
})
object Building_BuildConsoleWebLinuxX64 : BuildType({
name = "Build console & web (linux-x64)"
artifactRules = "bin => bin"
vcs {
root(DslContext.settingsRoot)
}
steps {
dotnetPublish {
name = "Build console"
projects = "Clock.Console/Clock.Console.csproj"
runtime = "linux-x64"
outputDir = "bin/Clock.Console/linux-x64"
args = "/p:PublishTrimmed=true /p:PublishSingleFile=true"
}
dotnetPublish {
name = "Build web"
projects = "Clock.Web/Clock.Web.csproj"
runtime = "linux-x64"
outputDir = "bin/Clock.Web/linux-x64"
}
}
triggers {
vcs {
enabled = false
}
}
requirements {
exists("DotNetCoreSDK7.0_Path")
exists("DotNetCoreRuntime7.0_Path")
}
})
在此步骤中,您将创建 快照依赖性以将构建配置绑定在一个链中。

在 "Build Desktop (Windows") 配置设置中,切换到 依赖 选项卡并单击 添加新的快照依赖项。 检查 "Run Tests (Windows)" 构建配置,告诉 TeamCity 应在启动此构建配置之前运行测试。
重复步骤1,为两个 "Build console & web ..." 配置设置快照依赖。 他们应依赖相应的 "Run Tests..." 配置。
在 "Build All" 配置设置中,为所有三个 "Build..." 配置添加快照依赖。
三种 "Build..." 配置发布工件。 为了使它们能够从最顶层的 "Build All" 配置中访问,您需要创建 工件依赖。
导航到 <Build All settings> | 依赖项 ,单击 添加新的工件依赖项 ,并为所有三个 "Build..." 配置创建依赖项。 每个工件依赖项中的 工件规则 设置应为
**/*.* => .
。现在, "Build All" 配置可以访问由各个 "Build..." 配置生成的构件,于是在其通用设置中添加
bin/**/*.* => .
构件发布规则。
以下的 Kotlin 代码演示了最终链设置。
object Building_1 : BuildType({
id("Building")
name = "Build All"
artifactRules = "bin/**/*.* => ."
// ...
dependencies {
dependency(Building_BuildConsoleWebLinuxX64) {
snapshot {
}
artifacts {
artifactRules = "**/*.* => ."
}
}
dependency(Building_BuildConsoleWebWinX64) {
snapshot {
}
artifacts {
artifactRules = "**/*.* => ."
}
}
dependency(Building_BuildDesktopWindows) {
snapshot {
}
artifacts {
artifactRules = "**/*.* => ."
}
}
}
})
object Building_BuildDesktopWindows : BuildType({
name = "Build Desktop (Windows)"
artifactRules = """
bin/Clock.Desktop/win/**/*.* => bin/Clock.Desktop.zip
bin/Clock.Desktop.Uwp/win/**/*.* => bin/Clock.Desktop.Uwp.zip
""".trimIndent()
// ...
dependencies {
snapshot(Building_RunTestsWindows) {
}
}
})
object Building_BuildConsoleWebWinX64 : BuildType({
name = "Build console & web (win-x64)"
artifactRules = "bin => bin"
// ...
dependencies {
snapshot(Building_RunTestsWindows) {
}
}
})
object Building_BuildConsoleWebLinuxX64 : BuildType({
name = "Build console & web (linux-x64)"
artifactRules = "bin => bin"
// ...
dependencies {
snapshot(Building_RunTestsLinux) {
}
}
})
您可以在配置设置的 常规 选项卡中选择构建配置类型。 在此示例链中,您可以将 "Build All" 配置类型更改为 "Composite"。

与常规构建配置相比,复合配置表现出以下差异。
TeamCity 使用不同的图标来帮助您区分常规配置和复合配置。
在导航栏中:

在 构建配置 | 链 页面上:

在导航栏中:

在 构建配置 | 链 页面上:

复合构建配置汇总其他构建生成的结果。 它并未设计用于执行实际的建筑流程。 因此,复合配置设置不会显示 构建步骤 或 代理要求 选项卡。

由于复合构建配置并没有任何实际的构建步骤要执行,所以它不会占用 build queue 中的一个位置。

如果您 限制同时运行的复合构建的数量 ,它将影响所有依赖项。 例如,假设当前的限制是 1,而一个复合构建正在运行。 在这种情况下,所有属于另一个排队的复合构建的依赖构建将会等待正在进行的构建完成。
当您停止复合构建或将其从队列中移除时,整个构建链都会被停止或移除。
当构建链的第一依赖项开始时,组合构建将显示为运行状态。 构建的状态文本、持续时间和进度指示器反映了此链中每个常规构建的聚合参数。

如果链中的任何构建失败,复合构建会反映这个问题,以便您可以立即发现问题。

复合构建的 测试 选项卡汇总测试,并在一个地方显示所有通过、失败、静音和忽略的测试。 代码覆盖率或代码检查/代码重复分析的结果同样适用。

普通构建和组合构建都不会聚合其链中的构建工件。 要在复合构建的 工件 选项卡中显示常规构建生成的工件,请添加相应的工件依赖项并设置所需的工件规则(请参见 设置构建链 部分中的步骤 4 和 5)。

由于复合配置没有自己的构件,因此需要在依赖配置中设置构件清理策略。
项目 | 构建链 页面显示 分组复合构建 选项,允许您将以复合配置结束的构建链的所有部分折叠为一个可视元素。

Thanks for your feedback!