first commit
This commit is contained in:
commit
2fc95f8174
|
|
@ -0,0 +1,32 @@
|
|||
# Maven
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
# Gradle
|
||||
.gradle/
|
||||
build/
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
# IntelliJ IDEA
|
||||
.idea/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
out/
|
||||
|
||||
# VS Code
|
||||
.vscode/
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package examples
|
||||
|
||||
import templates.PhpDockerBuildTemplate
|
||||
|
||||
/**
|
||||
* Example: How to use PhpDockerBuildTemplate in your project
|
||||
*
|
||||
* In your project's .teamcity/settings.kts:
|
||||
*
|
||||
* ```kotlin
|
||||
* import jetbrains.buildServer.configs.kotlin.*
|
||||
* import templates.PhpDockerBuildTemplate
|
||||
*
|
||||
* version = "2024.07"
|
||||
*
|
||||
* project {
|
||||
* buildType(Build)
|
||||
* }
|
||||
*
|
||||
* object Build : PhpDockerBuildTemplate({
|
||||
* backendDir = "backend"
|
||||
* enableCs = true
|
||||
* enableAnalyse = true
|
||||
* composerAuth = """
|
||||
* {
|
||||
* "http-basic": {
|
||||
* "nexus.dot-dot.ru": {
|
||||
* "username": "%env.NEXUS_USER%",
|
||||
* "password": "%env.NEXUS_PASSWORD%"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* """.trimIndent()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
object ExamplePhpBuild : PhpDockerBuildTemplate({
|
||||
// Registry settings
|
||||
registry = "registry.dot-dot.ru"
|
||||
dockerRegistryId = "PROJECT_EXT_2"
|
||||
|
||||
// PHP settings
|
||||
backendDir = "backend"
|
||||
enableCs = true
|
||||
enableAnalyse = true
|
||||
|
||||
// Composer auth for private packages
|
||||
composerAuth = """
|
||||
{
|
||||
"http-basic": {
|
||||
"nexus.dot-dot.ru": {
|
||||
"username": "ddadmin",
|
||||
"password": "secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
// Docker settings
|
||||
dockerfile = "Dockerfile"
|
||||
tag = "%teamcity.build.branch%"
|
||||
nexusHost = "nexus.dot-dot.ru"
|
||||
nexusIp = "192.168.100.110"
|
||||
|
||||
// Gitea settings
|
||||
giteaUrl = "https://gitea.dot-dot.ru/api/v1"
|
||||
giteaTokenId = "credentialsJSON:gitea-token"
|
||||
|
||||
// Triggers
|
||||
enableVcsTrigger = true
|
||||
})
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package examples
|
||||
|
||||
import templates.DockerBuildTemplate
|
||||
|
||||
/**
|
||||
* Example: Simple Docker build without PHP-specific features
|
||||
*
|
||||
* Use this for non-PHP projects that just need Docker build + push
|
||||
*/
|
||||
object ExampleSimpleBuild : DockerBuildTemplate({
|
||||
registry = "registry.dot-dot.ru"
|
||||
dockerfile = "Dockerfile"
|
||||
tag = "%teamcity.build.branch%"
|
||||
buildArgs = "--pull"
|
||||
extraHosts = listOf("nexus.dot-dot.ru:192.168.100.110")
|
||||
dockerRegistryId = "PROJECT_EXT_2"
|
||||
giteaUrl = "https://gitea.dot-dot.ru/api/v1"
|
||||
enableVcsTrigger = true
|
||||
})
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>ru.dot-dot.ci</groupId>
|
||||
<artifactId>ci-templates</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<kotlin.version>1.9.10</kotlin.version>
|
||||
<teamcity.dsl.version>2024.07</teamcity.dsl.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jetbrains-all</id>
|
||||
<url>https://download.jetbrains.com/teamcity-repository</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>mavenCentral</id>
|
||||
<url>https://repo1.maven.org/maven2/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>jetbrains-all</id>
|
||||
<url>https://download.jetbrains.com/teamcity-repository</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.teamcity</groupId>
|
||||
<artifactId>configs-dsl-kotlin-latest</artifactId>
|
||||
<version>${teamcity.dsl.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.teamcity</groupId>
|
||||
<artifactId>configs-dsl-kotlin-plugins-latest</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<type>pom</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-script-runtime</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>.</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<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>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import jetbrains.buildServer.configs.kotlin.*
|
||||
|
||||
version = "2024.07"
|
||||
|
||||
project {
|
||||
description = "CI Templates - reusable TeamCity DSL configurations"
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
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.triggers.vcs
|
||||
|
||||
/**
|
||||
* Configuration for Docker build template
|
||||
*/
|
||||
open class DockerBuildConfig {
|
||||
/** Docker registry URL (without protocol) */
|
||||
var registry: String = "registry.dot-dot.ru"
|
||||
|
||||
/** Path to Dockerfile relative to repo root */
|
||||
var dockerfile: String = "Dockerfile"
|
||||
|
||||
/** Image tag expression, supports TeamCity parameters */
|
||||
var tag: String = "%teamcity.build.branch%"
|
||||
|
||||
/** Additional docker build arguments */
|
||||
var buildArgs: String = "--pull"
|
||||
|
||||
/** Docker registry connection ID in TeamCity */
|
||||
var dockerRegistryId: String = "PROJECT_EXT_2"
|
||||
|
||||
/** Extra hosts for docker build (host:ip format) */
|
||||
var extraHosts: List<String> = listOf()
|
||||
|
||||
/** Enable VCS trigger */
|
||||
var enableVcsTrigger: Boolean = true
|
||||
|
||||
/** Branch filter for VCS trigger (e.g., "+:*" for all branches, "+:refs/tags/*" for tags) */
|
||||
var branchFilter: String = ""
|
||||
|
||||
/** Enable trigger on tags */
|
||||
var triggerOnTags: Boolean = false
|
||||
|
||||
/** Gitea API URL for commit status */
|
||||
var giteaUrl: String = "https://gitea.dot-dot.ru/api/v1"
|
||||
|
||||
/** Gitea token credential ID */
|
||||
var giteaTokenId: String = "credentialsJSON:gitea-token"
|
||||
}
|
||||
|
||||
/**
|
||||
* Template for building and pushing Docker images
|
||||
*
|
||||
* Usage:
|
||||
* ```
|
||||
* object Build : DockerBuildTemplate({
|
||||
* registry = "registry.dot-dot.ru"
|
||||
* dockerfile = "Dockerfile"
|
||||
* extraHosts = listOf("nexus.dot-dot.ru:192.168.100.110")
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
open class DockerBuildTemplate(
|
||||
configure: DockerBuildConfig.() -> Unit = {}
|
||||
) : BuildType() {
|
||||
|
||||
protected val config = DockerBuildConfig().apply(configure)
|
||||
|
||||
init {
|
||||
name = "build"
|
||||
allowExternalStatus = true
|
||||
|
||||
steps {
|
||||
dockerCommand {
|
||||
name = "build image"
|
||||
id = "build_image"
|
||||
commandType = build {
|
||||
source = file {
|
||||
path = config.dockerfile
|
||||
}
|
||||
platform = DockerCommandStep.ImagePlatform.Linux
|
||||
namesAndTags = "${config.registry}/%env.TEAMCITY_PROJECT_NAME%:${config.tag}"
|
||||
commandArgs = buildDockerArgs()
|
||||
}
|
||||
}
|
||||
dockerCommand {
|
||||
name = "push to registry"
|
||||
id = "push_to_registry"
|
||||
commandType = push {
|
||||
namesAndTags = "${config.registry}/%env.TEAMCITY_PROJECT_NAME%:${config.tag}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.enableVcsTrigger) {
|
||||
triggers {
|
||||
vcs {
|
||||
// Build branch filter
|
||||
val filters = mutableListOf<String>()
|
||||
if (config.branchFilter.isNotEmpty()) {
|
||||
filters.add(config.branchFilter)
|
||||
}
|
||||
if (config.triggerOnTags) {
|
||||
filters.add("+:refs/tags/*")
|
||||
}
|
||||
if (filters.isNotEmpty()) {
|
||||
branchFilter = filters.joinToString("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
features {
|
||||
dockerRegistryConnections {
|
||||
loginToRegistry = on {
|
||||
dockerRegistryId = config.dockerRegistryId
|
||||
}
|
||||
}
|
||||
commitStatusPublisher {
|
||||
publisher = github {
|
||||
githubUrl = config.giteaUrl
|
||||
authType = personalToken {
|
||||
token = config.giteaTokenId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildDockerArgs(): String {
|
||||
val args = mutableListOf(config.buildArgs)
|
||||
config.extraHosts.forEach { host ->
|
||||
args.add("--add-host=$host")
|
||||
}
|
||||
return args.joinToString(" ")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
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(" ")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
# CI Templates
|
||||
|
||||
Переиспользуемые TeamCity DSL шаблоны для проектов dot-dot.ru.
|
||||
|
||||
## Подключение к проекту
|
||||
|
||||
### 1. Добавить зависимость в pom.xml вашего проекта
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>ru.dot-dot.ci</groupId>
|
||||
<artifactId>ci-templates</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### 2. Настроить Versioned Settings в TeamCity
|
||||
|
||||
В настройках проекта TeamCity → Versioned Settings:
|
||||
- Synchronization enabled: **Yes**
|
||||
- Project settings VCS root: выбрать VCS root вашего проекта
|
||||
- Settings format: **Kotlin**
|
||||
- Allow editing project settings via UI: по желанию
|
||||
|
||||
Добавить дополнительный VCS root для ci-templates:
|
||||
- VCS URL: `git@gitea.dot-dot.ru:dot-dot/ci-templates.git`
|
||||
- Checkout rules: `+:.teamcity => .teamcity/ci-templates`
|
||||
|
||||
## Доступные шаблоны
|
||||
|
||||
### DockerBuildTemplate
|
||||
|
||||
Базовый шаблон для сборки и публикации Docker образов.
|
||||
|
||||
```kotlin
|
||||
import templates.DockerBuildTemplate
|
||||
|
||||
object Build : DockerBuildTemplate({
|
||||
registry = "registry.dot-dot.ru"
|
||||
dockerfile = "Dockerfile"
|
||||
tag = "%teamcity.build.branch%"
|
||||
extraHosts = listOf("nexus.dot-dot.ru:192.168.100.110")
|
||||
})
|
||||
```
|
||||
|
||||
### PhpDockerBuildTemplate
|
||||
|
||||
Шаблон для PHP проектов с поддержкой Composer, линтеров и анализаторов.
|
||||
|
||||
```kotlin
|
||||
import templates.PhpDockerBuildTemplate
|
||||
|
||||
object Build : PhpDockerBuildTemplate({
|
||||
backendDir = "backend"
|
||||
enableCs = true
|
||||
enableAnalyse = true
|
||||
composerAuth = """{"http-basic": {"nexus.dot-dot.ru": {"username": "%env.NEXUS_USER%", "password": "%env.NEXUS_PASSWORD%"}}}"""
|
||||
})
|
||||
```
|
||||
|
||||
## Параметры
|
||||
|
||||
### DockerBuildConfig
|
||||
|
||||
| Параметр | По умолчанию | Описание |
|
||||
|----------|--------------|----------|
|
||||
| registry | registry.dot-dot.ru | Docker registry URL |
|
||||
| dockerfile | Dockerfile | Путь к Dockerfile |
|
||||
| tag | %teamcity.build.branch% | Тег образа |
|
||||
| buildArgs | --pull | Аргументы docker build |
|
||||
| dockerRegistryId | PROJECT_EXT_2 | ID подключения к registry в TeamCity |
|
||||
| extraHosts | [] | Дополнительные хосты (host:ip) |
|
||||
| enableVcsTrigger | true | Включить VCS триггер |
|
||||
| giteaUrl | https://gitea.dot-dot.ru/api/v1 | URL Gitea API |
|
||||
| giteaTokenId | credentialsJSON:gitea-token | ID токена Gitea |
|
||||
|
||||
### PhpDockerBuildConfig (наследует DockerBuildConfig)
|
||||
|
||||
| Параметр | По умолчанию | Описание |
|
||||
|----------|--------------|----------|
|
||||
| backendDir | backend | Директория с PHP кодом |
|
||||
| ciImage | null | CI образ для линтеров (по умолчанию {project}-ci:latest) |
|
||||
| enableCs | false | Включить проверку code style |
|
||||
| enableAnalyse | false | Включить статический анализ |
|
||||
| composerAuth | null | Содержимое auth.json |
|
||||
| nexusHost | nexus.dot-dot.ru | Хост Nexus |
|
||||
| nexusIp | 192.168.100.110 | IP Nexus для /etc/hosts |
|
||||
Loading…
Reference in New Issue