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 { } } |
| SCM | Source 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 scm | Git 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
- New Item → имя → Pipeline (или Multibranch Pipeline).
- В настройках: Pipeline script from SCM.
- SCM: Git → URL репозитория, credentials при необходимости.
- Script Path:
Jenkinsfile(по умолчанию в корне). - Save → Build 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 UI | Manage 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
| Declarative | Scripted (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, литералы, вызовы) формируют данные, с которыми работает остальная часть примера. - Основная логика выражена последовательностью инструкций, которые рантайм выполняет сверху вниз.
- Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
- Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
Что попробовать
- Stage
Docker buildпосле тестов, если естьDockerfile.
Docker build
Разбор:
- Фрагмент на
bashпоказывает рабочий пример: начинается сDocker buildи задает контекст выполнения. - Ключевые операторы и выражения (
def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера. - Основная логика выражена последовательностью инструкций, которые рантайм выполняет сверху вниз.
- Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
- Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
parallel { stage('Unit'){...} stage('Lint'){...} }— параллельные этапы.- 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
- Все зависимости фиксированы по версиям.
- Секреты хранятся только в Jenkins Credentials.
- В каждом stage есть понятное имя и четкая цель.
post { always { junit ... } }сохраняет отчеты даже при ошибках.- Таймауты стоят на pipeline и на долгих shell-командах.
Связанные статьи — Gradle Groovy DSL, Spock, Работа с БД для миграционных шагов.
Сквозной кейс — pipeline для каталога книг
Минимальный путь для каталога:
- Сборка и тесты сервиса.
- Публикация тест-отчета.
- Условный деплой после ручного подтверждения.
Код ITЗагрузка примера кода…
Разбор:
- Фрагмент на
groovyпоказывает рабочий пример: начинается сpipeline {и задает контекст выполнения. - Ключевые операторы и выражения (
def, литералы, вызовы) формируют данные, с которыми работает остальная часть примера. - Вызовы функций или команд выполняют полезное действие: чтение данных, вычисление результата или запуск задачи сборки.
- Поток выполнения линейный: шаги идут последовательно, поэтому итог зависит от порядка операций в блоке.
- Итог фрагмента — воспроизводимый результат — вывод в консоль, изменение данных или артефакт, который можно сразу проверить.
Эта схема связывает код, тесты и релиз в один повторяемый процесс.
Продолжение — Jenkins Shared Library, Job DSL Playground, Gradle Groovy DSL.