Представь типичную боль. У тебя есть jenkins pipeline, который собирает проект на Maven. Сегодня он зеленый, а завтра падает с "mvn: command not found", потому что агент переехал и нужная версия Maven там не настроена. Дальше - сборка зависает на час, потому что тест ушел в бесконечный цикл, и слот агента занят намертво. А еще история сборок распухла до десятков гигабайт логов и артефактов, диск контроллера забит. И вишенка: чтобы выкатить релиз на нужный стенд, инженер лезет править Jenkinsfile руками, потому что окружение в коде захардкожено.
Все четыре проблемы закрываются директивами уровня pipeline, которые мы разберем в этом уроке: tools, options, parameters и triggers. Это не экзотика, а базовая гигиена любого декларативного конвейера. В книге Ластера они идут в главе про синтаксис declarative pipeline, и в 2026 году ничего из этого не устарело - наоборот, declarative стал стандартом де-факто, а scripted-конвейеры остались для случаев, где нужна настоящая динамика на Groovy.
Дальше я по очереди покажу, где каждая директива живет в блоке pipeline, что она делает и где об нее обычно спотыкаются.

tools: подтянуть Maven, JDK и Gradle в PATH
Директива jenkins tools решает ровно одну задачу - положить нужный инструмент в PATH стадии и выставить переменные окружения вроде JAVA_HOME. Работает она только с инструментами, которые ты заранее объявил в Manage Jenkins -> Tools (раньше это был раздел Global Tool Configuration). То есть имя в Jenkinsfile - это не путь и не версия из интернета, а ссылка на конкретную запись в конфигурации Jenkins.
Поддерживаются три типа из коробки: maven, jdk и gradle (плюс то, что добавляют плагины). Имя должно совпадать символ в символ с тем, что ты вписал в настройках инструмента.
Код: Выделить всё
pipeline {
agent any
tools {
maven 'Maven-3.9.9'
jdk 'JDK-21'
}
stages {
stage('Build') {
steps {
sh 'mvn -version'
sh 'mvn -B clean package'
}
}
}
}
options: таймауты, ротация и поведение сборки
Блок jenkins options настраивает поведение всего конвейера. Это самая практически полезная директива из четырех, потому что именно она спасает от зависших сборок и забитого диска. Разберу самые ходовые опции.
- timeout - жесткий лимит времени. Сборка висит дольше - Jenkins ее прибивает. Параметры: unit (SECONDS, MINUTES, HOURS) и time.
- buildDiscarder - ротация старых сборок через logRotator. Без нее история растет бесконечно.
- retry - повтор всего пайплайна N раз при падении (есть и step retry внутри стадии).
- disableConcurrentBuilds - запрет параллельных запусков одной джобы. Незаменимо, когда сборка деплоит и два запуска подрались бы за окружение.
- timestamps - префикс времени у каждой строки лога. Бесплатно и сильно облегчает разбор.
- skipStagesAfterUnstable - не запускать следующие стадии, если сборка стала unstable.
Код: Выделить всё
pipeline {
agent any
options {
timeout(time: 30, unit: 'MINUTES')
buildDiscarder(logRotator(numToKeepStr: '20', artifactNumToKeepStr: '5'))
disableConcurrentBuilds()
timestamps()
retry(2)
}
stages {
stage('Build') {
steps {
sh 'make build'
}
}
}
}
parameters: параметризованные сборки
Директива jenkins parameters превращает джобу в параметризованную: при запуске вручную Jenkins покажет форму с полями, а значения попадут в переменные окружения внутри пайплайна. Это то, что в книге называется параметризованной сборкой - один Jenkinsfile, разное поведение в зависимости от ввода.
Базовые типы параметров:
- string - строка (версия, тег, имя ветки).
- choice - выпадающий список фиксированных вариантов (стенд деплоя).
- booleanParam - галочка да/нет (например, запускать ли деплой).
- text - многострочный текст, password - скрытый ввод.
Код: Выделить всё
pipeline {
agent any
parameters {
string(name: 'RELEASE_TAG', defaultValue: 'latest', description: 'Тег для сборки')
choice(name: 'ENV', choices: ['dev', 'staging', 'prod'], description: 'Куда деплоим')
booleanParam(name: 'RUN_TESTS', defaultValue: true, description: 'Прогонять тесты')
}
stages {
stage('Test') {
when { expression { return params.RUN_TESTS } }
steps {
sh 'make test'
}
}
stage('Deploy') {
steps {
echo "Deploy ${params.RELEASE_TAG} -> ${params.ENV}"
sh "./deploy.sh ${params.ENV} ${params.RELEASE_TAG}"
}
}
}
}
И про безопасность: не передавай секреты через string или text. Для этого есть credentials и тип password, а лучше - подтягивать секрет через withCredentials. Параметр в открытом виде осядет в истории сборки.
triggers: автозапуск конвейера
Директива jenkins triggers отвечает за то, чтобы сборка стартовала сама, без человека у кнопки. Три рабочих варианта:
- cron - запуск по расписанию (ночные сборки, регрессия по выходным).
- pollSCM - Jenkins периодически опрашивает репозиторий и стартует при изменениях.
- upstream - запуск после успешного завершения другой джобы.
Код: Выделить всё
pipeline {
agent any
triggers {
cron('H 2 * * 1-5')
pollSCM('H/15 * * * *')
}
stages {
stage('Nightly') {
steps {
sh 'make nightly'
}
}
}
}
Честно скажу про 2026 год: pollSCM - это вчерашний день. Опрос репозитория каждые 15 минут создает лишнюю нагрузку и реагирует с задержкой. Правильный подход сегодня - вебхуки от GitHub, GitLab или Gitea: репозиторий сам пинает Jenkins при пуше, мгновенно и без опроса. pollSCM оставляют там, где вебхук физически не настроить (закрытый контур, нет доступа наружу). cron же по-прежнему актуален для ночных и регрессионных прогонов.
Тут уместно сравнение с конкурентами. В GitLab CI и GitHub Actions триггеры живут прямо в YAML (on: push, schedule, workflow_run) и завязаны на платформу. Jenkins гибче и не привязан к одному хостингу гита, но за гибкость платишь тем, что вебхуки и плагины надо настраивать руками. Если у тебя весь код в одном GitHub - Actions проще; если зоопарк репозиториев и сложные пайплайны - Jenkins выигрывает.
Типичные грабли
- Имя в tools не совпадает с записью в Manage Jenkins -> Tools. Падает с "No tool named ... found". Сверяй посимвольно.
- В buildDiscarder передали число без кавычек. Должно быть numToKeepStr: '20', строка.
- Ждут форму параметров на первом запуске. Она появляется со второго - первый идет на defaultValue.
- Поставили timeout слишком маленьким - сборка с долгими интеграционными тестами начинает рандомно падать по таймауту. Меряй реальное время и закладывай запас.
- Забыли disableConcurrentBuilds на деплойной джобе - два параллельных запуска подрались за один стенд.
- Используют pollSCM как основной механизм и удивляются нагрузке и задержкам. Переходи на вебхуки.
- Пытаются через tools поставить kubectl, docker, node по экзотическому плагину, которого нет. tools - это про maven, jdk, gradle; остальное - в образ агента.
Повтори руками на любом учебном проекте:
- Объяви в Manage Jenkins -> Tools установку Maven и JDK 21, подключи их через tools и убедись, что mvn -version в шаге sh видит правильную версию.
- Добавь options с timeout(time: 10, unit: 'MINUTES'), buildDiscarder на 10 сборок и timestamps. Запусти, посмотри на временные метки в логе.
- Сделай параметризованную сборку: choice со стендами dev/staging/prod и booleanParam RUN_TESTS. Привяжи RUN_TESTS к when у стадии тестов. Запусти дважды и сравни первый запуск со вторым (когда появилась форма).
- Добавь triggers с cron('H H(0-5) * * *') и убедись, что джоба запланировалась (Jenkins покажет следующий запуск).
- Чем имя инструмента в директиве tools отличается от пути к нему, и где Jenkins берет реальную установку?
- Какие аргументы принимает logRotator и почему артефактов обычно хранят меньше, чем логов?
- Почему форма параметров не появляется при самом первом запуске пайплайна с новой директивой parameters?
- Зачем в cron-выражении писать H вместо фиксированной минуты, и почему в 2026 году вебхуки предпочтительнее pollSCM?
Четыре директивы уровня pipeline закрывают четыре разные боли: tools кладет нужный Maven, JDK или Gradle в PATH на классических агентах, options дисциплинирует поведение сборки через timeout и buildDiscarder, parameters дает параметризованные запуски одним Jenkinsfile, а triggers заводит автозапуск по cron или из апстрима. Запомни актуальные акценты 2026: в Kubernetes инструменты живут в образе агента, а не в tools; вебхуки бьют pollSCM; секреты - только через credentials, не через string. Дальше эти директивы станут фундаментом, на котором мы будем строить более сложные многостадийные конвейеры.