TeamCity On-Premises 2024.03 Help

Kotlin DSL

除了以XML格式在版本控制中存储设置外,TeamCity还允许在DSL(基于Kotlin语言)中存储设置。

使用版本控制存储的 DSL 允许您以编程方式定义设置。 由于 Kotlin 是静态类型的,您在集成开发环境中会自动获得自动完成功能,这使得发现可用的 API 选项变得更加简单。

查看关于在 TeamCity 中使用 Kotlin DSL 的 博客文章系列,以及 推荐的重构文章。

查看更多 TeamCity Kotlin DSL 视频教程:

Kotlin DSL 是如何工作的

当启用 Kotlin 格式的版本设置时,TeamCity 将当前设置提交到指定的设置仓库。

当检测到设置仓库中有新的提交时,TeamCity 会运行此提交中找到的 DSL 脚本,并将结果应用到 TeamCity 服务器上的设置,或者在项目的 版本设置 标签页上报告错误。

注意:DSL 脚本基本上是编写 TeamCity 配置文件的另一种方式。 DSL 脚本并不能直接控制构建的执行方式。 例如,根据构建的当前状态设定条件并做出相应改变是不可能的。 脚本执行的结果是配置文件,这些文件由 TeamCity 服务器加载,然后新触发的构建的行为发生了变化。

由于 DSL 是 Kotlin 编程语言中的代码,因此该语言支持的所有范型都能用。 例如,可以创建一个函数或类,而不是使用 TeamCity 模板,以封装项目的通用设置。 对于具有编程技能的人来说,这让构建配置设置的重复使用变得更为自然。

DSL 也适用于需要大量类似的构建配置的情况。 在这种情况下,它们可以由一些相当简单的代码生成,而如果没有 DSL,则需要在用户界面中花费大量时间来创建所有这些配置。

开始使用 Kotlin DSL

这个 Kotlin 教程 可以帮助您快速学习大部分 Kotlin 功能。 您的服务器的 Kotlin DSL API 文档可在 <teamcityserver:port>/app/dsl-documentation/index.html 查看。 您也可以参考 最新 TeamCity 版本的 Kotlin DSL API 文档

要开始在 TeamCity 中使用 Kotlin DSL,您需要在服务器上创建一个空的沙盒项目并按照以下步骤操作:

  1. 启用版本设置用于您的项目。

  2. 选择所需的 VCS 根目录。 确保它指定了正确的凭据;如果使用匿名认证,TeamCity 将无法提交更改。

  3. 选择 Kotlin 作为格式。

  4. 点击 Apply,然后 TeamCity 将把生成的 Kotlin 文件提交到您的仓库。

在提交到存储库后,您将获得包含以下文件的 .teamcity 设置目录:

  • settings.kts — 包含所有项目配置的主文件。

  • pom.xml — 允许 TeamCity 和外部 IDE (您用于打开 Kotlin 项目的)解决编译和运行 DSL 代码所需的依赖关系。

在 IntelliJ IDEA 中编辑 Kotlin 项目

您可以在 IntelliJ IDEA (支持 Ultimate 和 Community 版本)中创建、编辑和调试 TeamCity Kotlin DSL 项目。

创建新项目

要将 .teamcity 设置目录作为新模块添加到 IntelliJ IDEA 中的现有项目中,请按照以下步骤操作:

  1. 进入File | Project Structure,或者按Ctrl+Shift+Alt+S

  2. Project Settings 部分下选择 Modules

  3. 点击加号,选择 Import module 并选择包含您项目设置的目录。 点击 OK 并按照向导进行操作。

  4. 点击 应用。 新的模块已添加到您的项目结构中。

打开已存在的项目

要在 IntelliJ IDEA 中打开 Kotlin DSL 项目,请将 .teamcity/pom.xml 文件作为项目打开。 所有必要的依赖项将会立即自动解决。

如果所有依赖都已解决,那么在 settings.kts 中将不会看到红色的错误。 如果您已经有一个 IntelliJ IDEA 项目,并希望在其中添加一个 Kotlin DSL 模块,请按照 创建新项目 部分中的指示进行操作。

下载 DSL 文档

您本地的 TeamCity 服务器的 DSL 文档始终可以在 <TeamCity_server_URL/app/dsl-documentation/index.html 上找到。 您也可以将此文档导入至 IDE。 这样,您编辑 .kts 文件时,就能查看对象描述和示例。

在 IDEA 中的 DSL 文档和示例

要下载这些源文件,请在 Maven 面板中点击相应的选项...

下载 DSL 文档

...或运行 mvn -U dependency:sources 命令。

通过命令下载 DSL 文档

导入的文档将作为提示显示,这些提示会在指针悬停在关键字上时出现。 要在独立窗口中打开它,按下文档热键(默认为 F1 ),点击 查看 | 工具窗口 | 文档,或使用提示面板中的省略号按钮。

打开文档面板

编辑 Kotlin DSL

当创建一个空项目时,您会在 IDE 中的 settings.kts 中看到:

import jetbrains.buildServer.configs.kotlin.* /* some comment text */ version = "2024.03" project { }

在此, 项目 {} 代表了您将在 DSL 中定义的当前项目(在 DSL 代码中,有时会被引用为 _Self)。 这就是您在上一步中启用了版本设置的同一个项目。 此项目的 ID 和名称可以通过一个特殊的 DslContext 对象进行访问,但不能通过 DSL 代码进行更改。

以下示例展示了如何使用命令行脚本添加构建配置:

import jetbrains.buildServer.configs.kotlin.* import jetbrains.buildServer.configs.kotlin.buildSteps.script version = "2024.03" project { buildType { id("HelloWorld") name = "Hello world" steps { script { scriptContent = "echo 'Hello world!'" } } } }

在这里, iD 将被用作 TeamCity 中 构建配置 ID 字段的值。 在上述示例中,必须指定 iD。 如果您省略它,尝试从这个脚本生成设置时会出现验证错误。

还有另一种定义相同构建配置的方法:

import jetbrains.buildServer.configs.kotlin.* import jetbrains.buildServer.configs.kotlin.buildSteps.script version = "2024.03" project { buildType(HelloWorld) } object HelloWorld: BuildType({ name = "Hello world" steps { script { scriptContent = "echo 'Hello world!'" } } })

在这种情况下, id() 函数调用是可选的,因为 TeamCity 会根据类名(在我们的案例中是 HelloWorld )生成 id。

settings.kts 文件中进行了必要的更改后,您可以将它们提交到存储库——TeamCity 将会检测并应用它们。 如果脚本执行过程中没有错误,您应该在项目中看到一个名为 "Hello world" 的构建配置。

在本地生成 XML 配置文件

为Kotlin项目提供的 pom.xml 文件具有 生成 任务,可用于从DSL脚本本地生成TeamCity XML配置文件。 这项任务可以从IDE启动(请参见Maven工具窗口中的 Plugins | teamcity-configs | teamcity-configs:generate 节点),或者从命令行启动:

mvn teamcity-configs:generate

任务执行的结果将会被放在 .teamcity/target/generated-configs 目录下。

调试 Kotlin DSL 脚本

如果您正在使用 IntelliJ IDEA ,您可以轻松开始调试任何 Maven 任务:

  1. 导航至 查看 | 工具窗口 | Maven 项目Maven 项目 工具窗口已显示。

  2. 定位任务节点:Plugins | teamcity-configs | teamcity-configs:generate,在任务的上下文菜单中提供了Debug选项:

在 IDEA 中调试任务

通过 Web UI 编辑项目设置

TeamCity 允许通过网络界面编辑项目设置,尽管项目设置存储在 Kotlin DSL 中。 如果 DSL 脚本未手动更改,即如果它们由 TeamCity 生成并在仓库中保持不变,则通过网页 UI 进行的更改将直接应用于这些生成的文件。

但是,如果生成的文件发生了变化,那么 TeamCity 将不得不生成一个补丁,因为它已经不再知道 .kt 或 .kts 文件的哪个部分应该被修改。

在便携式 DSL 的情况下,补丁被放置在 .teamcity/patches 目录下,例如:

patches/projects/<relative project id>.kts patches/buildTypes/<relative build configuration id>.kts patches/templates/<relative vcs root id>.kts patches/vcsRoots/<relative build configuration id>.kts

补丁示例

以下补丁将 构建文件清理器(Swabra) 构建功能添加到具有 ID SampleProject_Build 的构建配置中:

changeBuildType(RelativeId("SampleProject_Build")) { // this part finds the build configuration where the change has to be done features { add { // this is the part which should be copied to a file which generates settings for SampleProject_Build build configuration swabra { filesCleanup = Swabra.FilesCleanup.DISABLED } } } }

暗示您将更改从补丁文件移至相应的 .kt.kts 文件,并删除补丁文件。 补丁生成使您可以继续使用用户界面进行项目设置的编辑,同时利用 Kotlin DSL 脚本的优势。

在 ID 更改后恢复构建历史记录

为了识别基于便携式 DSL 的项目中的构建配置,TeamCity 使用分配给 DSL 中的此构建配置的 ID。 我们建议保持此 ID 的恒定性,以便在 DSL 代码中所做的更改能够始终一致地应用于 TeamCity 中的相应构建配置。

然而,如果您在 DSL 中修改了构建配置 ID ,请注意,对于 TeamCity 来说,这种修改看起来就像是以前的 ID 配置被删除,而一个新的配置使用新的 ID 在单次提交中创建了。 在这种情况下,TeamCity 将自动将构建历史附加到具有新 ID 的构建配置中。 这同样适用于在一次提交中改变多个构建配置的 IDs 的情况:TeamCity 使用了一种逻辑,将构建历史分配给与被删除的配置最相似的配置。 此操作的条目将出现在 服务器日志 中。

如果您使用两次提交来修改构建配置 ID —— 一次删除具有前一个 ID 的配置,另一次添加具有新 ID 的构建配置 —— 则新的构建配置将不再包含构建的历史记录。 TeamCity 将保留 5 天的构建历史,直到 清理,在此期间,仍可以手动还原历史记录。

在更改构建配置ID后,若要手动恢复构建的历史记录,请转到已更改ID的构建配置的构建配置设置,打开操作菜单,然后点击附加构建历史记录。 您将被重定向到 附加构建历史记录 标签页。 选择分离的构建历史记录并点击 附加

附加构建历史记录

在界面中查看 DSL

在用户界面中查看您的构建配置设置时,您可以在侧边栏中点击 以代码形式查看:将会显示当前配置的 DSL 表示,并会突出显示正在查看的设置(例如,构建步骤,触发器,依赖项)。 要返回,请点击 在 UI 中编辑

如果您需要在 DSL 脚本中添加一些构建功能或触发器,而又不确定 DSL 代码应该是什么样子,那么这将特别有用。

分享 Kotlin DSL 脚本

便携式 DSL 脚本的优点之一是,同一服务器中的多个项目或多个服务器(因此得名:便携式)都可以使用该脚本。

如果您有一个包含以便携格式存储的设置的存储库,那么您可以轻松地基于这些设置创建另一个项目。 Create Project From URL 功能可供您使用。

将 TeamCity 指向您的存储库,它将检测到 .teamcity 目录并提供从中导入设置:

从网址创建项目时导入 Kotlin 设置

在 DSL 中使用上下文参数

您可以通过在 TeamCity UI 中配置的上下文参数来自定义 DSL 生成行为。 上下文参数在界面中作为项目 版本设置 的一部分进行指定。

通过上下文参数,可以在同一 TeamCity 服务器的不同项目中维护和使用单一的 Kotlin DSL 代码。 每个项目都可以拥有自己的上下文参数值,且基于这些参数的值,相同的 DSL 代码可以产生不同的设置。

访问 我们的博客 观看教程,学习如何在您的项目中使用上下文参数。

要在 TeamCity 项目中使用上下文参数,您需要(1)在 UI 的项目版本化设置中定义它,并且(2)在项目 DSL 中引用它。

  1. 管理 UI 中的上下文参数
    您可以在 版本设置 | 上下文参数 选项卡上管理项目上下文参数。

    Kotlin DSL 参数

    在您添加、编辑或删除参数并点击 保存 后,TeamCity 将重新加载 DSL 配置,并将更改的值应用到项目设置中。

  2. 在 DSL 中引用上下文参数
    要在 DSL 代码中引用上下文参数,请使用 getParameter() 方法和 DslContext 对象。 您可以将此参数的默认值指定为可选的第二个参数: getParameter("<parameter-name>", "<default-value>")
    以下例子展示了如何在 DSL 中使用上下文参数:

    object Build : BuildType({ /* a context parameter that defines a build configuration name; its default value is `Test Build` */ name = "${DslContext.getParameter("BuildName", "Test Build")}" script { scriptContent = "echo Build Successful" } /* disable the last build step depending on the value of the `environment` parameter */ script { scriptContent = "echo Deploy" enabled = DslContext.getParameter(name = "Environment") != "Staging" } })

每个上下文参数都应该有一个值,要么是在 DSL 中设置的默认值,要么是在用户界面中设置的特定于项目的值。 当您从 DSL 创建一个项目或者更新项目的版本设置时,TeamCity 会检测所有缺失值的上下文参数并提示您设置它们。

在 Maven 中定义 DSL 上下文参数

要为 上下文参数 定义特定值,请在您的 pom.xml 文件中添加 <contextParameters> 块。

带有上下文参数的 Maven 插件示例:

<plugin> <groupId>org.jetbrains.teamcity</groupId> <artifactId>teamcity-configs-maven-plugin</artifactId> <version>${teamcity.dsl.version}</version> <configuration> <format>kotlin</format> <dstDir>target/generated-configs</dstDir> <contextParameters> <BuildName>Test</BuildName> <Message>Test</Message> </contextParameters> </configuration> </plugin>

如果您希望在本地验证您的 DSL 脚本是否根据 DSL 上下文参数的不同值正确生成设置,那么这将非常有用。

存储和管理全球服务器设置

Kotlin DSL 或 XML 设置存储在 VCS 中,允许您利用配置即代码的方法进行项目和构建配置。 您可以指定项目的层级结构,管理各个配置,动态更改步骤设置和参数,等等。

然而,这种方法不允许您管理服务器范围的设置(如用户和用户组设置、清理规则、通知、认证模块、许可证等)。 为了自动化您的服务器管理,需要在 HCL 语言格式中定义所需设置,并使用 HashiCorp Terraform 进行管理。 为了让 Terraform 能够与您的 TeamCity 服务器实例进行通信,请在您的 Terraform 配置中添加专用的 TeamCity Terraform 提供程序

了解更多:

高级主题

构建链 DSL 扩展

TeamCity Kotlin DSL 为配置 构建链 提供了一种管道风格的替代方法。

在 DSL 代码中,构建链是由 顺序的 方法在项目内部逐个列出并声明的链式构建。 要将将并行运行在一个链中的构建进行分组,请使用 并行 方法:在 并行 区块之后的第一个随后构建将依赖于所有前面的并行构建。

以下示例阐述了一个典型的编译和部署应用程序的流程:

project { buildType(Compile) buildType(Test1) buildType(Test2) buildType(Package) buildType(Deploy) buildType(Extra) ... sequential { buildType(Compile) parallel (options = { onDependencyFailure = FailureAction.CANCEL }) { // non-default snapshot dependency options dependsOn(Extra) // extra dependency to be defined in all builds in the parallel block buildType(Test1) buildType(Test2) } buildType(Package) buildType(Deploy) } }

如果您以管道风格定义构建链,请确保在所引用的构建配置中没有定义明确的快照依赖。

在上述示例中,构建链引用了已声明的构建。 或者,您可以在链声明后使用简化语法注册所有列出的构建:

project { // build chain definition: val buildChain = sequential { ... } // register all build configurations, referenced in the chain, in the current project: buildChain.buildTypes().forEach { buildType(it) } }

明确的快照依赖性可以通过在 并行顺序的 块中的 依赖于() 语句来定义,带有一个可选的 lambda 参数,允许设置依赖性选项。 可以通过任何块的 选项 lambda 参数设定隐式快照依赖项的非默认选项值。

设置验证

使用 DSL API 版本 v2017_2+ 的设置会在 TeamCity 服务器上的 DSL 执行期间进行验证。 您还可以通过 生成 XML 配置文件生成 任务,在本地进行验证。

验证确保必填属性都已指定,例如像这样的构建步骤:

buildType { ... steps { exec { } } ... }

将产生一个验证错误,表示未指定强制性的 path 属性。 这类似于您在用户界面中创建新的构建步骤时,TeamCity 执行的检查。

您也可以以适合您的设置的方式扩展验证。 为了做到这一点,您需要重写 验证() 方法。 例如,以下类为 Git VCS 根添加了自定义验证:

open class MyGit() : GitVcsRoot() { constructor(init: MyGit.() -> Unit): this() { init() } override fun validate(consumer: ErrorConsumer) { super.validate(consumer) //perform basic validation url?.let { if (it.startsWith("git://") || it.startsWith("http://")) { consumer.consumePropertyError("url", "Insecure protocol, please use https or ssh instead") } } authMethod?.let { if (it is AuthMethod.CustomPrivateKey || it is AuthMethod.DefaultPrivateKey) { consumer.consumePropertyError("authMethod", "Prohibited authentication method, please use 'uploadedKey' instead") } } } }

使用外部库的能力

您可以在您的 Kotlin DSL 代码中使用外部库,这样可以在不同的基于 Kotlin DSL 的项目之间分享代码。

要在您的 Kotlin DSL 代码中使用外部库,需要在设置仓库的 .teamcity/pom.xml 文件中添加对此库的依赖,并提交此更改,以便 TeamCity 能够检测到它。 然后,在开始生成过程之前,TeamCity 服务器将从 Maven 仓库获取必要的依赖项,用它们编译代码,然后启动设置的生成器。

您可以在私有仓库中建立对外部库的访问。 为此,请在 Maven 设置文件mavenSettingsDsl.xml )中指定所有必需的凭据,并将其上传到 Root 项目的 Maven 设置 页面。

非便携式 DSL

在 2018.1 之前的 TeamCity 版本中,Kotlin DSL 设置使用的是不同的格式。 如果您导入这种过时的非便携式格式的项目,TeamCity 将允许您使用它。 在这种情况下,Generate portable DSL scripts 选项将变为可用。

当 TeamCity 生成一种非便携式的 DSL 时, .teamcity 目录中的项目结构如下:

  • pom.xml

  • <项目 id>/settings.kts

  • <项目 id>/Project.kt

  • <项目 id>/buildTypes/<构建配置 id>.kt

  • <项目 id>/vcsRoots/<vcs 根 id>.kt

其中 <project id> 是启用版本设置的项目的 ID。 产生构建配置和 VCS 根的 Kotlin DSL 文件放在相应的子目录下。

settings.kts

在非便携格式中,每个项目都有以下 settings.kts 文件:

package MyProject import jetbrains.buildServer.configs.kotlin.* /* ... */ version = "2024.03" project(MyProjectId.Project)

这是项目设置生成的入口点。 基本上,它代表一个 Project 实例,该实例生成项目设置。

Project.kt

Project.kt 文件如下所示:

package MyPackage import jetbrains.buildServer.configs.kotlin.* import jetbrains.buildServer.configs.kotlin.Project object Project : Project({ uuid = "05acd964-b90f-4493-aa09-c2229f8c76c0" id("MyProjectId") parentId("MyParent") name = "My project" ... })

where:

  • iD 是项目的绝对 ID,如果您导航到此项目,将在浏览器地址栏中看到相同的 ID。

  • parentId 是此项目所附属的父项目的绝对ID

  • uuid 是一些独特的字符序列。
    uuid 是一个独特的标识符,它将项目、构建配置或 VCS 根与其数据关联起来。 如果 uuid 被更改,那么数据将会丢失。 恢复数据的唯一方式是将 uuid 恢复到原始值。 另一方面,如果 uuid 保持不变,一个实体的 iD 可以自由更改。 这是非便携式 DSL 格式与便携式格式的主要区别。 便携式格式无需指定 uuid ,但如果构建配置失去了其历史记录(例如,在更改构建配置外部 id 时),您可以使用附加构建历史选项,从操作菜单中,将历史重新附加到构建配置。 查看 详情

在非便携式 DSL 的情况下,补丁会存储在项目的 patches 目录下的 .teamcity

<project id>/patches/projects/<uuid>.kts <project id>/patches/buildTypes/<uuid>.kts <project id>/patches/templates/<uuid>.kts <project id>/patches/vcsRoots/<uuid>.kts

使用补丁的方法与在便携式 DSL 中一样:您需要将实际设置从补丁移至您的脚本中,并移除该补丁。

在 DSL 中处理安全值

总的来说,TeamCity 将 DSL 参数处理为字符串。 为了将 DSL 值标记为安全,您可以将其分配给 密码 类型的参数:

params { password("<parameter_name>", "credentialsJSON:<token>") }

在这里, <parameter_name> 是一个独特的名称,可以作为使用 DSL(例如,在 文件内容替换器 构建功能中)访问安全值的键; <token> 是对应目标安全值的代币。

示例:

params { password("pass-to-bucket", "credentialsJSON:12a3b456-c7de-890f-123g-4hi567890123") }

常见问题与常见问题解答

为什么便携式 DSL 需要对所有 ID 使用相同的前缀?

模板、构建配置以及 VCS 根都在服务器上的所有 TeamCity 项目中都有 唯一的 ID。 这些 ID 通常看起来像这样: <父项目 id>_<实体 id>

由于这些 ID 必须是唯一的,因此系统中不能存在两个具有相同 ID 的不同实体。

然而,可移植 DSL 被称为可移植的原因之一是因为相同的 settings.kts 脚本甚至可以在同一服务器上为两个不同的项目生成设置。
为了在克服 ID 的唯一性的同时达到这个目标,TeamCity 在可移植 DSL 脚本中使用相对 ID。 这些相对 ID 中并未包含父项目 ID 前缀。 所以,当 TeamCity 生成可移植的 Kotlin DSL 脚本时,它必须从所有生成的实体的 ID 中移除父项目的 ID 前缀。

但是,如果并非所有项目实体的 ID 都包含此前缀,此方法将无法正常工作。 在这种情况下,可能会显示以下错误:

构建配置 id '<some id>' 应该有一个与其父项目 id : '<parent project id>' 相对应的前缀

为了解决这个问题,更改受影响实体的 ID。 如果有许多此类 ID,使用 批量编辑 ID 项目操作一次性全部修改。

如何从 DSL 设置中访问辅助脚本

为了保持您的设置文件整洁,将冗长的代码指令存储在单独的文件中是便利的。 此类辅助脚本可以与设置文件一同放在 .teamcity 目录中。 您可以通过它们的相对路径来引用它们。

例如,这部分的 settings.kts 创建了一个带有功能的对象 readScript ,该功能读取它接收到的文件的内容:

object Util { fun readScript(path: String): String { val bufferedReader: BufferedReader = File(path).bufferedReader() return bufferedReader.use{ it.readText() }.trimIndent() } }

在构建步骤中,我们调用了这个函数,所以它读取了位于 .teamcity 目录下的 scripts\test.sh 文件:

object CommandLineRunnerTest : BuildType({ name = "Command Line Runner Test" steps { script { name = "Imported from a file" scriptContent = Util.readScript("scripts\\test.sh") } } })

因此,您的 Command Line 构建步骤将运行一个在 scripts\test.sh 中指定的自定义脚本。

如何使用特殊字符

当编写用于脚本运行器(命令行PowerShellPython 等)的 Kotlin DSL 时,需注意脚本中使用的特殊字符可能与 Kotlin DSL 语法发生冲突。 这些潜在问题大多数通常属于以下任何一个类别:

  • 根据 Kotlin 指南 的要求,没有逃避特殊字符。 例如, echo $(date +"%A") Shell 命令并不与 Kotlin 语法规则冲突,可以直接在 Kotlin DSL 中使用:

    script { id = "simpleRunner" scriptContent = """ #... echo $(date +"%A") """.trimIndent() }

    然而,如果不进行转义,直接变量引用将导致"Kotlin DSL 编译错误:无法解析的引用"的构建日志消息。

    script { id = "simpleRunner" scriptContent = """ day_of_week=Monday echo $day_of_week // Compilation error echo ${'$'}day_of_week // No compilation error, returns "Monday" """.trimIndent() }
  • 不转义 % 字符。 TeamCity 可能会将此类未转义的字符串解读为对 构建参数 的引用。 要转义百分号字符,需要重复两次( %%)。

    例如,如果您将双百分号字符( %%regex%% )替换为单一的( % \regex % ),以下的 Kotlin DSL 将生成一个没有兼容代理的配置:

    script { name = "Bash script" scriptContent = """ //... set "regex=[0-9]+[.][0-9][0-9](.1)? EAP" set "items=" for /r "$tcInstallDir" %%i in (*) do ( findstr /r "%%regex%%" "%%i" >nul 2>nul if errorlevel 1 ( set "items=1" ) ) //... """ }

设置 VCS 根的新 URL (非便携式格式)

问题:我更改了在 Kotlin 中存储设置的 VCS 根的 URL,现在 TeamCity 无法在新位置的仓库中找到任何设置。

解决方案

  • 在版本控制中修复 Kotlin DSL 的 URL,并推送修复。

  • 禁用版本设置以启用用户界面。

  • 在 UI 中修复 VCS 根目录中的 URL。

  • 启用版本设置,并再次使用相同的 VCS 根目录和 Kotlin 格式。 TeamCity 将检测到存储库中包含 .teamcity 目录,并询问您是否要导入设置。

  • 选择导入设置。

如何在 Kotlin DSL 中读取文件

问题:我希望根据存储在 VCS 内的 .teamcity 目录中的某个文件中的数据生成 TeamCity 构建配置。

解决方案
您可以使用 DslContext.baseDir 属性从 DSL 脚本访问 .teamcity 目录的位置,例如:

val dataFile = File(DslContext.baseDir, "data/setup.xml")

自2019.2开始,这已成为首选方法,因为 TeamCity 不再保证 DSL 脚本的当前工作目录与 .teamcity 目录相同。

在 2019.2 之前,可以使用以下代码:

val dataFile = File("data/setup.xml")

如何重新排序项目和构建配置

要通过 DSL 在项目内重新排序子项目或构建配置,类似于 相应的 UI 选项 ,将它们的列表传递给 subProjectsOrderbuildTypesOrder。 例如,

project { buildType(BuildA) buildType(BuildB) buildType(BuildC) buildTypesOrder = arrayListOf(BuildC, BuildA, BuildB) } object BuildA: buildType ({ ... }) object BuildB: buildType ({ ... }) object BuildC: buildType ({ ... })

根据这些设置,构建配置将按照以下顺序在用户界面中显示:C ,A ,B。

如何拆分 .kts 文件

描述服务器上所有项目设置的单个 .kts 文件可能难以维护。 您可能会在两种情况下结束此类文件:

  • 该文件由 TeamCity 生成。 当您通过 操作 | 以 Kotlin 格式下载设置... 菜单导出项目设置时,TeamCity 首先会计算您当前拥有多少实体(项目,配置,根)。 如果此数字小于20,TeamCity 会写入一个 .kts 文件。 否则,它会为每个项目生成包含单独 .kt 文件的多个文件夹。

  • 该文件是手动创建的。 如果您从一个 .kts 文件开始,并不断向其添加新的项目,那么随着时间的推移,这个文件可能会变得过于庞大,难以管理。

在第一种情况下,一旦您的构建服务器超过20个实体,TeamCity 会自动分割其设置。 对于手动创建的 .kts 文件,您可以按照以下方式进行分割:

.teamcity └─── pom.xml └─── settings.kts # Stores only the Kotlin DSL version and the "project(_Self.Project)" line └─── _Self └─── ... └─── ... └─── ProjectA └─── ... └─── ... └─── ProjectA_Subproject1 └─── ... └─── ... └─── ProjectA_Subproject2 └─── ... └─── ... └─── ProjectB └─── ... └─── ... └───... └───...

每个文件夹(包括 <Root> 项目的 "_Self" 文件夹)都具有以下结构:

ProjectA └─── Project.kt # Stores a list of subprojects, parameters, connections, and other project-level settings └─── buildTypes # A folder with .kt files that define build configurations, their steps, triggers, build features, and more └─── ProjectA_MyBuildConfig1.kt └─── ProjectA_MyBuildConfig2.kt └─── vcsRoots # A folder with .kt files that define VCS roots (for example, custom GitVcsRoot class descendants) └─── ProjectA_MyRoot1.kt └─── ProjectA_MyRoot2.kt

您可以下载附在 TW-64768 工单上的 ZIP 压缩包,以查看样本的层次结构,并了解单个 .kt 文件通常储存什么内容。

如何测试 Kotlin DSL 脚本

Kotlin 脚本可以使用如 JUnit 这样的常规测试框架进行测试。 请参阅此博客文章以获取更多信息:代码化配置,第6部分:测试配置脚本

Kotlin DSL API 文档尚未初始化

问题

  • 在我们的 Teamcity 服务器上显示 "Kotlin DSL API 文档尚未初始化"

  • 在 TeamCity 启动时,堆栈跟踪中出现 org.jetbrains.dokka

解决方案:设置内部属性 teamcity.kotlinConfigsDsl.docsGenerationXmx=1500m ,然后重启服务器。

内存溢出 错误

问题:同步 Kotlin DSL 设置失败,"编译错误:java.lang.OutOfMemoryError:Java 堆空间" 错误写入 teamcity-versioned-settings.log 文件。

解决方案:将 teamcity.versionedSettings.configsGeneratorXmx 内部属性设定为 1g (一千兆字节)或更多,然后重新启动服务器。 默认属性值为 512m

最后修改日期: 16日 7月 2024年