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
Комментарии (2)
TuktarovMarat
11.08.2022 12:06Groovy вставки в декларативном пайплайне выглядят, конечно, ужасно))
если интересны подобные не совсем стандартные сценарии, то я бы посоветовал посмотреть в сторону вот этой shared либы. В своё время я нашёл там очень много фишечек https://github.com/SAP/jenkins-library
kWatt
Хорошая и нужная статья. Спасибо что описали пример с activeChoice.
Сам столкнулся с похожей задачей и решал с помощью etcd и вот такого кода:
Jenkinsfile: