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(" ") } }