A library that extends the TeamCity Kotlin DSL providing a pipeline type, stages, a matrix build type and a number of convenience functions.
To use the library add the following dependency to the Maven POM in the .teamcity
directory.
<dependency>
<groupId>com.github.rodm</groupId>
<artifactId>teamcity-dsl-extensions</artifactId>
<version>0.9</version>
<scope>compile</scope>
</dependency>
Import the pipeline
function
import com.github.rodm.teamcity.pipeline
Use the DSL method to create a pipeline with one or more stages, and each stage with one or more build configurations.
The example below shows the creation of a build template and a pipeline with 2 stages. The first stage defines default settings for each of the following build configurations. Each stage is represented in TeamCity as a composite build configuration with dependencies on each build configuration defined in the stage. Build configurations in subsequent stages have a dependency on the previous stage build configuration.
import com.github.rodm.teamcity.pipeline
project {
val buildTemplate = gradleBuildTemplate {
id("GradleBuild")
name = "Gradle Build"
...
}
pipeline {
stage("Stage 1") {
defaults {
failureConditions {
executionTimeoutMin = 10
}
}
build {
templates(buildTemplate)
id("Build1")
name = "Build 1"
}
build {
templates(buildTemplate)
id("Build2")
name = "Build 2"
}
}
stage("Stage 2") {
deploy {
templates(buildTemplate)
id("ExamplePublish")
name = "Publish"
}
}
}
}
The VCS root settings for a stage build configuration can be changed from the default settings using the vcs
configuration block.
stage("Stage") {
vcs {
showDependenciesChanges = false
excludeDefaultBranchChanges = true
buildDefaultBranch = false
}
}
The deploy
configuration creates a build configuration with the Deployment
type with personal builds disallowed
and a maximum number of running builds set to 1.
Stages can have an optional description
stage("Stage") {
description = "Build the library"
...
}
The default dependency for a stage can be overridden by using the dependsOn
function. A stage can depend on one or
more earlier stages.
import com.github.rodm.teamcity.pipeline
project {
pipeline {
val stage1 = stage("Stage 1") {
...
}
stage("Stage 2") {
...
}
stage("Stage 3") {
dependsOn (stage1)
...
}
}
}
The above can also be written using the stage(name: String)
extension function to lookup a previous stage by name.
import com.github.rodm.teamcity.pipeline
project {
pipeline {
stage("Stage 1") {
...
}
stage("Stage 2") {
...
}
stage("Stage 3") {
dependsOn (stage("Stage 1")
...
}
}
}
Templates can be defined within a stage and the template(name: String)
extension function can be used to lookup
a template when configuring a build
or deploy
build configuration.
Multiple build configurations can be defined using the matrix
configuration block.
pipeline {
stage("Stage1") {
matrix {
axes {
"OS"("Linux", "Windows", "Mac OS X")
"JDK"("JDK_18", "JDK_11")
}
build {
name = "Build - ${axes["OS"]} - ${axes["JDK"]}"
val os = axes["OS"] as String
requirements {
matches("os.name", os)
}
val jdk = axes["JDK"] as String
params {
param("java.home", "%${jdk}%")
}
}
}
}
}
The matrix
configuration block contains an axes
block that defines one or more axes followed by a build
configuration block that can use values from the defined axes. A build configuration is created for each combination
of values defined when multiple axes are defined. An axes
defines a name, in the above example OS
and JDK
, with
a number of values, from the above example Linux
, Windows
and Mac OS X
for OS
and JDK_18
and JDK_11
for
JDK
. The example will create 6 build configurations, one for each combination of OS
and JDK
.
If not all the combinations defined by the matrix axes are required, combinations can be removed by using the
excludes
block. Each exclusion is a map of name and value pairs, if a build configuration matches the
values defined by the exclusion it is removed.
The example below will create 4 build configurations, the combination of Windows
and JDK_18
and the combination
of Mac OS X
and JDK_11
are removed.
pipeline {
stage ("Stage1") {
matrix {
axes {
"OS"("Linux", "Windows", "Mac OS X")
"JDK"("JDK_18", "JDK_11")
}
excludes {
exclude("OS" to "Windows", "JDK" to "JDK_18")
exclude("OS" to "Mac OS X", "JDK" to "JDK_11")
}
build {
name = "Build - ${axes["OS"]} - ${axes["JDK"]}"
...
}
}
}
}
Artifacts can be defined using the Artifact
type. The producerRules
and consumerRules
patterns define the
paths of build output artifacts collected from a producing build and the paths the artifacts are written to for
a consuming build. More on the patterns can be found in TeamCity documentation,
Artifact Paths and Artifact Dependency.
val artifact = Artifact("producerRules", "consumerRules")
The Artifact
is passed to the build that produces the artifact using the produces
extension function and
passed to the build that uses the artifact using the consumes
extension function.
pipeline {
val artifact = Artifact("producerRules", "consumerRules")
stage("Stage1") {
build {
name = "Build1"
produces(artifact)
}
build {
name = "Build2"
consumes(artifact)
}
}
}
Configuring a GitHub issue tracker can be defined using the githubIssueTracker
function
import com.github.rodm.teamcity.project.githubIssueTracker
project {
features {
githubIssueTracker {
displayName = "TeamCityDSLExtensions"
repository = "https://github.com/rodm/teamcity-dsl-extensions"
pattern = """#(\d+)"""
}
}
}
The library is available under the Apache License, Version 2.0.