Перейти к основному содержимому

Jenkins Pipeline — первый Jenkinsfile

Разработчику

Jenkins Pipeline — первый Jenkinsfile

CI/CD — автоматизация сборки и доставки: при каждом push в Git сервер собирает проект, запускает тесты и (опционально) выкатывает артефакт.

Jenkins — один из популярных CI-серверов. Сценарий сборки хранят в файле Jenkinsfile в корне репозитория — это Pipeline as Code: изменения проходят code review, как обычный код.

Синтаксис Pipeline — Groovy, но API другой, чем в Gradle DSL — здесь ключевые слова pipeline, stage, agent, а не dependencies и tasks.

Groovy в pipeline: основы § Jenkins · тесты: Spock · Java-сборка: Maven.


Что получится

При push Jenkins клонирует репозиторий, выполнит ./gradlew test, опубликует результаты JUnit. Вы поймёте каждый блок минимального Jenkinsfile.

./gradlew test

Разбор:

  • Фрагмент на bash показывает рабочий пример: начинается с ./gradlew test и задает контекст выполнения.
  • Ключевые операторы и выражения (def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера.
  • Основная логика выражена последовательностью инструкций, которые рантайм выполняет сверху вниз.
  • Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
  • Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.

Термины

ТерминПростыми словами
Job (задача)Настроенный пайплайн в Jenkins
Agent (агент)Машина/контейнер, где выполняются шаги
Stage (этап)Логический шаг: Checkout, Test, Deploy
StepОдна команда внутри stage (sh, echo)
Declarative pipelineСтруктурированный стиль pipeline { stages { } }
SCMSource Control — Git в нашем случае
MultibranchОтдельная сборка на каждую ветку с Jenkinsfile

Pipeline as Code и Freestyle

Freestyle job (UI)Pipeline as Code
Настройка кликами в браузереJenkinsfile в Git, ревью в PR
Сложно воспроизвести на другой веткеОдинаковый сценарий на feature и main
История изменений размытаИстория в Git blame

Для новых проектов команды обычно выбирают Pipeline или Multibranch Pipeline.


Минимальный Jenkinsfile

Положите в корень репозитория:

Код ITЗагрузка примера кода…

Разбор:

  • pipeline { } — корень Declarative Pipeline; Jenkins проверяет структуру до запуска агента.
  • agent any — job может выполниться на любом подключённом агенте с JDK и Git.
  • options { timestamps(); timeout(...) } — метки времени в логе и жёсткий лимит 20 минут на всю сборку.
  • stages — этапы Checkout (checkout scm — клон по настройкам job) и Build & Test (sh './gradlew test --no-daemon').
  • post { always { junit ... } } — после всех stage загружаются XML-отчёты тестов; success/failure — сообщения по итогу.

Разбор построчно

ФрагментСмысл
pipeline { }Корень declarative pipeline
agent anyЗапуск на любом подключённом агенте с JDK и Git
options { timestamps() }В логе — время каждой строки
timeout(... 20 ... MINUTES)Убить зависшую сборку через 20 минут
stage('Checkout')Этап 1: получить код
checkout scmGit clone по настройкам job (URL, ветка)
sh './gradlew test --no-daemon'Shell на Linux-агенте; --no-daemon — Gradle не оставляет фоновый процесс в CI
post { always { junit ... } }После всех stage — загрузить XML тестов в Jenkins
success / failureДействия при итоге сборки

Windows-агент: вместо sh используйте bat './gradlew.bat test --no-daemon'.


Maven вместо Gradle

stage('Build & Test') {
steps {
sh 'mvn -B test'
}
}

Разбор:

  • Фрагмент на groovy показывает рабочий пример: начинается с stage('Build & Test') { и задает контекст выполнения.
  • Ключевые операторы и выражения (def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера.
  • Вызовы функций или команд выполняют полезное действие: чтение данных, вычисление результата или запуск задачи сборки.
  • Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
  • Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.

В post путь к Surefire:

junit '**/target/surefire-reports/*.xml'

Разбор:

  • Фрагмент на groovy показывает рабочий пример: начинается с junit '**/target/surefire-reports/*.xml' и задает контекст выполнения.
  • Ключевые операторы и выражения (def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера.
  • Основная логика выражена последовательностью инструкций, которые рантайм выполняет сверху вниз.
  • Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
  • Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.

-B — batch mode Maven (меньше интерактива в логе).


Подключение в Jenkins

  1. New Item → имя → Pipeline (или Multibranch Pipeline).
  2. В настройках: Pipeline script from SCM.
  3. SCM: Git → URL репозитория, credentials при необходимости.
  4. Script Path: Jenkinsfile (по умолчанию в корне).
  5. SaveBuild Now.

Multibranch Pipeline сам находит ветки и Jenkinsfile на каждой; удобно для GitFlow и PR из fork (с политикой безопасности).

Первый запуск может упасть, если в репозитории нет gradlew — wrapper нужно закоммитить вместе с проектом.


Credentials (секреты)

Пароли, токены Docker Registry, ключи API не пишут в открытом виде в Jenkinsfile:

environment {
DOCKER_TOKEN = credentials('docker-hub-token-id')
}

Разбор:

  • Фрагмент на groovy показывает рабочий пример: начинается с environment { и задает контекст выполнения.
  • Ключевые операторы и выражения (def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера.
  • Вызовы функций или команд выполняют полезное действие: чтение данных, вычисление результата или запуск задачи сборки.
  • Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
  • Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
ШагДействие
Jenkins UIManage Jenkins → Credentials
ДобавитьSecret text или Username + password
IDСовпадает со строкой в credentials('...')
В pipelineПеременная DOCKER_TOKEN подставится при сборке

В логах Jenkins маскирует секреты, но случайный echo "${DOCKER_TOKEN}" в скрипте всё равно опасен — не печатайте секреты.

echo "${DOCKER_TOKEN}"

Разбор:

  • Фрагмент на bash показывает рабочий пример: начинается с echo "${DOCKER_TOKEN}" и задает контекст выполнения.
  • Ключевые операторы и выражения (def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера.
  • Основная логика выражена последовательностью инструкций, которые рантайм выполняет сверху вниз.
  • Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
  • Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.

Declarative и scripted

DeclarativeScripted (node { })
Жёсткая структура pipeline { stages { } }Произвольный Groovy-скрипт
Проще читать новичкамГибче, сложнее сопровождать
Внутри можно script { }Весь файл — код

Для старта — declarative. Сложную логику (циклы по модулям) иногда выносят в script { } внутри одного stage.

Пример declarative + Groovy:

stage('Matrix') {
steps {
script {
def branches = ['main', 'develop']
branches.each { b ->
echo "Checking branch ${b}"
}
}
}
}

Разбор:

  • Фрагмент на groovy показывает рабочий пример: начинается с stage('Matrix') { и задает контекст выполнения.
  • Ключевые операторы и выражения (def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера.
  • Вызовы методов и объявления функций задают основной шаг логики: входные значения передаются в метод и сразу обрабатываются.
  • Поток выполнения строится на итерации: код последовательно применяет одну и ту же операцию к набору значений.
  • Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.

Типичный поток сборки JVM-проекта

Разбор:

  • Фрагмент на mermaid показывает рабочий пример: начинается с flowchart LR и задает контекст выполнения.
  • Ключевые операторы и выражения (def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера.
  • Основная логика выражена последовательностью инструкций, которые рантайм выполняет сверху вниз.
  • Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
  • Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.

После зелёных тестов следующим stage часто добавляют docker build или деплой — это уже отдельные статьи DevOps.

docker build

Разбор:

  • Фрагмент на bash показывает рабочий пример: начинается с docker build и задает контекст выполнения.
  • Ключевые операторы и выражения (def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера.
  • Основная логика выражена последовательностью инструкций, которые рантайм выполняет сверху вниз.
  • Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
  • Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.

Частые ошибки

СимптомПричина
gradlew: not foundНет wrapper в репо — выполните gradle wrapper и закоммитьте
JDK не той версииGlobal Tool Configuration → JDK, или tool name: 'jdk17' в pipeline
checkout пустойВ job не настроен SCM (для Pipeline from SCM URL задаётся в job)
Тесты зелёные, job красныйНеверный glob в junit '...'
Spock не в отчётеПуть к XML Gradle: build/test-results/test/

Spock-тесты попадают в тот же ./gradlew test, отдельный шаг не нужен.

./gradlew test

Разбор:

  • Фрагмент на bash показывает рабочий пример: начинается с ./gradlew test и задает контекст выполнения.
  • Ключевые операторы и выражения (def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера.
  • Основная логика выражена последовательностью инструкций, которые рантайм выполняет сверху вниз.
  • Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
  • Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.

Что попробовать

  1. Stage Docker build после тестов, если есть Dockerfile.
Docker build

Разбор:

  • Фрагмент на bash показывает рабочий пример: начинается с Docker build и задает контекст выполнения.
  • Ключевые операторы и выражения (def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера.
  • Основная логика выражена последовательностью инструкций, которые рантайм выполняет сверху вниз.
  • Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
  • Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
  1. parallel { stage('Unit'){...} stage('Lint'){...} } — параллельные этапы.
  2. Webhook из GitHub/GitLab — сборка на каждый push без "Build Now".

Дальше

Job DSL Playground · Jenkins Shared Library · Spock · Gradle DSL в Groovy · DevOps


Расширение Jenkinsfile для production-потока

После базового pipeline обычно добавляют:

  • stage Lint до Build & Test;
  • stage публикации артефакта (publish, docker push);
  • ручное подтверждение перед production-деплоем;
  • уведомления в чат о статусе.
stage("Deploy approval") {
steps {
input message: "Подтвердите выкладку в production", ok: "Deploy"
}
}

Разбор:

  • Фрагмент на groovy показывает рабочий пример: начинается с stage("Deploy approval") { и задает контекст выполнения.
  • Ключевые операторы и выражения (def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера.
  • Вызовы функций или команд выполняют полезное действие: чтение данных, вычисление результата или запуск задачи сборки.
  • Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
  • Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.

Этот шаг отделяет автоматическую сборку от управляемого релиза.


Мини-чек-лист стабильности CI

  1. Все зависимости фиксированы по версиям.
  2. Секреты хранятся только в Jenkins Credentials.
  3. В каждом stage есть понятное имя и четкая цель.
  4. post { always { junit ... } } сохраняет отчеты даже при ошибках.
  5. Таймауты стоят на pipeline и на долгих shell-командах.

Связанные статьи — Gradle Groovy DSL, Spock, Работа с БД для миграционных шагов.


Сквозной кейс — pipeline для каталога книг

Минимальный путь для каталога:

  1. Сборка и тесты сервиса.
  2. Публикация тест-отчета.
  3. Условный деплой после ручного подтверждения.

Код ITЗагрузка примера кода…

Разбор:

  • Фрагмент на groovy показывает рабочий пример: начинается с pipeline { и задает контекст выполнения.
  • Ключевые операторы и выражения (def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера.
  • Вызовы функций или команд выполняют полезное действие: чтение данных, вычисление результата или запуск задачи сборки.
  • Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
  • Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.

Эта схема связывает код, тесты и релиз в один повторяемый процесс.

Продолжение — Jenkins Shared Library, Job DSL Playground, Gradle Groovy DSL.