Jenkins — один из наиболее популярных инструментов CI/CD. Он позволяет автоматизировать каждый этап жизненного цикла программного обеспечения: от создания до развертывания. В этой статье Кирилл Борисов, Infrastructure Engineer технологического центра Deutsche Bank, расскажет о параметрах в Jenkins и о том, как решить проблему хардкода с их помощью.

Основные виды параметров
Чтобы добавить параметры в Job, необходимо установить галочку «This project is parameterised»:

По умолчанию Jenkins предоставляет несколько типов параметров, но вы можете расширять это список, используя Plugins. Например, вы можете добавить Active Choice Parameter, о котором мы поговорим далее.
Вот основные параметры, которые Jenkins предлагает «из коробки»:
Boolean Parameter определяет логические параметры. Может принимать значения true/false. Также для параметра можно задать значение по умолчанию.
booleanParam (name: «DryRun», defaultValue: true, description: «Тестовый запуск»)
String Parameter определяет одностроковый параметр. Поддерживает удаление пробелов с обоих сторон от введённого значения.
string (name: «version», defaultValue: «r48», trim: false, description: «Введите версию компонента»)
Multi-line String Parameter определят многостроковый параметр.
text (name: «releaseNotes», defaultValue: «none», description: «Описание изменений в релизе»)
Password позволяет определить ввод пароля. Данные пароля не будут отображаться при запуске Job и в console log.
password (name: «password», defaultValue: «changeme», description: «Введите пароль»)
Choice Parameter позволяет выбрать несколько параметров из списка ранее предустановленных параметров.
choice (name: «env», choices: [«PROD», «DEV», «UAT»], description: «Выберите окружение для установки релиза»)
Как объявлять параметры в Jenkinsfile
pipeline { agent any parameters { booleanParam(name: "dryrun", defaultValue: true, description: "Тестовый запуск") string(name: "version", defaultValue: "r48", trim: true, description: "Введите версию компонента") text(name: "releaseNotes", defaultValue: "Добавлены новые feature", description: "Описание изменений в релизе") password(name: "password", defaultValue: "changeme", description: "Введите пароль") choice(name: "env", choices: ["PROD", "DEV", "UAT"], description: "Sample multi-choice parameter") } stages { stage('DryRun') { when { expression { params.dryrun } } steps { echo "THIS IS DRYRUN!" } } stage("Build") { steps { echo "Build stage." echo "Hello $params.version" } } stage("Test") { steps { echo "Test stage." } } stage("Release") { steps { echo "Defined release notes $params.releaseNotes" echo "Starting release on $params.env" } } } }
При запуске Job в Jenkins мы увидим:

И наконец то вывод нашего pipeline:

Active Choice Parameter
Active Choice Parameter не добавляется по умолчанию. Для его использования сначала нужно установить плагин Active Choices.
Как написано в документации: «Active Choices используется для параметризация Jenkins Job и для создания динамических и интерактивных параметров. Параметры Active Choices могут динамически обновляться и отображаться в виде полей со списком, флажков, переключателей или виджетов пользовательского интерфейса с HTML».

В нашем распоряжении появилось 3 дополнительных опции в разделе параметры:

Рассмотрим каждую из них:
Active Choices Parameter позволяет использовать сценарий Groovy или Scriplet(плагин), чтобы определить, будет ли ввод вычисляться или он уже предопределен, и возвращать результаты в зависимости от выполненных скриптов.
Active Choices Reactive Parameter похож на Active Choice Parameter. Он позволят использовать Groovy или Scriplet, а его значение меняется в зависимости от значения выбранного зависимого параметра.
Active Choices Reactive Reference Parameter содержит параметры Active Choice Parameter и Active Choice Reactive Parameter, а также добавляет новые опции. Например, HTML-виджеты, маркированные или нумерованные списки и поля ввода.
Перейдём к практике: кейс использования Active Choice Parameter
Представим, что у вас есть задача сделать Job, который позволит разработке или L2 support устанавливать сервис определенной версии в нужное окружение. Кажется, всё должно быть автоматизировано, но на практике возникает ситуация, когда разработчик или QA-инженер хочет проверить свою версию микросервиса на определенном окружении. Это можно было бы сделать и с использованием обычных string-параметров, но давайте упростим задачу и предоставим более дружественный интерфейс.
Для начала добавим выбор компонентов, используя gitlab api, напишем простой groovy скрипт для получения списка проектов, а затем создадим Jenkinsfile и добавим в него определение нашего параметра:
properties([ parameters([ [$class: 'ChoiceParameter', choiceType: 'PT_SINGLE_SELECT', description: 'Select a choice', filterLength: 1, filterable: false, name: 'component', script: [$class: 'GroovyScript', fallbackScript: [classpath: [], sandbox: false, script: 'return ["Could not get component"]'], script: [classpath: [], sandbox: false, script: """ import groovy.json.JsonSlurperClassic def list = [] def connection = new URL("https://run.mocky.io/v3/e406ee99-be79-4d50-818f-b186dad7f4f4") .openConnection() as HttpURLConnection connection.setRequestProperty('Accept', 'application/json') def json = connection.inputStream.text data = new JsonSlurperClassic().parseText(json) data.each { component -> list += component.name } return list """ ]]]]) ]) pipeline { agent any stages { stage("Component Name") { steps { sh "echo Selected component ${params.component}" } } } }
Не забываем, что новые скрипты нужно подтверждать:

Теперь перейдем к созданию Active Choices Reactive Parameter. В зависимости от выбранного компонента нам будут показываться все версии компонента в артефатори.
Создадим простой groovy-скрипт и добавим описание в Jenkinsfile:
[$class: 'CascadeChoiceParameter', choiceType: 'PT_SINGLE_SELECT', description: 'Select Version', filterLength: 1, filterable: true, name: 'version', referencedParameters: 'component', script: [ $class: 'GroovyScript', fallbackScript: [ classpath: [], sandbox: false, script: 'return[\'Could not get version\']' ], script: [ classpath: [], sandbox: false, script: """ import groovy.json.JsonSlurperClassic def list = [] def connection = new URL("https://run.mocky.io/v3/c782ae33-98a2-4994-acc4-14c0b5cc7655") .openConnection() as HttpURLConnection connection.setRequestProperty('Accept', 'application/json') def json = connection.inputStream.text data = new JsonSlurperClassic().parseText(json) data.data.each { it -> if (it.component == component ) { list += it.version } } return list """ ] ] ]
Важное изменение — это опция referencedParameters. В ней мы указываем параметр, от которого зависит выполнение скрипта. Запускаем нашу Job, выбираем компонент и версию и смотрим на результат:


https://gist.github.com/silabeer/2bb3baf37c7ee1dbed369e84d4b8d9d0
В результате мы получаем удобство в эксплуатации: конечному пользователю не нужно каждый раз руками «вбивать» имя компонента и искать версию в артефактори, нужно просто выбрать из списка.
Для тех, кто хочет в тонкости работы с Jenkins и получить скидку 10% на обучение
6 сентября у нас стартует курс по Jenkins, автором которого выступил Кирилл Борисов, Infrastructure Engineer технологического центра Deutsche Bank. В курсе будет много кейсов и примеров из практики спикера.
Вы научитесь:
автоматизировать процесс интеграции и поставки;
ускорять цикл разработки и внедрять полезные инструменты;
настраивать плагины и создавать пайплайны Jenkins as a code;
работать с Jenkins Shared Library.
Промокод «READER» даёт скидку 10% при покупке курса.
Ознакомиться с программой и записаться: https://slurm.club/3bGiJzB
