Параметры в Jenkins

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

cf91a20edd616f2eeb045b881de0c4a1.jpg

Основные виды параметров

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

4217551da5a9844627f6409fd9af85c7.png

 По умолчанию Jenkins предоставляет несколько типов параметров, но вы можете расширять это список, используя Plugins. Например, вы можете добавить Active Choice Parameter, о котором мы поговорим далее.

Вот основные параметры, которые Jenkins предлагает «из коробки»:

  1. Boolean Parameter определяет логические параметры. Может принимать значения true/false. Также для параметра можно задать значение по умолчанию.

    booleanParam (name: «DryRun», defaultValue: true, description: «Тестовый запуск»)

  2. String Parameter определяет одностроковый параметр. Поддерживает удаление пробелов с обоих сторон от введённого значения.

    string (name: «version», defaultValue: «r48», trim: false, description:»Введите версию компонента»)

  3. Multi-line String Parameter определят многостроковый параметр.

    text (name: «releaseNotes», defaultValue: «none», description: «Описание изменений в релизе»)

  4. Password позволяет определить ввод пароля. Данные пароля не будут отображаться при запуске Job и в console log.

    password (name: «password», defaultValue: «changeme», description: «Введите пароль»)

  5. 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 == "try" }
            }
            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 мы увидим:  

a456459b8d0d004769d8209707b1de77.png

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

3e6a68c20dd3a49cb66e17cefc84a03a.png

Active Choice Parameter

Active Choice Parameter не добавляется по умолчанию. Для его использования сначала нужно установить плагин Active Choices.

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

f0c5d7d8888d76820af4a7e4cd436344.png

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

33c89c04803278019d7c9834abe160a5.png

Рассмотрим каждую из них:

  1. Active Choices Parameter позволяет использовать сценарий Groovy или Scriplet (плагин), чтобы определить, будет ли ввод вычисляться или он уже предопределен, и возвращать результаты в зависимости от выполненных скриптов.

  2. Active Choices Reactive Parameter похож на Active Choice Parameter. Он позволят использовать Groovy или Scriplet, а его значение меняется в зависимости от значения выбранного зависимого параметра.

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

Не забываем, что новые скрипты нужно подтверждать:

62982439a6a2b7a324887542578c558a.png

Теперь перейдем к созданию 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, выбираем компонент и версию и смотрим на результат:

3cdfafc60cb8029115e0e4909e658392.png0e482e535f956244d97c728b35f442f0.png

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

© Habrahabr.ru