CI/CD для Java проектов: GitHub Actions от А до Я

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Почему CI/CD — стандарт современной Java-разработки

В мире Java-разработки скорость и качество поставки кода критичны. Каждый день команды вносят сотни изменений, и без автоматизации процесс интеграции превращается в хаос. CI/CD (Continuous Integration / Continuous Deployment) решает эту проблему: код автоматически собирается, тестируется и разворачивается на серверах.

Инструмент GitHub Actions — встроенное решение для CI/CD прямо в репозитории. Он позволяет создавать пайплайны (workflows) на YAML, которые реагируют на push, pull request или другие события. В этой статье мы разберём полный цикл настройки CI/CD для Java-проекта: от базового билда до деплоя в облако.

Вы узнаете, как ускорить разработку, избежать ошибок и автоматизировать рутину. Поехали!

1. Основы GitHub Actions: структура workflow

Что такое GitHub Actions?

GitHub Actions — это платформа для автоматизации рабочих процессов. Workflow (рабочий процесс) — это набор шагов, которые выполняются при наступлении события (например, push в ветку main). Каждый workflow состоит из:

  • Event — триггер (push, pull_request, schedule).
  • Jobs — задачи, которые выполняются на виртуальных машинах (runner).
  • Steps — конкретные действия (запуск скрипта, установка зависимостей).

Для Java-проекта типичный workflow включает: загрузку кода, установку JDK, сборку Maven/Gradle, запуск тестов и публикацию артефактов.

Создание первого workflow для Java

Создайте в корне репозитория папку .github/workflows/ и файл ci.yml. Вот минимальный пример для Maven-проекта:

name: Java CI with Maven

on:
  push:
    branches: [ main ]
  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 Maven
      run: mvn clean compile
    - name: Run tests
      run: mvn test

Этот workflow запускается при push или pull request в main. Он проверяет, что код компилируется и тесты проходят. Если тест падает — workflow завершается ошибкой, и вы получаете уведомление.

2. Продвинутая настройка: кэширование, матрицы и артефакты

Кэширование зависимостей

Maven и Gradle каждый раз скачивают зависимости заново — это медленно. GitHub Actions поддерживает кэширование. Добавьте шаг с actions/cache:

- name: Cache Maven packages
  uses: actions/cache@v4
  with:
    path: ~/.m2/repository
    key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
    restore-keys: |
      ${{ runner.os }}-maven-

Ключ кэша основан на хеше pom.xml. Если файл не менялся — зависимости восстанавливаются из кэша, время сборки сокращается в 2-3 раза.

Матрица сборок (Matrix Build)

Java-проекты часто тестируют на нескольких версиях JDK и ОС. Используйте стратегию matrix:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        java: [11, 17, 21]
    steps:
    - uses: actions/checkout@v4
    - name: Set up JDK ${{ matrix.java }}
      uses: actions/setup-java@v4
      with:
        java-version: ${{ matrix.java }}
        distribution: 'temurin'
    - name: Test with Maven
      run: mvn test

GitHub создаст 3 параллельных джоба — для Java 11, 17 и 21. Это гарантирует совместимость кода с разными версиями JDK.

Сохранение артефактов

После сборки JAR-файл можно сохранить как артефакт, чтобы скачать его вручную или использовать в следующем джобе:

- name: Upload JAR artifact
  uses: actions/upload-artifact@v4
  with:
    name: my-app-${{ github.sha }}
    path: target/*.jar

3. Автоматизация деплоя: от сборки до продакшена

Деплой на сервер через SSH

Допустим, у вас есть VPS. Добавьте секреты в репозиторий (Settings → Secrets → Actions): SSH_HOST, SSH_USER, SSH_KEY. Workflow для деплоя:

deploy:
  needs: build
  runs-on: ubuntu-latest
  if: github.ref == 'refs/heads/main'
  steps:
  - uses: actions/checkout@v4
  - name: Build JAR
    run: mvn package -DskipTests
  - name: Deploy to server
    uses: appleboy/scp-action@v0.1.7
    with:
      host: ${{ secrets.SSH_HOST }}
      username: ${{ secrets.SSH_USER }}
      key: ${{ secrets.SSH_KEY }}
      source: "target/*.jar"
      target: "/opt/myapp/"
  - name: Restart service
    uses: appleboy/ssh-action@v1.1.0
    with:
      host: ${{ secrets.SSH_HOST }}
      username: ${{ secrets.SSH_USER }}
      key: ${{ secrets.SSH_KEY }}
      script: |
        systemctl restart myapp

Этот workflow копирует JAR на сервер и перезапускает сервис. Важно: используйте needs: build, чтобы сначала пройти тесты.

Деплой в Docker Hub и на Kubernetes

Для контейнеризации добавьте шаг сборки Docker-образа и отправки в Docker Hub:

- name: Login to Docker Hub
  uses: docker/login-action@v3
  with:
    username: ${{ secrets.DOCKER_USERNAME }}
    password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker image
  uses: docker/build-push-action@v6
  with:
    push: true
    tags: myuser/myapp:${{ github.sha }}

Для Kubernetes используйте kubectl или Helm: обновите образ в deployment-файле и примените изменения.

4. Безопасность и лучшие практики

Секреты и переменные окружения

Никогда не хардк

Блоги

Рекомендаций по книгам