GitHub Actions se tornou a ferramenta de CI/CD mais popular para projetos open source e comerciais. Para projetos Kotlin, a integração e poderosa e permite automatizar desde testes simples até pipelines completos de deploy. Neste guia, vamos construir workflows reais para projetos Kotlin.
Por Que GitHub Actions para Kotlin
GitHub Actions oferece vantagens específicas para projetos Kotlin:
- Integração nativa com repositórios GitHub
- Runners gratuitos para projetos open source
- Cache de dependências Gradle nativo
- Marketplace com milhares de actions prontas
- Suporte a matrix builds para testar em múltiplas versões de JDK
Workflow Básico para Kotlin Backend
Vamos começar com um workflow para um projeto Spring Boot com Kotlin:
// O workflow YAML fica em .github/workflows/ci.yml
// Aqui vamos focar na configuracao do projeto Kotlin
// build.gradle.kts otimizado para CI
plugins {
kotlin("jvm") version "2.1.0"
kotlin("plugin.spring") version "2.1.0"
id("org.springframework.boot") version "3.3.0"
id("io.spring.dependency-management") version "1.1.4"
id("org.jetbrains.kotlinx.kover") version "0.7.5"
id("io.gitlab.arturbosch.detekt") version "1.23.4"
}
tasks.withType<Test> {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
showStandardStreams = true
}
// Gerar relatorios para CI
reports {
junitXml.required.set(true)
html.required.set(true)
}
}
// Configuração kover para relatorio de cobertura
koverReport {
defaults {
xml { onCheck = true }
html { onCheck = true }
}
}
O workflow GitHub Actions correspondente inclui etapas de checkout, setup JDK, cache Gradle, execução de testes e upload de relatorios. A configuração permite rodar em pushes para main e em pull requests.
Cache Eficiente de Gradle
O cache de dependências Gradle e crítico para performance do CI:
// gradle.properties - Otimizações para CI
org.gradle.caching=true
org.gradle.parallel=true
org.gradle.daemon=false
org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC
kotlin.incremental=true
GitHub Actions tem uma action oficial para cache de Gradle que armazena:
- Dependências baixadas (~/.gradle/caches)
- Wrapper do Gradle (~/.gradle/wrapper)
- Build cache (.gradle/build-cache)
Isso pode reduzir o tempo de build de 5-10 minutos para 1-2 minutos em builds subsequentes.
Workflow para Projeto Android
Projetos Android com Kotlin tem necessidades específicas:
// build.gradle.kts (modulo app) - Configuração para CI
android {
compileSdk = 34
defaultConfig {
minSdk = 24
targetSdk = 34
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
lint {
abortOnError = true
xmlReport = true
htmlReport = true
}
testOptions {
unitTests {
isIncludeAndroidResources = true
all {
it.useJUnitPlatform()
}
}
}
}
O workflow Android inclui:
- Setup do JDK e Android SDK
- Execução de lint
- Testes unitarios
- Build do APK/AAB
- Opcionalmente, testes instrumentados com emulador
Testes Instrumentados no CI
Para rodar testes instrumentados, você pode usar emuladores no GitHub Actions:
// Teste instrumentado com Compose
@HiltAndroidTest
class LoginScreenTest {
@get:Rule(order = 0)
val hiltRule = HiltAndroidRule(this)
@get:Rule(order = 1)
val composeRule = createAndroidComposeRule<MainActivity>()
@Test
fun loginComCredenciaisValidas_deveNavegar() {
composeRule.apply {
onNodeWithTag("email_field")
.performTextInput("user@test.com")
onNodeWithTag("password_field")
.performTextInput("senha123")
onNodeWithTag("login_button")
.performClick()
waitForIdle()
onNodeWithTag("home_screen")
.assertIsDisplayed()
}
}
}
Automacoes Avançadas
Publicacao Automatica de Releases
Quando você cria uma tag, o workflow pode automaticamente:
// build.gradle.kts - Versão baseada em tags
val gitTag = System.getenv("GITHUB_REF_NAME") ?: "dev"
version = if (gitTag.startsWith("v")) {
gitTag.removePrefix("v")
} else {
"0.0.0-SNAPSHOT"
}
// Publicacao no Maven Central
publishing {
publications {
create<MavenPublication>("maven") {
from(components["java"])
groupId = "com.example"
artifactId = "minha-biblioteca"
}
}
}
Deploy Automatico para Cloud
Workflows podem fazer deploy para diferentes provedores de cloud:
// Exemplo de configuracao para deploy em produtao
// Aplicação Kotlin com Spring Boot
@Configuration
@Profile("production")
class ProductionConfig {
@Bean
fun corsConfig(): WebMvcConfigurer {
return object : WebMvcConfigurer {
override fun addCorsMappings(registry: CorsRegistry) {
registry.addMapping("/api/**")
.allowedOrigins("https://meusite.com.br")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowCredentials(true)
}
}
}
}
// Health check para validação pos-deploy
@RestController
class HealthController(
private val dataSource: DataSource
) {
@GetMapping("/health")
fun health(): Map<String, Any> {
val dbHealthy = try {
dataSource.connection.use { it.isValid(5) }
} catch (e: Exception) {
false
}
return mapOf(
"status" to if (dbHealthy) "UP" else "DOWN",
"version" to (System.getenv("APP_VERSION") ?: "unknown"),
"timestamp" to Instant.now().toString(),
"checks" to mapOf(
"database" to if (dbHealthy) "UP" else "DOWN"
)
)
}
}
Dependabot para atualizações
Configure Dependabot para manter dependências atualizadas. A configuração monitora atualizações de dependências Gradle e GitHub Actions semanalmente, agrupando-as por tipo.
Workflow para Kotlin Multiplatform
Projetos KMP precisam de configuração específica:
// build.gradle.kts para KMP
kotlin {
androidTarget()
iosX64()
iosArm64()
iosSimulatorArm64()
jvm()
sourceSets {
commonMain.dependencies {
implementation("io.ktor:ktor-client-core:3.0.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.0")
}
commonTest.dependencies {
implementation(kotlin("test"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")
}
}
}
O workflow KMP roda testes em múltiplas plataformas: JVM tests no Linux, iOS tests no macOS e Android tests no Linux.
Matrix Builds
Teste seu projeto Kotlin em múltiplas versões de JDK:
// Código que pode se comportar diferente entre JDKs
// Importante testar com matrix build
class DateTimeService {
fun formatarData(instant: Instant): String {
val formatter = DateTimeFormatter
.ofPattern("dd/MM/yyyy HH:mm")
.withZone(ZoneId.of("America/Sao_Paulo"))
return formatter.format(instant)
}
fun parsearData(texto: String): Instant {
val formatter = DateTimeFormatter
.ofPattern("dd/MM/yyyy HH:mm")
.withZone(ZoneId.of("America/Sao_Paulo"))
return Instant.from(formatter.parse(texto))
}
}
Uma strategy matrix com JDK 17, 21 e 23 garante compatibilidade.
Notificacoes e Badges
Configure notificacoes para falhas de pipeline:
- Slack: Actions para enviar notificacoes em canais de time
- Email: Notificacoes nativas do GitHub
- Badge no README: Mostra o status do build no repositório
Segurança no CI
Proteção de Segredos
// NUNCA coloque segredos no codigo
// Use GitHub Secrets e acesse via variaveis de ambiente
@Configuration
class ExternalServiceConfig(
@Value("\${API_KEY:default}") private val apiKey: String,
@Value("\${API_SECRET:default}") private val apiSecret: String
) {
@Bean
fun externalClient(): ExternalClient {
return ExternalClient.builder()
.apiKey(apiKey)
.apiSecret(apiSecret)
.build()
}
}
Scanning de Vulnerabilidades
GitHub oferece Dependabot alerts e code scanning que identificam vulnerabilidades em dependências e no código. Habilite essas features para manter seu projeto seguro.
Otimização de Performance do CI
Dicas para pipelines mais rápidos:
- Use cache agressivamente: Gradle, dependências Maven, imagens Docker
- Paralelismo: Execute jobs independentes em paralelo
- Skip desnecessário: Nao rode testes Android se só mudou código backend
- Runners self-hosted: Para projetos com muitos builds, considere runners próprios
Conclusão
GitHub Actions e uma ferramenta poderosa e flexivel para automatizar projetos Kotlin. De testes simples a pipelines complexos de deploy, a plataforma oferece tudo que você precisa para manter a qualidade e a velocidade de entrega.
Comece com um workflow básico de build e testes, e evolua gradualmente adicionando análise estática, cobertura de código, deploys automaticos e notificacoes. GitHub Actions funciona igualmente bem para projetos em Go, Python e Rust, então o conhecimento que você ganha aqui se transfere facilmente. A automação e um investimento que se paga exponencialmente ao longo do tempo, e GitHub Actions torna esse investimento acessivel para projetos de qualquer tamanho.