ci-templates/.teamcity/templates/PhpDockerBuildTemplate.kt

170 lines
5.6 KiB
Kotlin

package templates
import jetbrains.buildServer.configs.kotlin.*
import jetbrains.buildServer.configs.kotlin.buildFeatures.commitStatusPublisher
import jetbrains.buildServer.configs.kotlin.buildFeatures.dockerRegistryConnections
import jetbrains.buildServer.configs.kotlin.buildSteps.DockerCommandStep
import jetbrains.buildServer.configs.kotlin.buildSteps.dockerCommand
import jetbrains.buildServer.configs.kotlin.buildSteps.script
import jetbrains.buildServer.configs.kotlin.triggers.vcs
/**
* Configuration for PHP Docker build template
*/
open class PhpDockerBuildConfig : DockerBuildConfig() {
/** Path to backend directory */
var backendDir: String = "backend"
/** CI image for running linters/analysis */
var ciImage: String? = null
/** Enable composer code style check */
var enableCs: Boolean = false
/** Enable composer static analysis */
var enableAnalyse: Boolean = false
/** Composer auth.json content (for private packages) */
var composerAuth: String? = null
/** Nexus host for private packages */
var nexusHost: String = "nexus.dot-dot.ru"
/** Nexus IP for /etc/hosts */
var nexusIp: String = "192.168.100.110"
}
/**
* Template for PHP projects with Docker build
*
* Usage:
* ```
* object Build : PhpDockerBuildTemplate({
* backendDir = "backend"
* enableCs = true
* enableAnalyse = true
* composerAuth = """{"http-basic": {"nexus.dot-dot.ru": {"username": "user", "password": "pass"}}}"""
* extraHosts = listOf("nexus.dot-dot.ru:192.168.100.110")
* })
* ```
*/
open class PhpDockerBuildTemplate(
configure: PhpDockerBuildConfig.() -> Unit = {}
) : BuildType() {
protected val phpConfig = PhpDockerBuildConfig().apply(configure)
init {
name = "build"
allowExternalStatus = true
steps {
// Create auth.json if configured
phpConfig.composerAuth?.let { auth ->
script {
name = "create auth.json"
id = "create_auth_json"
scriptContent = """
echo '$auth' > ${phpConfig.backendDir}/auth.json
""".trimIndent()
}
}
// CI image for linting
val ciImg = phpConfig.ciImage ?: "${phpConfig.registry}/%env.TEAMCITY_PROJECT_NAME%-ci:latest"
val dockerRunArgs = buildDockerRunArgs()
// Code style check
if (phpConfig.enableCs) {
dockerCommand {
name = "composer cs"
id = "composer_cs"
commandType = other {
subCommand = "run"
commandArgs = """
$dockerRunArgs
-v %system.teamcity.build.workingDir%/${phpConfig.backendDir}:/application
-w /application $ciImg /usr/local/bin/composer cs
""".trimIndent()
}
}
}
// Static analysis
if (phpConfig.enableAnalyse) {
dockerCommand {
name = "composer analyse"
id = "composer_analyse"
commandType = other {
subCommand = "run"
commandArgs = """
$dockerRunArgs
-v %system.teamcity.build.workingDir%/${phpConfig.backendDir}:/application
-w /application $ciImg /usr/local/bin/composer analyse-ci
""".trimIndent()
}
}
}
// Build image
dockerCommand {
name = "build image"
id = "build_image"
commandType = build {
source = file {
path = phpConfig.dockerfile
}
platform = DockerCommandStep.ImagePlatform.Linux
namesAndTags = "${phpConfig.registry}/%env.TEAMCITY_PROJECT_NAME%:${phpConfig.tag}"
commandArgs = buildDockerBuildArgs()
}
}
// Push to registry
dockerCommand {
name = "push to registry"
id = "push_to_registry"
commandType = push {
namesAndTags = "${phpConfig.registry}/%env.TEAMCITY_PROJECT_NAME%:${phpConfig.tag}"
}
}
}
if (phpConfig.enableVcsTrigger) {
triggers {
vcs {}
}
}
features {
dockerRegistryConnections {
loginToRegistry = on {
dockerRegistryId = phpConfig.dockerRegistryId
}
}
commitStatusPublisher {
publisher = github {
githubUrl = phpConfig.giteaUrl
authType = personalToken {
token = phpConfig.giteaTokenId
}
}
}
}
}
private fun buildDockerRunArgs(): String {
val args = mutableListOf("--add-host=${phpConfig.nexusHost}:${phpConfig.nexusIp}", "-i", "--rm")
return args.joinToString(" ")
}
private fun buildDockerBuildArgs(): String {
val args = mutableListOf(phpConfig.buildArgs)
args.add("--add-host=${phpConfig.nexusHost}:${phpConfig.nexusIp}")
phpConfig.extraHosts.forEach { host ->
args.add("--add-host=$host")
}
return args.joinToString(" ")
}
}