在版本控制中存储项目设置
TeamCity 允许将项目设置与版本控制库(VCS)同步。 支持的版本控制系统包括 Git 、 Mercurial 、 Perforce 、 Subversion 以及 Azure DevOps Server (之前称为 TFS)。
您可以使用 XML 格式或 Kotlin 语言 来存储项目设置,并使用 基于 Kotlin 的 DSL 编程定义设置。
版本设置存储在 VCS 仓库根目录的 .teamcity
文件夹中,其格式与 TeamCity 数据目录 中的格式相同。
warning
默认情况下,项目设置与版本控制系统的同步功能已被禁用。
要启用它,前往 Project Settings | Versioned Settings | Configuration。 需要"启用/禁用版本设置"的权限(系统管理员角色的默认权限)。
在这里,您可以选择以下选项之一:
使用与父项目(默认)相同的设置。
禁用同步。
启用同步。 在这种情况下,您也可以定义在构建开始时要使用哪些设置。 参见以下 详情。
存在两种设置同步模式: 双向 和 单向。
默认模式是 双向同步,也就是当 允许通过用户界面编辑项目设置 选项开启时。 其工作原理如下:
在 TeamCity 用户界面中对项目设置所做的每一次管理更改都会被提交到版本控制系统中;修改是以 TeamCity 用户的身份进行提交的。
如果设置更改已提交至 VCS,那么 TeamCity 服务器将会检测到它们,并即时将其应用到项目中。
在应用新提交的设置之前,TeamCity 会进行验证。 如果验证约束未得到满足(即,设置无效),当前设置将保持原样,并且在用户界面中显示一条错误。 无效的设置是因为某些限制无法加载的设置:例如,构建配置引用了不存在的 VCS 根或者有重复的 ID 或名称。
如果您禁用了 允许通过 UI 编辑项目设置 选项,项目设置将在 UI 中变为只读,并且只会反映在 VCS 中所做的更改。 如果您更倾向于将项目设置定义为代码,或者从只读的 VCS 分支加载设置,这将非常方便。
为项目启用同步也会默认启用其所有子项目的 "使用父项目的设置" 选项。 TeamCity 同步所有对项目设置的更改(包括对 构建配置、模板、VCS 根等的修改),除了 SSH 密钥。
然而,如果某些子项目选择了"禁用同步"选项,则即使其父项目启用了此选项,这些子项目也不会被同步。
一旦在项目中启用同步,TeamCity 将在选定的仓库中进行初始提交,存储整个项目树(包含所有子项目的项目)的当前设置,这些设置来自服务器。 如果在指定的VCS根目录(父项目设置的VCS根目录或用户选择的VCS根目录)中找到给定项目的设置,将显示警告,询问是否应该由 TeamCity 来执行。
将 VCS 中的设置覆盖为 TeamCity 服务器上的当前项目设置(仅在启用了双向 同步 时有效);或
从版本控制系统中导入设置,将 TeamCity 服务器上的当前项目设置替换为版本控制中的设置。
tip
如果您选择生成 可移植 DSL 脚本,并且当前项目包含的实体少于 20 个,那么 TeamCity 将创建一个
settings.kts
文件来定义它们所有的实体。 单个实体包括 项目、构建配置、模板 和 VCS 根目录。如果项目中的实体数量超过 20,那么 TeamCity 就会创建一个独立的.kt
文件层级来定义并分组这些实体。
在 Configuration 标签页中,您也可以选择用于存储项目设置的 VCS 根目录:您可以将设置存储在与源代码相同的库中,或者在专用的 VCS 根目录中。
当 TeamCity 需要启动构建时,它可以应用两种可能的设定中的任何一种:
TeamCity 服务器上的当前设置。 这些设置包括应用于服务器的所有最新更改,无论是通过 TeamCity UI 还是通过提交至 VCS 中的
.teamcity
目录。在版本控制系统中存储的自定义设置。 这些是从
.teamcity
目录中存储的设置,它们保存在非默认分支或在为构建选定的特定修订版本中。
选择应用这两种设置中的哪一种的能力,为您提供了以下选项:
在
.teamcity
目录中,拥有多个分支,且各分支设定不同。 这意味着您的分支 A 可以拥有参数、步骤、构建功能、工件发布规则和链设置,这些都可能与分支 B 中的设定不同。开始 个人构建,并在
.teamcity
目录中进行更改,这些更改将影响构建行为。为您的 history builds 添加更多的灵活性。 TeamCity 最初尝试使用与所选更改时刻相对应的设置。 否则,将使用当前项目的设置。
要指定 TeamCity 在构建开始时应应用哪些设置,请在 管理 | <项目> 版本设置 页面上选择所需的选项。

始终使用当前设置 — 所有构建都使用来自 TeamCity 服务器的当前项目设置。 在分支、历史记录和个人构建中的设置更改将被忽略。 用户无法使用自定义项目设置运行构建。
默认使用当前设置—— 常规构建会使用来自 TeamCity 服务器的最新项目设置。 用户可以运行从 VCS 导入设置的 自定义构建。
使用来自 VCS 的设置 — 所有分支构建和历史构建,使用来自 VCS 的设置,加载来自为构建计算的版本设置的修订。 用户可以在 IDE 中的个人构建中更改配置设置,或者通过 自定义构建对话框在 TeamCity 服务器上使用当前项目设置运行构建。
warning
某些设置无法从 VCS 中加载。 当 TeamCity 检测到这些设置中的编辑时,它会忽略它们,并应用服务器上存储的当前设置。 这些设置包括:
构建触发器
构建配置级别的选项,如挂起构建检测,个人构建的可用性,构建配置类型等等
清理规则
custom runs中的代理要求
某些构建功能的设置(例如,Commit Status Publisher 使用 VCS 设置,而 Pull Requests 始终使用当前服务器设置)
对现有工件规则的编辑(您仍然可以添加新规则和删除现有规则)
(仅当 在快照依赖和版本控制设置中应用更改 设置被禁用时)创建新的并编辑现有的快照依赖、检出规则和 VCS 根。
tip
在开始构建之前,TeamCity 将此构建的配置存储为 隐藏工件,存放在
.teamcity/settings
目录下。 您可以检查这些配置文件,以确定构建实际使用了哪些设置。
在您选择的 VCS 中创建并初始化一个空的存储库。 在此示例中,使用了 GitHub.com 上的一个仓库。
从此仓库创建一个新的 TeamCity 项目。
在您的构建配置中添加一个 Python 运行器。
import jetbrains.buildServer.configs.kotlin.* import jetbrains.buildServer.configs.kotlin.buildSteps.python object Build : BuildType({ name = "Build" // ... steps { python { id = "python_runner" command = script { content = """print ("Running a Python script...")""" } } } // ... })
前往 Administration | <Project> | Versioned Settings 并选择以下选项:
启用同步:开启
项目设置 VCS 根目录:请选择您的项目的 VCS 根目录
设置格式:Kotlin
当构建开始时:选择 "使用 VCS 的设置"
应用快照依赖项和版本控制设置中的更改:开启(请参见 应用快照依赖性和版本控制设置中的更改 部分)
点击 Apply 以保存您的新设置。 TeamCity 将验证您的构建配置的有效性,并将带有您的设置的
.teamcity
文件夹推送到相关的 VCS 仓库。将 TeamCity 设置从远程仓库复制到本地存储。
git clone <Clone_URL> .
创建一个新的仓库分支。
git checkout -b custom-branch
按照以下步骤编辑您的
.teamcity/settings.kts
文件的本地副本:import jetbrains.buildServer.configs.kotlin.* import jetbrains.buildServer.configs.kotlin.buildSteps.csharpScript object Build : BuildType({ name = "Build" // ... steps { csharpScript { id = "csharpScript" content = """Console.WriteLine("Running a CSharp script...");""" tool = "%teamcity.tool.TeamCity.csi.DEFAULT%" } } // ... })
将您的新分支推送到远程仓库。
git add * git commit -a -m "Modify custom-branch settings" git push --set-upstream origin custom-branch
TeamCity 应该会很快收集您的新更改。 您可以通过在项目设置页面的 版本设置 选项卡上点击 从 VCS 加载项目设置... 来手动触发此过程。
如果您已设置默认的 触发器,用于在远程仓库发生变化时启动新的构建,则您的新自定义分支的新构建将自动启动。 否则,在构建配置页面上选择所需的分支,然后手动运行新的构建。
因此,您的构建配置现在会根据运行的分支执行不同的操作:主分支运行 Python Script,而自定义分支运行 C# 脚本。 您可以尝试在分支设置和运行分支构建中增加更多的差异,以观察 TeamCity 如何处理您 settings.kts
文件的不同版本。
如果在项目的 版本设置 页面上对应的选项被禁用,那么 TeamCity 将忽略对以下内容所做的编辑:
快照依赖项
签出规则
VCS 根
这适用于编辑现有的依赖关系、检出规则和根,以及创建新的依赖关系、检出规则和根。
例如,下面的 Kotlin 示例说明了同一个项目的两个 设置版本。
主(默认)分支定义了三个构建配置,它们在单个的 BC0 → BC3 → BC5 构建链中被链接起来。 每个配置都会编辑 "output.txt" 文件并将其传递给下一个配置。
自定义分支通过添加两个新的配置项扩展了原始链:BC0 → BC2 → BC3 → BC4 → BC5。
import jetbrains.buildServer.configs.kotlin.*
import jetbrains.buildServer.configs.kotlin.buildSteps.script
project {
buildType(BC0)
buildType(BC3)
buildType(BC5)
}
// 1st build configuration
object BC0 : BuildType({
name = "BC0"
artifactRules = "output.txt"
steps {
script {
name = "Prepare File"
id = "Prepare_File"
scriptContent = """
rm output.txt
touch output.txt
""".trimIndent()
}
script {
name = "WriteLine"
id = "WriteLine0"
scriptContent = """echo "Running BC0 config" > output.txt"""
}
}
// ...
})
// 2nd build configuration
object BC3 : BuildType({
name = "BC3"
artifactRules = "output.txt"
steps {
script {
name = "WriteLine"
id = "WriteLine3"
scriptContent = """echo "Running BC3 config" >> output.txt"""
}
}
dependencies {
dependency(BC0) {
snapshot { reuseBuilds = ReuseBuilds.NO }
artifacts { artifactRules = "output.txt" }
}
}
// ...
})
// 3rd build configuration
object BC5 : BuildType({
name = "BC5"
artifactRules = "output.txt"
steps {
script {
name = "WriteLine"
id = "WriteLine5"
scriptContent = """echo "Running BC5 config" >> output.txt"""
}
}
dependencies {
dependency(BC3) {
snapshot { reuseBuilds = ReuseBuilds.NO }
artifacts { artifactRules = "output.txt" }
}
}
// ...
})
import jetbrains.buildServer.configs.kotlin.*
import jetbrains.buildServer.configs.kotlin.buildSteps.script
project {
buildType(BC0)
buildType(BC2)
buildType(BC3)
buildType(BC4)
buildType(BC5)
}
// 1st build config
object BC0 : BuildType({
name = "BC0"
artifactRules = "output.txt"
steps {
script {
name = "Prepare File"
id = "Prepare_File"
scriptContent = """
rm output.txt
touch output.txt
""".trimIndent()
}
script {
name = "WriteLine"
id = "WriteLine0"
scriptContent = """echo "Running BC5 config" > output.txt"""
}
}
// ...
})
// 2nd build config
object BC2 : BuildType({
name = "BC2"
artifactRules = "output.txt"
steps {
script {
name = "WriteLine"
id = "WriteLine2"
scriptContent = """echo "Running virtual BC2 config" >> output.txt"""
}
}
dependencies {
dependency(BC0) {
snapshot { reuseBuilds = ReuseBuilds.NO }
artifacts { artifactRules = "output.txt" }
}
}
// ...
})
// 3rd build config
object BC3 : BuildType({
name = "BC3"
artifactRules = "output.txt"
steps {
script {
name = "WriteLine"
id = "WriteLine3"
scriptContent = """echo "Running BC3 config" >> output.txt"""
}
}
dependencies {
dependency(BC2) {
snapshot { reuseBuilds = ReuseBuilds.NO }
artifacts { artifactRules = "output.txt" }
}
}
// ...
})
// 4th build config
object BC4 : BuildType({
name = "BC4"
artifactRules = "output.txt"
steps {
script {
name = "WriteLine"
id = "WriteLine4"
scriptContent = """echo "Running virtual BC4 config" >> output.txt"""
}
}
dependencies {
dependency(BC3) {
snapshot { reuseBuilds = ReuseBuilds.NO }
artifacts { artifactRules = "output.txt" }
}
}
// ...
})
// 5th build config
object BC5 : BuildType({
name = "BC5"
artifactRules = "output.txt"
steps {
script {
name = "WriteLine"
id = "WriteLine5"
scriptContent = """echo "Running BC5 config" >> output.txt"""
}
}
dependencies {
dependency(BC4) {
snapshot { reuseBuilds = ReuseBuilds.NO }
artifacts { artifactRules = "output.txt" }
}
}
// ...
})
如果您禁用了 应用快照依赖项和版本控制设置中的更改 选项,并尝试为定制分支运行构建,则会出现 "无法解析构件依赖" 错误。 这是因为对快照依赖项所做的编辑被忽视了。 从 TeamCity 的角度来看,此设置无效,因为它需要不存在的配置。

前述设置使 TeamCity 能够自动生成缺失的配置并解决更新的依赖关系,这反过来使得可以应用这些自定义分支设置。

note
自动生成的构建配置是“服务”配置,确保所有必需的设置都已成功应用。 这些配置并非设计为手动运行,而只应在运行具有自定义分支特定设置的链时由 TeamCity 触发。
如果您将设置从自定义分支合并到默认分支,将会保留自动生成配置的构建历史。
建议将安全数据存储在 VCS 之外。 如果启用了 双向同步,则 在 VCS 外部存储密码和 API 令牌 这一选项会在 Project Settings | Versioned Settings | Configuration 页面中可用。 默认情况下,如果首次为项目启用了版本设置,那么此选项将会被启用,而对于已经在 VCS 中存储了它们设置的项目,此选项将被禁用。
如果启用了此选项,TeamCity 将在 XML 配置文件中存储随机生成的 ID,而不是混淆的密码。 实际密码存储在磁盘上的 TeamCity 数据目录 下,并未纳入版本控制系统的检查中。
warning
如果禁用此选项,应在将安全数据提交到 VCS 之前考虑以下列出的 安全影响。
如果您需要将密码(或其他安全值)添加到非通过 TeamCity UI(例如,通过 Kotlin DSL)的版本设置中,您可以生成一个用于在设置中替代此密码的令牌。
在项目设置中,从操作下拉菜单中选择为安全值生成令牌。 输入密码并点击 生成令牌。 生成的令牌将被存储在服务器上。 您可以复制并在项目配置文件中使用它,而不是密码。
params {
password("<parameter_name>", "credentialsJSON:<token>")
}
note
您只能在配置文件中使用令牌来引用安全值。 如果您在 TeamCity UI 中将 "credentialsJSON:<token>" 插入为 密码参数 的值,TeamCity 将不会获取令牌的底层安全值。 反而,“credentialsJSON:<token>”字符串本身将被用作实际的密码值。
您还可以在项目的 版本设置 部分的 令牌 标签中生成新的安全令牌。 启用 "将安全值存储在 VCS 外部 " 选项的项目可以使用此选项卡。
令牌标签页允许查看所有的项目令牌,包括未使用的令牌。
当项目的安全数据存储在版本控制系统之外时,它可能会从项目中分离出来:例如,如果将带有令牌的项目移动到层次结构的另一个位置,或者在新的 TeamCity 服务器上从 DSL 创建。 在这种情况下,您可以在此选项卡上指定项目令牌的值,以便项目可以继续使用它们。
此外,如果您有权限编辑的其他项目中有所需的令牌,TeamCity 将自动找到它们。 您可以将在这些项目中使用的安全值复制到您当前的项目。

当一个令牌有一个或多个安全值可用时, 按钮会出现在此令牌的对面。 点击它以查看可用的项目并选择一个项目以复制其值,然后点击 复制 来确认您的选择。
安全值可以由项目层次结构继承。 如果项目中的某项设置(VCS 根,OAuth 连接,云配置文件)需要密码,为此密码生成的令牌可以在此项目及其任何子项目中使用。 为了能够使用继承的密码,子项目必须启用版本设置,并在与其父项目相同的 VCS 中存储设置。
或者,您可以添加一个带有安全值的 密码参数,并在嵌套项目中使用对该参数的 引用。
如果您决定在 VCS 中存储安全设置,建议您仔细考虑以下影响:
如果在版本控制系统(VCS)中的项目或构建配置中有设置定义了密码字段,那么这些值将以混乱的形式出现在提交到 VCS 的设置中。
如果项目设置存储在与源代码同一个仓库中,任何有权访问该仓库的人都将能看到这些被打乱的密码。
如果项目设置被单独存储在一个专用的仓库中,与源代码分开 ,并且 "在构建中显示设置更改" 选项被启用,拥有 "查看 VCS 文件内容" 权限的任何用户都能使用 更改差异查看器 在 TeamCity UI 中查看所有更改。
通过 VCS 以任意方式更改设置,无论在 TeamCity 中配置的构建配置权限如何,都可以触发任何构建配置的构建并获取任何构建配置的设置。
通过提交错误或恶意的设置,用户可能会影响整个服务器的性能或对其他用户的服务器展示。
建议将密码、API 令牌以及其它安全设置存储在 VCS 之外,使用上文所述的相应配置选项。
请注意,SSH 密钥不会存储在 VCS 仓库中。
将 Kotlin DSL 或 XML 设置存储在 VCS 中,允许您利用配置即代码的方法进行项目和构建配置。 您可以指定项目的层级结构,管理各个配置,动态更改步骤设置和参数,等等。
然而,这种方法不允许您管理服务器范围的设置(如用户和用户组设置、清理规则、通知、认证模块、许可证等)。 为了自动化您的服务器管理,需要在 HCL 语言格式中定义所需设置,并使用 HashiCorp Terraform 进行管理。 为了让 Terraform 能够与您的 TeamCity 服务器实例进行通信,请在您的 Terraform 配置中添加专用的 TeamCity Terraform 提供程序。
了解更多:
为了能够选择设置格式,请在 Project Settings | Versioned Settings | Configuration 中点击 显示高级选项。
TeamCity 存储项目设置:
在 XML 格式中
在 Kotlin-based DSL 格式中(请参阅专门的页面)
note
要在沙盒项目中测试基于 Kotlin 的设置,您可以在不禁用用户界面的情况下下载设置作为 ZIP 归档文件:在 项目设置 页面上,点击 操作 菜单并选择 以 Kotlin 格式下载设置。 将会下载一个 ZIP 归档文件。
warning
在将设置提交到 VCS 之前,请考虑按照上述推荐的方法存储安全设置。
如果您想将当前配置提交到版本控制系统(例如,之前您将配置错误的设置提交到代码库,而 TeamCity 无法加载它,显示错误和警告),您可以在 版本化设置 | 配置 页面使用 提交当前项目设置 选项。
当 TeamCity 将设置提交到 VCS 时,它使用标准的提交信息,注明 TeamCity 用户作为提交者以及设置已更改的项目。 通过 TeamCity 提交的每个设置更改都可以添加固定的自定义前缀,这可以通过 teamcity.versionedSettings.commitMessagePrefix
内部属性实现,例如, teamcity.versionedSettings.commitMessagePrefix=TC 变更\n\n
。
TeamCity 不仅会同步设置,还会自动显示项目设置的更改,就像它对版本控制中的常规更改所做的那样。 您可以配置显示受影响的构建配置中的更改:在 Project Settings | Versioned Settings | Configuration 标签页上,点击 显示高级选项 并勾选 在构建中显示设置更改 框。 只有在您将版本化设置存储在未直接附加到当前构建配置的 VCS 根中时,此选项才有效。 如果一个 VCS 根被附加到此配置上,它的变化将默认显示,除非配置了特定的 构建触发规则。
如果您在单独的 VCS 根目录中存储版本设置,而不是直接附加到您的构建配置的那个,那么当此复选框打开时,将开始显示对这些 VCS 根目录所做的更改。 如果 VCS 根已经连接到您的配置,那么它什么也不会做。
默认情况下,VCS 触发器会忽略此类更改。 要启用设置提交上的构建触发,按照以下格式添加一个触发规则: +":root=Settings_root_id;:*
。
所有在 VCS 根目录中进行的更改,其中存储了项目设置,都会在 版本设置 | 更改日志 选项卡上列出。
XML 设置文件的格式会随着 TeamCity 版本的变更而变更,以适应新的功能和改进。 通常,格式在错误修正版本中不会改变,而在主要版本中会发生改变。 当 TeamCity 服务器进行升级时,TeamCity 服务器上的当前设置会从旧版本格式改变为当前版本格式。
在升级生产服务器之前,用生产数据升级 TeamCity 测试服务器是一种常见的做法。 为了避免意外更改用于较旧版本的生产服务器的设置格式,升级 TeamCity 后将禁用版本设置,并显示相应的健康项。 系统管理员有权限启用版本设置(管理员 | 服务器健康 | 版本设置已禁用,点击 启用)。 启用后,将以当前 TeamCity 版本的格式检查已转换的设置是否在版本控制中。 请注意,新的设置将被提交到 VCS 根的默认分支;存储在其他分支中的设置将需要手动更新。
Q. 我可以应用来自不同版本的 TeamCity 服务器的设置吗?
答: 不,因为就像 TeamCity 数据目录一样,设置的格式会因 TeamCity 的版本不同而有所不同。
Q. 设置保存在哪里?
A。 设置存储在VCS根配置仓库路径的根目录的 .teamcity
目录中。 对于 Git 和 Mercurial,这总是仓库的根目录。 在 VCS 根目录中配置的默认分支将与 Git 和 Mercurial 一起使用。 您可以创建一个专用的 VCS 根来更改分支(或者在 Perforce,Subversion 或 Azure DevOps(以前称为 TFS)的情况下更改仓库路径)。
Q. 为什么我在用户界面更改设置后,构建的运行会有延迟?
答: 当通过用户界面更改设置时,TeamCity 会等待更改通过 VCS 的提交完成后,才会使用最新的更改运行构建。
Q. 更改是由谁编写的?
A。 如果通过用户界面更改了设置,在 Git 和 Mercurial 中,将代表实际通过 UI 进行更改的用户在 VCS 上执行一次提交。 对于 Perforce 和 Azure DevOps Server(以前的 TFS),将使用在 VCS 根中指定的用户名称,在 Subversion 中,提交消息也将包含通过 UI 实际进行更改的 TeamCity 用户的用户名。
感谢您的反馈!