如何根据 TeamCity Kotlin DSL 中的现有步骤创建自定义构建步骤?

How to create custom build step based on existing one in TeamCity Kotlin DSL?

我使用 TeamCity Kotlin DSL 2018.1 来设置构建配置。我的 settings.kts 文件如下所示:

version = "2018.1"

project {
    buildType {
        id("some-id")
        name = "name"
        steps {
            ant {
                name = "Step1"
                targets = "target1"
                mode = antFile { path = "/some/path" }
                workingDir = "/some/dir"
                jdkHome = "some_jdk"
            }
            ant {
                name = "Step2"
                targets = "target2"
                mode = antFile { path = "/some/path" }
                workingDir = "/some/dir"
                jdkHome = "some_jdk"
            }
            ...
        }
    }
}

它按预期工作,但我想避免为每个步骤一遍又一遍地编写相同的重复参数。

我尝试编写函数,它将构建预填充默认值的构建步骤:

fun customAnt(init: AntBuildStep.() -> kotlin.Unit): AntBuildStep {
    val ant_file = AntBuildStep.Mode.AntFile()
    ant_file.path = "/some/path"

    val ant = AntBuildStep()
    ant.mode = ant_file
    ant.workingDir = "/some/dir"
    ant.jdkHome = "some_jdk"
    return ant
}
project {
    buildType {
        id("some-id")
        name = "name"
        steps {
            customAnt {
                name = "Step1"
                targets = "target1"
            }
            customAnt {
                name = "Step2"
                targets = "target2"
            }
            ...
        }
    }
}

它编译但不起作用:TeamCity 只是忽略以这种方式定义的构建步骤。

遗憾的是,official documentation 不包含有关自定义和扩展 DSL 的任何信息。可能,我在 Kotlin 的 () -> Unit 构造上做错了,但无法找出到底出了什么问题。

我知道了。

实际上,我很接近。以下代码如我所愿:

version = "2018.1"

fun BuildSteps.customAnt(init: AntBuildStep.() -> Unit): AntBuildStep {
    val ant_file = AntBuildStep.Mode.AntFile()
    ant_file.path = "/some/path"

    val result = AntBuildStep(init)
    result.mode = ant_file
    result.workingDir = "/some/dir"
    result.jdkHome = "some_jdk"
    step(result)
    return result
}

project {    
    buildType {
        steps {
            customAnt {
                name = "step1"
                targets = "target1"
            }
            customAnt {
                name = "step2"
                targets = "target2"
            }
            ...
        }
    }
}