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.
Термины
| Термин | Простыми словами |
|---|---|
| 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
Положите в корень репозитория:
pipeline {
agent any
options {
timestamps()
timeout(time: 20, unit: 'MINUTES')
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build & Test') {
steps {
sh './gradlew test --no-daemon'
}
}
}
post {
always {
junit '**/build/test-results/test/*.xml'
}
success {
echo 'Сборка успешна'
}
failure {
echo 'Сборка упала — смотрите лог stage'
}
}
}
Разбор построчно
| Фрагмент | Смысл |
|---|---|
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'
}
}
В post путь к Surefire:
junit '**/target/surefire-reports/*.xml'
-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')
}
| Шаг | Действие |
|---|---|
| Jenkins UI | Manage Jenkins → Credentials |
| Добавить | Secret text или Username + password |
| ID | Совпадает со строкой в credentials('...') |
| В pipeline | Переменная DOCKER_TOKEN подставится при сборке |
В логах Jenkins маскирует секреты, но случайный echo "${DOCKER_TOKEN}" в скрипте всё равно опасен — не печатайте секреты.
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}"
}
}
}
}
Типичный поток сборки JVM-проекта
После зелёных тестов следующим stage часто добавляют docker build или деплой — это уже отдельные статьи DevOps.
Частые ошибки
| Симптом | Причина |
|---|---|
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, отдельный шаг не нужен.
Что попробовать
- Stage
Docker buildпосле тестов, если естьDockerfile. parallel { stage('Unit'){...} stage('Lint'){...} }— параллельные этапы.- Webhook из GitHub/GitLab — сборка на каждый push без «Build Now».
Дальше
Spock · Gradle DSL в Groovy · DevOps
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). Краткая хронология Groovy на JVM — от идеи James Strachan до ниши Gradle, Jenkins и Spock. Groovy — язык для JVM: тот же байт-код и библиотеки Java, но короче синтаксис, замыкания и скрипты. Набор советов, правил, принципов и обычаев в разработке на этом языке. Простые приложения на Groovy — скрипты на JVM, файлы, JSON и HTTP. Макросы на уровне языка (начиная с Groovy 2.5) — groovy.transform.Macro позволяет инжектить код, основываясь на анализе AST. Статическая и динамическая типизация в Groovy, примитивы JVM, строки GString, коллекции, диапазоны и ключевые операторы def, as, instanceof. Операторы и выражения в Groovy - арифметика, логика и выразительный синтаксис поверх JVM-экосистемы. Циклы и управляющие конструкции Groovy - императивные и декларативные способы описания логики выполнения. В этом примере greet — это переменная, содержащая замыкание. Замыкание принимает один параметр name и выводит приветствие. Вызов greet(Groovy) выполняет код внутри замыкания. Нет проверяемых исключений — компилятор Groovy игнорирует механизм throws, принятый в Java. Динамическая типизация, метапрограммирование, AST-трансформации, DSL, работа с XML и JSON, синтаксический сахар и интеграция с Java. Кавычки, скобки, замыкания, switch, регулярные выражения и truthiness в Groovy.История языка Groovy
Что требуется знать перед началом изучения языка программирования Groovy
Рекомендации по разработке на Groovy
Простые приложения на Groovy
Основы языка Groovy
Типы данных и объявление переменных
Операторы и выражения в Groovy
Циклы и управляющие конструкции
Объектно-ориентированное программирование в Groovy
Иерархия исключений в Groovy
Особенности и расширения языка Groovy
Синтаксис и пунктуация в Groovy