Введение в CI/CD для Kotlin с GitHub Actions
В современной разработке автоматизация процессов сборки, тестирования и развертывания стала неотъемлемой частью профессионального подхода. Для Kotlin-проектов, будь то Android-приложения, бэкенд-сервисы на Ktor или многоплатформенные библиотеки, настройка CI/CD (Continuous Integration / Continuous Deployment) позволяет значительно сократить время вывода продукта и снизить риск ошибок.
GitHub Actions — это мощный и гибкий инструмент, встроенный в экосистему GitHub. Он позволяет создавать кастомные пайплайны, которые автоматически запускаются при пушах, создании пулл-реквестов или по расписанию. В этой статье мы разберем полный цикл настройки CI/CD для Kotlin: от базовой проверки кода до автоматического деплоя.
Основы GitHub Actions: структура и синтаксис
Прежде чем погружаться в Kotlin-специфику, важно понять базовые концепции GitHub Actions. Пайплайн описывается в YAML-файлах, которые хранятся в директории .github/workflows/ вашего репозитория.
Ключевые элементы workflow
- Event (событие): триггер, запускающий пайплайн (push, pull_request, release и др.).
- Job (задача): набор шагов, выполняющихся на одном runner (виртуальной машине).
- Step (шаг): конкретное действие — выполнение команды, запуск скрипта или использование готового action.
- Runner: среда выполнения (Ubuntu, Windows, macOS).
Базовая структура файла kotlin-ci.yml:
name: Kotlin CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
run: ./gradlew build
Настройка CI для Kotlin: сборка, тесты и линтинг
Первый и самый важный этап — непрерывная интеграция. Она гарантирует, что каждый новый код проходит компиляцию и не ломает существующие тесты.
Кэширование зависимостей Gradle
Чтобы ускорить сборку, обязательно используйте кэширование. Без него каждый запуск будет заново скачивать все библиотеки.
- name: Cache Gradle packages
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
Запуск тестов и проверка стиля
Добавим шаги для запуска юнит-тестов и линтера (detekt или ktlint). Это поможет поддерживать качество кода.
- name: Run tests
run: ./gradlew test
- name: Run linter
run: ./gradlew detekt
Пример полного CI workflow для Kotlin-проекта
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Cache Gradle
uses: actions/cache@v3
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
- name: Build and test
run: ./gradlew check
Continuous Deployment: автоматический деплой Kotlin-приложений
После успешной интеграции наступает этап деплоя. Для Kotlin-проектов это может означать публикацию библиотеки в Maven Central, развертывание бэкенда на сервере или сборку APK для Android.
Деплой бэкенд-сервиса на Ktor
Допустим, у нас есть Kotlin-приложение на фреймворке Ktor. Мы хотим автоматически деплоить его на удаленный сервер через SSH после пуша в ветку main.
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build JAR
run: ./gradlew shadowJar
- name: Copy JAR to server
uses: appleboy/scp-action@v0.1.4
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: "build/libs/app.jar"
target: "/opt/myapp/"
- name: Restart service
uses: appleboy/ssh-action@v0.1.5
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
sudo systemctl restart myapp
Публикация библиотеки в GitHub Packages
Для внутренних библиотек удобно использовать GitHub Packages. Это простой способ делиться артефактами внутри команды.
- name: Publish to GitHub Packages
run: ./gradlew publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Оптимизация и best practices для Kotlin-пайплайнов
Чтобы ваш CI/CD работал быстро и надежно, следуйте нескольким простым рекомендациям.
Матричная сборка
Если ваш проект поддерживает несколько версий Kotlin или JDK, используйте матрицу стратегий. Это позволит параллельно тестировать все комбинации.
strategy:
matrix:
java: [ '11', '17', '21' ]
kotlin: [ '1.9.0', '2.0.0' ]
steps:
- uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
- name: Run tests
run: ./gradlew test -PkotlinVersion=${{ matrix.kotlin }}
Использование готовых actions
Не изобретайте велосипед. Для типовых задач (настройка JDK, кэширование, отправка уведомлений) используйте проверенные actions из GitHub Marketplace.
Безопасность секретов
Ни