Условное выполнение when и блок post

Рейтинг: 72.2% · 10 голосов
Подробный курс по Jenkins и CI/CD: установка и настройка, плагины и Configuration as Code, конвейеры (pipeline) и Jenkinsfile, declarative и scripted, агенты, Docker и Kubernetes, общие библиотеки на Groovy, безопасность и credentials, интеграции (SonarQube, артефакты), траблшутинг. Актуально на 2026.
Ответить
Аватара пользователя
Andrey_CICD
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Условное выполнение when и блок post

Сообщение Andrey_CICD »

Оглавление курса (47)
  1. Что такое Jenkins и зачем нужен CI/CD
  2. Jenkins в 2026: версии, экосистема и сравнение с GitLab CI и GitHub Actions
  3. Архитектура Jenkins: контроллер, агенты, узлы и исполнители
  4. Установка Jenkins: пакеты, Docker и Kubernetes
  5. Первичная настройка Jenkins: мастер, плагины, пользователи
  6. Плагины Jenkins: установка, обновление и ключевой набор
  7. Configuration as Code (JCasC): настройка Jenkins декларативно
  8. Конвейеры Jenkins и Jenkinsfile: pipeline as code
  9. Scripted против Declarative: два синтаксиса конвейера
  10. Структура конвейера: node, stage, steps и первый pipeline
  11. Генератор сниппетов, запуск конвейера и Replay
  12. Типы заданий Jenkins: Freestyle, Pipeline, Multibranch и Organization
  13. Декларативный конвейер: структура pipeline, agent, stages
  14. agent, environment и переменные в конвейере
  15. tools, options, parameters и triggers в декларативном конвейере
  16. stages, parallel и matrix: организация этапов
  17. Условное выполнение when и блок post (вы здесь)
  18. Триггеры сборки: webhook от GitHub, SCM polling и расписание
  19. Параметры сборки и пользовательский ввод
  20. Управление потоком: timeout, retry, sleep и waitUntil
  21. Параллелизм и блокировки: parallel, lock, milestone
  22. Постобработка и уведомления о результате сборки
  23. Groovy для Jenkins: основы скриптового конвейера
  24. Скриптовый конвейер: логика, циклы и функции
  25. Общие библиотеки Jenkins: Shared Libraries
  26. Подключение и загрузка общих библиотек
  27. Шаги оболочки: sh, bat, powershell и коды возврата
  28. Переменные среды, withEnv и рабочие пространства
  29. Работа с файлами, артефактами и отпечатками
  30. Сборка проектов в конвейере: Maven, Gradle, npm
  31. Качество кода: SonarQube и покрытие тестами
  32. Управление артефактами: публикация в Nexus и Artifactory
  33. Docker в Jenkins: образы как агенты сборки
  34. Сборка и публикация Docker-образов из конвейера
  35. Jenkins в Kubernetes: динамические pod-агенты
  36. Развёртывание в Kubernetes из конвейера
  37. Безопасность Jenkins: аутентификация и матрица прав
  38. Учётные данные Jenkins: credentials в конвейере
  39. Безопасность сценариев: Groovy sandbox и Vault
  40. Уведомления и отчёты: email, Slack, Telegram, HTML
  41. Blue Ocean и интерфейс Jenkins в 2026
  42. Автоматизация Jenkins: CLI, REST API и script console
  43. Поиск и устранение неисправностей: читаем логи конвейера
  44. Типичные ошибки конвейера: сериализация и неутверждённый код
  45. Эксплуатация Jenkins: бэкап, обновление, масштабирование
  46. Конвертация и миграция: от Freestyle к Jenkinsfile
  47. Итог: сквозной CI/CD конвейер и Jenkins против альтернатив в 2026
Представь конвейер, который собирает приложение, гоняет тесты и деплоит в прод. Он один на все ветки. И вот фрилансер из ветки feature/button-color запускает сборку, а твой код радостно выкатывает его недоделку на боевые серверы. Знакомая боль? Деплой должен идти только из main, нотификация в чат - только когда что-то упало, а чистку рабочей директории надо делать всегда, иначе агент захламится за неделю. Всё это решают две вещи: директива when (когда вообще выполнять стейдж) и блок post (что сделать по итогу). Разберём их так, чтобы ты собрал боевой деплой-конвейер, а не игрушку из туториала.

Директива when: jenkins pipeline и условие на стейдже

when живёт внутри stage и решает один вопрос: запускать этот стейдж в текущей сборке или пропустить. Если условие ложное, Jenkins помечает стейдж как Skipped и идёт дальше - сборка при этом остаётся зелёной. Это ровно то, что нужно: один Jenkinsfile, разное поведение в зависимости от ветки, окружения или того, какие файлы изменились.

Самый частый кейс - jenkins when branch. Деплой только из main:

Код: Выделить всё

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'make build'
            }
        }
        stage('Deploy') {
            when {
                branch 'main'
            }
            steps {
                sh './deploy.sh prod'
            }
        }
    }
}
Стейдж Deploy выполнится в сборке ветки main и будет пропущен в любой другой. Важная тонкость: условие branch работает только для multibranch pipeline или когда переменная окружения BRANCH_NAME реально проставлена. В обычном pipeline-задании без multibranch её просто нет, и условие всегда ложное - частая причина "почему мой деплой не запускается".

Кроме branch есть набор встроенных условий:
  • branch - имя ветки, поддерживает маски: branch 'release/*' или branch comparator: 'REGEXP', pattern: 'release-.*'
  • environment - проверка переменной: environment name: 'DEPLOY_ENV', value: 'production'
  • expression - произвольное Groovy-выражение, которое должно вернуть true: expression { return params.RUN_DEPLOY == true }
  • changeset - сработает, если в коммите менялись файлы по маске: changeset "**/*.sql" (удобно гонять миграции только когда они реально изменились)
  • tag - сборка по git-тегу: tag "v*"
  • buildingTag, triggeredBy - сборка тега и причина запуска
Условия комбинируются логическими блоками. allOf требует, чтобы выполнились ВСЕ вложенные условия, anyOf - хотя бы одно, not - инверсия. jenkins when с несколькими условиями выглядит так:

Код: Выделить всё

stage('Deploy prod') {
    when {
        allOf {
            branch 'main'
            environment name: 'DEPLOY_ENV', value: 'production'
            not { changeset "docs/**" }
        }
    }
    steps {
        sh './deploy.sh prod'
    }
}
Читается дословно: деплоим, если это ветка main, и окружение production, и менялись не только доки. anyOf удобен для "собирай на push в main ИЛИ если кто-то запустил руками":

Код: Выделить всё

when {
    anyOf {
        branch 'main'
        triggeredBy 'UserIdCause'
    }
}
Отдельно запомни опцию beforeAgent. По умолчанию Jenkins сначала поднимает агента (в Kubernetes - целый pod), а уже потом проверяет when. Если условие ложное, ты впустую поднял и погасил под. Ставь beforeAgent true - тогда условие проверяется ДО выделения агента:

Код: Выделить всё

stage('Deploy') {
    agent { label 'deploy-node' }
    when {
        beforeAgent true
        branch 'main'
    }
    steps { sh './deploy.sh' }
}
Есть ещё beforeInput и beforeOptions с похожим смыслом - проверять when раньше шага input или блока options.

Изображение

Блок post: jenkins post always и постобработка по результату

Стейдж выполнился (или упал) - что дальше? Уведомить, заархивировать артефакты, прибрать за собой. Этим занимается блок post. Он ставится либо в конце конкретного stage (постобработка этого стейджа), либо в конце pipeline (итог всей сборки). Внутри - условия по статусу, и Jenkins сам выберет, какие из них запустить.

Полный набор условий post:
  • always - выполнится всегда, чем бы сборка ни кончилась. Сюда кладут очистку и то, что должно произойти при любом исходе
  • success - только при успехе
  • failure - только при падении (статус FAILURE)
  • unstable - сборка нестабильна (обычно упали тесты, но шаг не зафейлился жёстко)
  • aborted - сборку прервали вручную или по таймауту
  • unsuccessful - любой неуспех: failure, unstable или aborted
  • changed - статус изменился относительно прошлой сборки (была красная, стала зелёная - или наоборот)
  • fixed - прошлая сборка была неуспешной, а эта успешна (чинили - починили)
  • regression - прошлая была успешной, эта сломалась (то, на что хочется орать алертом)
  • cleanup - выполняется самым последним, после всех остальных условий, для финальной уборки
jenkins post always - самый ходовой блок. Боевой post для деплой-конвейера:

Код: Выделить всё

post {
    always {
        cleanWs()
    }
    success {
        echo 'Сборка прошла успешно'
    }
    failure {
        mail to: 'team@example.com',
             subject: "Упала сборка ${env.JOB_NAME} #${env.BUILD_NUMBER}",
             body: "Смотри логи: ${env.BUILD_URL}"
    }
    unstable {
        echo 'Часть тестов красная - смотри отчёт'
    }
    fixed {
        echo 'Сборка снова зелёная после падения'
    }
}
Здесь cleanWs() (из плагина Workspace Cleanup) чистит директорию всегда, а письмо уходит только при падении. Условие regression удобно вешать отдельным алертом - именно оно ловит момент, когда стабильная ветка внезапно сломалась, и не шумит на сборках, которые и так были красными.

script-блок и сочетание when + post в реальном деплое

Declarative намеренно ограничен - ты описываешь структуру, а не пишешь программу. Но иногда нужна логика: цикл, try/catch, сложное ветвление. Для этого есть аварийный люк - script. Внутри него работает полноценный Groovy (scripted pipeline), но держи такие блоки маленькими: чем больше Groovy в declarative, тем хуже читается конвейер.

Код: Выделить всё

stage('Notify') {
    steps {
        script {
            def color = currentBuild.currentResult == 'SUCCESS' ? 'good' : 'danger'
            def msg = "Сборка ${env.JOB_NAME} #${env.BUILD_NUMBER}: ${currentBuild.currentResult}"
            slackSend channel: '#ci', color: color, message: msg
        }
    }
}
Теперь соберём всё вместе - типовой паттерн "деплой только из main, уведомить при падении". Это та самая связка when + post, ради которой и затевался урок:

Код: Выделить всё

pipeline {
    agent any
    environment {
        DEPLOY_ENV = 'production'
    }
    stages {
        stage('Build') {
            steps { sh 'make build' }
        }
        stage('Test') {
            steps { sh 'make test' }
        }
        stage('Deploy prod') {
            when {
                beforeAgent true
                allOf {
                    branch 'main'
                    environment name: 'DEPLOY_ENV', value: 'production'
                }
            }
            steps {
                sh './deploy.sh prod'
            }
            post {
                success {
                    slackSend channel: '#deploys',
                              message: "Прод задеплоен: ${env.BUILD_URL}"
                }
                failure {
                    slackSend channel: '#deploys', color: 'danger',
                              message: "ДЕПЛОЙ УПАЛ: ${env.BUILD_URL}"
                }
            }
        }
    }
    post {
        always {
            cleanWs()
        }
        regression {
            mail to: 'team@example.com',
                 subject: "Регрессия в ${env.JOB_NAME}",
                 body: "Стабильная сборка сломалась: ${env.BUILD_URL}"
        }
    }
}
Обрати внимание на два уровня post: внутри стейджа Deploy - нотификация именно про деплой (она НЕ сработает, если стейдж пропущен по when), а снаружи - уборка и алерт о регрессии для всей сборки. Это и есть рабочий скелет, который ты будешь копировать из проекта в проект.

Типичные грабли
  • branch не срабатывает в обычном job. Условие branch требует BRANCH_NAME, а её ставит только multibranch pipeline. В одиночном задании проверяй ветку через expression и git rev-parse либо параметр.
  • post стейджа не выполняется при пропуске. Если стейдж пропущен по when, его внутренний post не запустится - там нечего постобрабатывать. Алерты о деплое вешай на post того стейджа, который реально шёл, или на post всего pipeline.
  • beforeAgent забыт - и под поднимается зря. Особенно больно в Kubernetes: без beforeAgent true Jenkins создаёт эфемерный pod, и только потом видит, что when ложный. Деньги и время на ветер.
  • success в post не значит "всё хорошо". Если внутри шага ты сделал catchError или тесты пометили сборку UNSTABLE, итог - не SUCCESS. Проверяй currentBuild.currentResult, а не свои ожидания.
  • changeset на первой сборке ветки. Когда у ветки ещё нет предыдущего коммита для сравнения, changeset может вести себя неожиданно. Не строй на нём критичный деплой без запасного условия.
Мини-лаба
  • Возьми Jenkins LTS актуальной линии (2.541.x на июнь 2026; учти, что новые линии 2.555+ уже требуют Java 21 или 25). Создай multibranch pipeline на любом git-репозитории с ветками main и dev.
  • Напиши Jenkinsfile со стейджами Build, Test, Deploy. На Deploy повесь when { branch 'main' } с beforeAgent true. Запусти сборку из dev - убедись, что Deploy помечен Skipped.
  • Добавь блок post на уровне pipeline: always с echo, success и failure с разными сообщениями. Сломай шаг (например sh 'exit 1') и проверь, что отработал именно failure, а не success.
  • Замени одно условие на allOf из branch и expression, протестируй обе ветки логики.
  • Добавь script-блок, который пишет в лог currentBuild.currentResult, и посмотри значение при упавшей и при успешной сборке.
Контрольные вопросы
  • Чем отличается результат, когда стейдж пропущен по when, от ситуации, когда он упал? Что происходит со статусом всей сборки?
  • Зачем нужна опция beforeAgent true и где её отсутствие особенно дорого обходится?
  • В чём разница между условиями post always, changed и regression? Когда какое сработает?
  • Почему post внутри стейджа не выполнится, если этот стейдж пропущен по when, и куда тогда вешать нотификацию о деплое?
Итог

when отвечает на вопрос "выполнять ли стейдж", post - "что сделать по итогу". Связка branch плюс post.failure/success - это стандартный шаблон безопасного деплоя: выкатываем только из main, шумим в чат при падении, всегда прибираемся за собой. Добавь beforeAgent true, чтобы не жечь агентов впустую, держи script-блоки короткими - и твой declarative-конвейер будет одновременно читаемым и боевым. Дальше эти же when и post лягут в основу матричных сборок и параллельных стейджей, которые разберём в следующих главах.
👍3 ❤️4 🔥3 😄 🤔2
Аватара пользователя
iyb57
Сообщения: 1
Зарегистрирован: 26 май 2026, 11:01

Re: Условное выполнение when и блок post

Сообщение iyb57 »

Спасибо, наконец дошло почему мой Deploy всегда Skipped - это был обычный pipeline без multibranch, BRANCH_NAME пустая. Перевёл на multibranch и заработало.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
zigcoder
Сообщения: 1
Зарегистрирован: 14 май 2026, 21:00

Re: Условное выполнение when и блок post

Сообщение zigcoder »

Про beforeAgent true прям боль из жизни. У нас на k8s каждый прогон поднимал под на проверку условия, которое в 9 из 10 раз false. Поставил - агенты перестали зря плодиться, спасибо за подсказку.
👍1 ❤️ 🔥1 😄 🤔1
Ответить
← Предыдущая глава
stages, parallel и matrix: организация этапов
Следующая глава →
Триггеры сборки: webhook от GitHub, SCM polling и расписание

Все главы курса «Jenkins: конвейеры CI/CD от основ до продакшена»

Поделиться темой: ✈ Telegram VK

Вернуться в «Jenkins: конвейеры CI/CD от основ до продакшена»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя