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

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 { } }
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

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

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 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'
}
}

В post путь к Surefire:

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

-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')
}
ШагДействие
Jenkins UIManage Jenkins → Credentials
ДобавитьSecret text или Username + password
IDСовпадает со строкой в credentials('...')
В pipelineПеременная DOCKER_TOKEN подставится при сборке

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


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}"
}
}
}
}

Типичный поток сборки 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, отдельный шаг не нужен.


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

  1. Stage Docker build после тестов, если есть Dockerfile.
  2. parallel { stage('Unit'){...} stage('Lint'){...} } — параллельные этапы.
  3. Webhook из GitHub/GitLab — сборка на каждый push без «Build Now».

Дальше

Spock · Gradle DSL в Groovy · DevOps


См. также

Другие статьи этого же раздела в боковом меню (как на странице «О разделе»).