вы будете? Трубопровод Дженкинса

Jenkins

Справочная информация: система нашей компании основана на распределении. С ростом бизнеса количество сервисов увеличивается быстрее, что приводит к удвоению рабочей нагрузки в Интернете, поэтому мы подумали об автоматическом развертывании, и Jenkins просто соответствует нашим распределенным требованиям. Необходимость в автоматизированном развертывании .

1. Дженкинс

Что такое Дженкинс?

  • Jenkins — это программное обеспечение CI&CD с открытым исходным кодом, используемое для автоматизации различных задач, включая создание, тестирование и развертывание программного обеспечения.

  • Jenkins поддерживает различные среды выполнения либо через системные пакеты, Docker, либо через отдельную программу Java.

Подробное объяснение CI&CD см.:Что такое CI/CD?

Непрерывная интеграция

Современная разработка приложенийЦель состоит в том, чтобы несколько разработчиков работали над разными функциями одного и того же приложения одновременно. Однако, если предприятие запланировало день для слияния исходного кода всех ветвей (так называемый "Дата слияния"), что в конечном итоге может оказаться утомительным, трудоемким и ручным. Это связано с тем, что когда независимый разработчик вносит изменения в приложение, есть вероятность, что оно будет конфликтовать с одновременными изменениями, внесенными другими разработчиками. Каждый разработчик настраивает свои собственный местныйИнтегрированная среда разработки (IDE), вместо того, чтобы команда согласовала облачную IDE, усугубила бы проблему.

Непрерывная интеграция (CI) может помочь разработчикам чаще объединять изменения кода в общую ветку или «ствол» (иногда даже ежедневно). Как только изменения, внесенные разработчиками в приложение, объединены, система проверяет изменения, автоматически создавая приложение и запуская различные уровни автоматических тестов (обычно модульных и интеграционных тестов), чтобы убедиться, что изменения не нарушили работу приложения. Это означает, что тесты охватывают все, от классов и функций до различных модулей, составляющих все приложение. Если автоматизированное тестирование обнаруживает конфликты между новым и существующим кодом, CI упрощает быстрое исправление этих ошибок.

непрерывная поставка

Непрерывная доставка автоматизирует выпуск проверенного кода в репозиторий после завершения автоматизированного процесса сборки и модульного и интеграционного тестирования в CI. Для эффективного процесса непрерывной доставки важно убедиться, что CI встроен в конвейер разработки. Цель непрерывной доставки — иметь кодовую базу, готовую к развертыванию в рабочей среде.

При непрерывной доставке каждый этап (от слияния изменений кода до поставки готовой сборки) включает в себя автоматизацию тестирования и автоматизацию выпуска кода. В конце процесса операционная группа может быстро и легко развернуть приложение в рабочей среде.

Непрерывное развертывание

Для полноценного конвейера CI/CD последним этапом является непрерывное развертывание. В качестве расширения непрерывной доставки — автоматического выпуска готовых к работе сборок в репозитории кода — непрерывное развертывание может автоматически выпускать приложения в рабочую среду. Поскольку на этапе конвейера перед производством нет ручного управления, непрерывное развертывание в значительной степени зависит от хорошо продуманной автоматизации тестирования.

На практике непрерывное развертывание означает, что изменения, внесенные разработчиком в приложение, вступают в силу в течение нескольких минут после написания (при условии, что оно проходит автоматизированные тесты). Это упрощает постоянное получение и интеграцию отзывов пользователей. В совокупности все эти шаги, связанные с CI/CD, помогают снизить риск развертывания вашего приложения, упрощая выпуск изменений в приложении небольшими частями, а не всеми сразу. Тем не менее, первоначальные вложения по-прежнему значительны, поскольку также необходимо написать автоматизированные тесты для соответствия различным этапам тестирования и выпуска в конвейере CI/CD.

Что такое конвейер Дженкинса?

Jenkins Pipeline (или просто «Конвейер») — это набор подключаемых модулей, которые интегрируют реализацию непрерывной доставки в Jenkins. Конвейер непрерывной доставки автоматизирует процесс непрерывной доставки программного обеспечения на основе контроля версий вашим пользователям и потребителям. Jenkins Pipeline предоставляет расширяемый набор инструментов для реализации процессов доставки «от простого к сложному» в виде «непрерывной доставки как кода». Определения Jenkins Pipeline обычно записываются в текстовый файл (называемыйJenkinsfile), файл можно поместить в репозиторий системы управления версиями проекта.

Во-вторых, установите Дженкинс

Метод установки Jenkins очень прост.Перейдите непосредственно на официальный сайт, чтобы загрузить военный пакет jenkins, найдите сервер для установки Jenkins и заранее установите Tomcat, затем скопируйте пакет War в папку веб-приложений tomcat и запустите сервер tomcat Посетите Jenkins! ! Например: localhost:8080/jenkins/ как показано ниже:

Метод установки Jenkins на основе Docker здесь подробно описываться не будет.


  • Глобальная конфигурация

Войдите в конфигурацию системы, см. следующий рисунок: Настройка каталога склада Jenkins


3. Дженкинс строит пайплайн (Jenkins Pipeline)

Благодаря двум вышеуказанным шагам мы получили простое представление о Jenkins и Jenkins Pipeline и успешно установили Jenkins на сервер, так как же автоматически развернуть проект на Jenkins? Здесь мы демонстрируем конвейерный метод Дженкинса, другие методы демонстрироваться не будут.

1. Создайте новый конвейер

Сначала нажмите на новую задачу слева, вы увидите следующий интерфейс, требуется имя задачи, а тип выбора — конвейер.

2. Настройте конвейер

После того, как пайплайн построен, его необходимо настроить, основная конфигурация показана на следующем рисунке:

Шаг 1: Выберите тип конвейера.

Jenkinsfiles можно писать с использованием двух синтаксисов — декларативного и скриптового. Декларативные и скриптовые конвейеры принципиально отличаются. Декларативный конвейер — это более поздняя функция Jenkins Pipeline: по сравнению со сценарным синтаксисом конвейера он предоставляет более богатые синтаксические функции и предназначен для упрощения написания и чтения кода конвейера.

Шаг 2: Управление конфигурацией программного обеспечения (SCM), выберите Git

Управление конфигурацией программного обеспечения (SCM) относится к обеспечению целостности и прослеживаемости всех элементов конфигурации путем реализации контроля версий, процедур контроля изменений и использования соответствующего программного обеспечения для управления конфигурацией. Управление конфигурацией — это эффективная защита рабочих продуктов.

Шаг 3: Выберите адрес склада хостинга, где находится JenkinsFile.

​ ​ Этот проект размещен в облаке Alibaba. Jenkinsfile – это текстовый файл, содержащий определения Jenkins Pipeline, который зарегистрирован в системе управления версиями.

Шаг 4: Добавьте учетные данные

Зачем нам нужны учетные данные: потому что наш JenkinsFile размещен в облаке Alibaba, поэтому, когда мы указываем источник файла в качестве адреса хостинга Alibaba Cloud, доступ требует контроля разрешений.Здесь мы можем сгенерировать учетные данные в системе и добавить их, как показано на рисунке ниже. Выберите тип учетных данных, вот метод закрытого ключа ssh, конкретная операция заключается в создании открытого ключа и закрытого ключа на любом компьютере, копирование открытого ключа на платформу хостинга кода Alibaba Cloud, вставка закрытого ключа в текстовое поле ниже нажмите После подтверждения добавление сертификата завершено, после чего мы можем выбрать сертификат.

Шаг 5: Укажите путь к скрипту

Весь процесс относится к следующему рисунку:


4. ДженкинсФайл

Теперь, когда мы создали задачу конвейера и базовая конфигурация почти завершена, следующим шагом будет объяснение того, как написать файл сценария JenkinsFile.

​ Мы создали еще одну задачу конвейера в соответствии с вышеуказанными шагами, одна из которых используется как задача сборки, а другая — как задача развертывания.Далее мы увидим, как сценарий сборки и сценарий развертывания пишутся отдельно.

Прежде чем мы начнем писать сценарии, давайте сначала взглянем на библиотеку общей библиотеки Jenkins.

Что такое библиотека?

библиотека является общей библиотекой Jenkins, почему появляется понятие общей библиотеки, потому что, когда мы напишем много файлов сценария JenkinsFile, мы обнаружим, что есть много повторяющихся операций кода сценария, таких как сборка проекта, команды развертывания и некоторые проверки логики, которые очень повторяются, почти в каждом скрипте проекта есть эти коды, поэтому Дженкинс предоставляет концепцию разделяемых библиотек. Общий смысл состоит в том, чтобы извлечь общие части, создать новый проект для управления этими общими кодами сценариев и разместить проект, чтобы мы могли вызывать эту общую библиотеку в файле сценария каждого проекта!

Как создать библиотеку?

Найдите конфигурацию общей библиотеки в глобальной конфигурации Jenkins, как показано ниже:

Первый шаг — указать адрес хостинга проекта общей библиотеки;

Второй шаг — добавить учетные данные. (Логика учетных данных больше не объясняется). Поскольку сценарии общей библиотеки размещаются с помощью средства размещения, для доступа к этим сценариям необходимо добавить учетные данные.

Как писать скрипты сборки

Мы открываем указанный выше файл JenkinsFile для задачи сборки, как показано ниже:

Шаг 1: Укажите имя библиотеки

Шаг 2: Укажите адрес создаваемого проекта, например демонстрационного проекта.

Шаг 3: Укажите имя ветки, которую нужно построить, например qa

Шаг 4: Укажите местоположение встроенного модуля pom.xml, например, demo-parent

Шаг 5: Укажите учетные данные. Учетные данные были подробно описаны выше. Вот учетные данные, необходимые для извлечения демонстрационного проекта. Если демонстрационный проект и файл JenkinsFile размещены в одном месте, например, они оба находятся в Alibaba. Cloud, затем используйте указанные выше учетные данные напрямую.

Шаг 6: Здесь метод сборки вызывает метод, определенный в общей библиотеке.buildМетод сборки специально создан, и параметр карты передается. Ниже приведен скрипт сборки helloword, написанный, и содержимое настроено.

​
def call(map) {
    pipeline {
        agent any
        parameters {
            string(name: 'BRANCH_NAME', defaultValue: "${map.BRANCH_NAME}", description: '选择分支名称')
            string(name: 'POM_FOLDER', defaultValue: "${map.POM_FOLDER}", description: '选择pom文件夹')
        }
        tools {
            maven 'maven 3'
        }
        // 声明全局变量
        environment {
            REPO_URL = "${map.REPO_URL}"
            BRANCH_NAME = "${BRANCH_NAME}"
        }
​
        stages {
            stage('获取代码') {
                steps {
                    echo "========================开始拉取代码========================"
                    git branch: "${BRANCH_NAME}", url: "${REPO_URL}", credentialsId: "${map.PULL_KEY}"
                    echo "代码git地址:" + "${REPO_URL}"
                    echo "分支名称:" + "${BRANCH_NAME}"
                    echo "========================结束拉取代码========================"
                }
            }
​
            stage('编译代码') {
                steps {
                    dir("${map.POM_FOLDER}") {
                        echo "========================开始编译代码========================"
                        sh 'mvn clean install -Dmaven.test.skip=true'
                        echo "========================结束编译代码========================"
                    }
                }
            }
        }
    }
}
​

На этом наша задача сборки завершена. Вы можете перейти на страницу и нажать кнопку «Создать сейчас», чтобы проверить, успешно ли она выполнена. Если она выполнена успешно, мы обнаружим, что jenkins автоматически упаковал пакет для нас.

Как писать сценарии развертывания

Мы успешно подготовили военный пакет, так как же развернуть его на удаленном сервере и как написать этот скрипт?

Точно так же мы открываем указанный файл JenkinsFile для задачи развертывания выше, как показано на следующем рисунке:

Как и в приведенном выше скрипте сборки, некоторые пользовательские параметры передаются, но на этот раз вызов выполняется в общей библиотеке.deployметод, сценарий метода в основном используется для развертывания проекта.

Этот сценарий развертывания является основным содержимым

Мысль 1: Как убить процесс tomcat другого сервера на одном сервере?

Предположим, наш Jenkins установлен на сервере ServerA, а проект, который нужно развернуть, находится на сервере ServerB.Как правило, чтобы убить tomcat вручную, мы посетим ServerB/bin/shutdown.sh, чтобы убить процесс tomcat, так как мы можем работать это удаленно?Потому что в распределенной системе наши проекты развернуты на множестве разных серверов.Идеальное состояние это когда ServerA может удаленно управлять другими серверами и контролировать жизненный цикл кота.Первое что приходит на ум это ssh,поэтому я попробовал настроить вход без пароля.

Обычный метод состоит в том, чтобы скопировать открытый ключ, сгенерированный под пользователем adminuser сервера A, в папку author_keys под пользователем adminuser сервера B, а затем обнаружить, что сервер A успешно входит в систему на сервере B, получив доступ к порту ssh -p adminuser@ip. мы пытаемся получить доступ к команде для ServerA:

​ ​ ​ ​ ssh -p port adminuser@ip /${SERVER_B_TOMCAT_PATH}/bin/shutdown.sh, надеюсь таким способом можно удаленно убить процесс tomcat ServerB, сюрприз в том, что его можно выполнить успешно, так что смело копируем это Строка команды Для сценария Jenkins Pipeline сценарий выглядит следующим образом:

stage('执行shutdown.sh命令') {
                    steps {
                        ssh -p 端口 adminuser@ip  /${SERVER_B_TOMCAT_PATH}/bin/shutdown.sh
                    }
                }

Я думал, что это может быть выполнено гладко, но следующая ошибка Проверка ключа хоста не удалась.

Мысль 2: почему два сервера успешно обмениваются данными, но в Jenkins все еще происходит сбой?

По моему мнению, я думаю, что это должно быть осуществимо, но это все еще не работает, и я чувствую, что у меня все еще нет разрешения на работу. В чем причина? Очевидно, что есть два сервера, которые могут войти в систему без пароля, почему это все еще ограничено.

После проверки данных мы обнаружили, что операция ssh в Jenkins выполняется через учетные данные, поэтому мы сгенерировали учетные данные так же, как и раньше, нажимаем OK, чтобы сгенерировать учетные данные X1, а затем используем подключаемый модуль, предоставленный Jenkins: SSH Agent mode , вставьте сертификат X1 в соответствии с официальным методом следующим образом и обнаружил, что это не удалось

stage('执行shutdown.sh命令') {
                    steps {
                      sshagent ('X1') {
                          ssh -p 端口 adminuser@ip  /${SERVER_B_TOMCAT_PATH}/bin/shutdown.sh
                        }
                    }
                }

Так судя по интернету

stage('执行shutdown.sh命令') {
                    steps {
                      sshagent (credentials: ['X1']) {
                          ssh -p 端口 adminuser@ip  /${SERVER_B_TOMCAT_PATH}/bin/shutdown.sh
                        }
                    }
                }

Я чувствую, что на этот раз это определенно возможно, поэтому обнаружение выполнения все еще является ошибкой.

Host key verification failed.

​!!!!Я хочу плакать без слез!!!!Поэтому мне пришлось снова зайти в Baidu.На этот раз я сделал новое открытие.На самом деле Jenkins был запущен пользователями Jenkins.Мы просто управляли пользователями adminuser сервераA , поэтому мы снова идем в папку пользователя Jenkins, находим папку .ssh и аналогичным образом генерируем учетные данные X2.В это время закрытый ключ в учетных данных заполняется закрытым ключом пользователя jenkins, а затем попробуйте агент SSH:

stage('执行shutdown.sh命令') {
                    steps {
                      sshagent (credentials: ['X2']) {
                          ssh -p 端口 adminuser@ip  /${SERVER_B_TOMCAT_PATH}/bin/shutdown.sh
                        }
                    }
                }

На этот раз я всегда могу добиться успеха, но я обнаружил, что он по-прежнему популярен, и он все еще терпит неудачу: проверка ключа хоста не удалась.

Быстрее быстрее! ! !

Мышление 3: Я иду в неправильном направлении?

​ Наконец, с помощью моих коллег я нашел проблему.Основная причина в том, что у меня нет глубокого понимания принципов SSH, поэтому я продолжаю сообщать об ошибке Проверка ключа хоста не удалась, но он не отвечает что это вызвано SSH.

Основная причина этого в том, что вам нужно проверить ключ хоста при подключении к машине через ssh.Есть два способа: один — изменить конфигурацию ssh StrictHostKeyChecking на no на стороне сервера, другой — использовать текущего пользователя кому нужно войти удаленно.Далее сохраните подпись открытого ключа удаленного сервера.

Что это обозначает?

Вот подробный взгляд на принцип ssh:

SSH обеспечивает вход по паролю и вход с открытым ключом

(источник)

  • пароль логин

Если мы войдем на сервер другой стороны в первый раз, система покажет следующее приглашение:

 $ ssh user@host
​
  The authenticity of host 'host (12.18.429.21)' can't be established.
​
  RSA key fingerprint is 98:2e:d7:e0🇩🇪9f:ac:67:28:c2:42:2d:37:16:58:4d.
​
  Are you sure you want to continue connecting (yes/no)?
​

Смысл этого пассажа в том, что подлинность хоста не может быть подтверждена, известен только его отпечаток открытого ключа.Вы все еще хотите продолжить соединение?

Так называемый «отпечаток открытого ключа» означает, что длина открытого ключа велика (здесь используется алгоритм RSA, до 1024 бит), что сложно сравнивать, поэтому по нему выполняется вычисление MD5, чтобы превратить его в 128-битный отпечаток пальца. В приведенном выше примере это 98:2e:d7:e0🇩🇪9f:ac:67:28:c2:42:2d:37:16:58:4d, и его гораздо проще сравнивать.

Возникает естественный вопрос: откуда пользователь узнает, каким должен быть отпечаток открытого ключа удаленного хоста? Ответ заключается в том, что нет хорошего способа, удаленный хост должен разместить отпечаток открытого ключа на своем собственном веб-сайте, чтобы пользователи могли проверить его самостоятельно.

Предположим, что после оценки риска пользователь решает принять открытый ключ удаленного хоста.

Are you sure you want to continue connecting (yes/no)? yes

В системе появится подсказка, указывающая, что хост был распознан.

Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts.

Затем вас попросят ввести пароль.

Password: (enter password)

Если пароль правильный, вы можете войти в систему.

  • логин с открытым ключом

Чтобы войти с паролем, каждый раз приходится вводить пароль, что очень хлопотно. К счастью, SSH также обеспечивает вход с открытым ключом, что позволяет избежать ввода пароля.

Так называемый «вход с открытым ключом», принцип очень прост, то есть пользователь хранит свой открытый ключ на удаленном хосте. При входе в систему удаленный хост отправляет пользователю случайную строку, а пользователь шифрует ее своим закрытым ключом и отправляет обратно. Удаленный хост выполняет расшифровку с помощью предварительно сохраненного открытого ключа. В случае успеха это доказывает, что пользователь доверенный, и разрешает вход в оболочку напрямую, не требуя пароля.

Этот метод требует, чтобы пользователи предоставили свой собственный открытый ключ. Если нет готового, можно сгенерировать напрямую с помощью ssh-keygen:

$ ssh-keygen

После выполнения вышеуказанной команды в системе появится ряд подсказок, и вы можете нажать Enter до упора. Один из вопросов заключается в том, следует ли установить парольную фразу для закрытого ключа.Если вы беспокоитесь о безопасности закрытого ключа, вы можете установить ее здесь.

После завершения операции в каталоге $HOME/.ssh/ будут сгенерированы два новых файла: id_rsa.pub и id_rsa. Первый — это ваш открытый ключ, а второй — ваш закрытый ключ.

Затем введите следующую команду для передачи открытого ключа на удаленный хост:

$ ssh-copy-id user@host

Что ж, теперь при повторном входе пароль вводить не нужно.


Ссылаясь на приведенную выше информацию, давайте подумаем о нашей собственной ситуации: когда открытый ключ удаленного хоста будет принят, он будет сохранен в файле $HOME/.ssh/known_hosts. В следующий раз, когда вы подключитесь к этому хосту, система распознает, что его открытый ключ был сохранен локально, таким образом, пропустив часть с предупреждением и напрямую запросив пароль. У каждого пользователя SSH есть свой собственный файл known_hosts, поэтому я просмотрел файл known_hosts под пользователем Jenkins и обнаружил, что подпись открытого ключа ServerB не была сохранена, поэтому я скопировал копию подписи открытого ключа ServerB от пользователя adminuser из ServerA, а потом еще раз попробовал, там была задевающая сторона, и все заработало! ! ! ! Принцип относится к следующему рисунку:


Успешный снимок экрана:


Пока наш Jenkins Pipeline можно считать удачным входом, процесс очень ухабистый, а концовка хорошая. Далее следует введение в базовый синтаксис пайплайна, подробно описанный на официальном сайте, это лишь часть.

Пять, синтаксис конвейера

stages

Содержит серию из одной или нескольких директив stage, в разделе stages происходит большая часть «работы» описания конвейера. Рекомендуется, чтобы этапы содержали по крайней мере одну директиву этапа для каждой отдельной части процесса непрерывной доставки, такой как сборка, тестирование и развертывание.

Required Yes
Parameters None
Allowed Only once, inside the pipeline block.
Пример
pipeline {
    agent any
    stages { 
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

steps

Раздел шагов определяет серию из одного или нескольких шагов, которые выполняются в данной директиве этапа.

Required Yes
Parameters None
Allowed Inside each stage block.
Пример
pipeline {
    agent any
    stages {
        stage('Example') {
            steps { 
                echo 'Hello World'
            }
        }
    }
}

инструкция

environment

Директива среды задает последовательность пар ключ-значение, которые будут определены как переменные среды для всех шагов или для конкретных шагов, в зависимости от того, где директива среды находится в конвейере. Эта директива поддерживает специальный вспомогательный метод учетных данных(), который можно использовать для доступа к предопределенным учетным данным по идентификатору в среде Jenkins. Для учетных данных типа «Секретный текст» учетные данные () гарантируют, что указанная переменная среды содержит содержимое секретного текста. Для учетных данных типа «Стандартное имя пользователя и пароль» указанная переменная среды указывается как имя пользователя: пароль, и автоматически определяются две дополнительные переменные среды: MYVARNAME_USR и MYVARNAME_PSW соответственно.

Required No
Parameters None
Allowed Inside the pipeline block, or within stage directives.
Пример
pipeline {
    agent any
    environment { 
        CC = 'clang'
    }
    stages {
        stage('Example') {
            environment { 
                AN_ACCESS_KEY = credentials('my-prefined-secret-text') 
            }
            steps {
                sh 'printenv'
            }
        }
    }
}

Директива среды, используемая в блоке конвейера верхнего уровня, будет применяться ко всем шагам конвейера. Директива среды, определенная на этапе, будет применять заданные переменные среды только к шагам на этапе. В блоке среды определен вспомогательный метод учетных данных(), который можно использовать в среде Jenkins для доступа к предопределенным учетным данным по идентификатору.

options

Директива options позволяет настраивать специфичные для конвейера параметры внутри конвейера. Pipeline предоставляет многие из этих параметров, таких как buildDiscarder, но также может предоставляться плагинами, такими как временные метки.`````

Required No
Parameters None
Allowed Only once, inside the pipeline block.
Доступные Варианты
buildDiscarder为最近的流水线运行的特定数量保存组件和控制台输出。
例如: options { buildDiscarder(logRotator(numToKeepStr: '1')) }
disableConcurrentBuilds不允许同时执行流水线。 可被用来防止同时访问共享资源等。 
例如: options { disableConcurrentBuilds() }
overrideIndexTriggers允许覆盖分支索引触发器的默认处理。 如果分支索引触发器在多分支或组织标签中禁用, 
options { overrideIndexTriggers(true) } 将只允许它们用于促工作。
否则, options { overrideIndexTriggers(false) } 只会禁用改作业的分支索引触发器。
skipDefaultCheckout在`agent` 指令中,跳过从源代码控制中检出代码的默认情况。例如: options { skipDefaultCheckout() }
skipStagesAfterUnstable一旦构建状态变得UNSTABLE,跳过该阶段。例如: options { skipStagesAfterUnstable() }
checkoutToSubdirectory在工作空间的子目录中自动地执行源代码控制检出。例如: options { checkoutToSubdirectory('foo') }
timeout设置流水线运行的超时时间, 在此之后,Jenkins将中止流水线。例如: options { timeout(time: 1, unit: 'HOURS') }
retry在失败时, 重新尝试整个流水线的指定次数。 For example: options { retry(3) }
timestamps预谋所有由流水线生成的控制台输出,与该流水线发出的时间一致。 例如: options { timestamps() }
​
Example
pipeline {
    agent any
    options {
        timeout(time: 1, unit: 'HOURS') 
    }
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}
指定一个小时的全局执行超时, 在此之后,Jenkins 将中止流水线运行。
一个完整的可用选项列表正在等待完成第 INFRA-1503次。 

Варианты сцены

stage
 的 options 指令类似于流水线根目录上的 options 指令。然而, stage -级别 options 只能包括 retry, timeout, 或 timestamps 等步骤, 或与 stage 相关的声明式选项,如 skipDefaultCheckout。在`stage`, options 指令中的步骤在进入 agent 之前被调用或在 when 条件出现时进行检查。
дополнительные опции этапа
skipDefaultCheckout在 agent 指令中跳过默认的从源代码控制中检出代码。例如: options { skipDefaultCheckout() }
timeout设置此阶段的超时时间, 在此之后, Jenkins 会终止该阶段。 例如: options { timeout(time: 1, unit: 'HOURS') }
retry在失败时, 重试此阶段指定次数。 例如: options { retry(3) }
timestamps预谋此阶段生成的所有控制台输出以及该行发出的时间一致。例如: options { timestamps() }
​
Пример
pipeline {
    agent any
    stages {
        stage('Example') {
            options {
                timeout(time: 1, unit: 'HOURS') 
            }
            steps {
                echo 'Hello World'
            }
        }
    }
}
** уточнитьExampleТайм-аут выполнения этапа, по истечении которого Jenkins прервет конвейер.

параметр

parameters`` 指令提供了一个用户在触发流水线时应该提供的参数列表。这些用户指定参数的值可通过 params 对象提供给流水线步骤, 了解更多请参考示例。

Required No
Parameters None
Allowed Only once, inside the pipeline block.
Доступные параметры
string字符串类型的参数, 例如: parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }
booleanParam布尔参数, 例如: parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '') }
​
Пример
pipeline {
    agent any
    parameters {
        string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
    }
    stages {
        stage('Example') {
            steps {
                echo "Hello ${params.PERSON}"
            }
        }
    }
}

курок

triggersДирективы определяют автоматизированный метод повторного запуска конвейера. Может не потребоваться для конвейеров, которые интегрируют такие источники, как GitHub или BitBucket.triggers, так как веб-интеграция, скорее всего, уже существует. Доступные в настоящее время триггеры:cron, pollSCMиupstream.

Required No
Parameters None
Allowed Only once, inside the pipeline block.

cron

Принимает строку в стиле cron для определения регулярного интервала повторного запуска конвейера, например:triggers { cron('H */4 * * 1-5') }

pollSCM

Принимает строку в стиле cron для определения фиксированного интервала, в течение которого Jenkins проверяет наличие новых обновлений исходного кода. Если есть изменения, конвейер перезапускается. Например:triggers { pollSCM('H */4 * * 1-5') }

upstream

Принимает рабочую строку и порог, разделенные запятыми. Конвейер перезапускается, когда любое задание в строке завершается минимальным порогом. Например:triggers { upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS) }

** pollSCMДоступно только в Jenkins 2.22 и выше.
Пример

Jenkinsfile (Declarative Pipeline)

pipeline {
    agent any
    triggers {
        cron('H */4 * * 1-5')
    }
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

stage

stage`` 指令在 stages 部分进行,应该包含一个 实际上, 流水巷所做的所有实际工作都将封装进一个或多个 stage 指令中。

``

Required At least one
Parameters One mandatory parameter, a string for the name of the stage.
Allowed Inside the stages section.
Пример
pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

инструмент

定义自动安装和放置 PATH 的工具的一部分。如果 agent none 指定,则忽略该操作。

Required No
Parameters None
Allowed Inside the pipeline block or a stage block.
Инструменты поддержки

maven

jdk

gradle

Пример
pipeline {
    agent any
    tools {
        maven 'apache-maven-3.0.1' 
    }
    stages {
        stage('Example') {
            steps {
                sh 'mvn --version'
            }
        }
    }
}

input

stage`` 的 input 指令允许你使用 ```[input` step提示输入。 在应用了 options 后,进入 stage 的 agent 或评估 when 条件前,stage 将暂停。 如果 input 被批准, stage 将会继续。 作为 input 提交的一部分的任何参数都将在环境中用于其他 stage。](Jenkins.IO/doc/pipe lin...)

элемент конфигурации
message必需的。 这将在用户提交 input 时呈现给用户。
idinput 的可选标识符, 默认为 stage 名称。
ok`input`表单上的"ok" 按钮的可选文本。
submitter可选的以逗号分隔的用户列表或允许提交 input 的外部组名。默认允许任何用户。
submitterParameter环境变量的可选名称。如果存在,用 submitter 名称设置。
parameters提示提交者提供的一个可选的参数列表。 更多信息参见 [parameters]。
​
Пример
pipeline {
    agent any
    stages {
        stage('Example') {
            input {
                message "Should we continue?"
                ok "Yes, we should."
                submitter "alice,bob"
                parameters {
                    string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
                }
            }
            steps {
                echo "Hello, ${PERSON}, nice to meet you."
            }
        }
    }
}

when

when`` 指令允许流水线根据给定的条件决定是否应该执行阶段。 when 指令必须包含至少一个条件。 如果 when 指令包含多个条件, 所有的子条件必须返回True,阶段才能执行。 这与子条件在 allOf 条件下嵌套的情况相同 (参见下面的示例)。使用诸如 not, allOf, 或 anyOf 的嵌套条件可以构建更复杂的条件结构 can be built 嵌套条件刻意潜逃到任意深度。

Required No
Parameters None
Allowed Inside a stage directive
Встроенное состояние
branch当正在构建的分支与模式给定的分支匹配时,执行这个阶段, 例如: when { branch 'master' }。注意,这只适用于多分支流水线。
environment当指定的环境变量是给定的值时,执行这个步骤, 例如: when { environment name: 'DEPLOY_TO', value: 'production' }
expression当指定的Groovy表达式评估为true时,执行这个阶段, 例如: when { expression { return params.DEBUG_BUILD } }
not当嵌套条件是错误时,执行这个阶段,必须包含一个条件,例如: when { not { branch 'master' } }
allOf当所有的嵌套条件都正确时,执行这个阶段,必须包含至少一个条件,例如: when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
anyOf当至少有一个嵌套条件为真时,执行这个阶段,必须包含至少一个条件,例如: when { anyOf { branch 'master'; branch 'staging' } }
在进入 stage 的 agent 前评估 when默认情况下, 如果定义了某个阶段的代理,在进入该`stage` 的 agent 后该 stage 的 when 条件将会被评估。但是, 可以通过在 when 块中指定 beforeAgent 选项来更改此选项。 如果 beforeAgent 被设置为 true, 那么就会首先对 when 条件进行评估 , 并且只有在 when 条件验证为真时才会进入 agent 。
​
Пример
pipeline {
    agent any
    stages {
        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        stage('Example Deploy') {
            when {
                branch 'production'
            }
            steps {
                echo 'Deploying'
            }
        }
    }
}

Jenkinsfile (Declarative Pipeline)

pipeline {
    agent any
    stages {
        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        stage('Example Deploy') {
            when {
                branch 'production'
                environment name: 'DEPLOY_TO', value: 'production'
            }
            steps {
                echo 'Deploying'
            }
        }
    }
}


Jenkinsfile (Declarative Pipeline)

pipeline {
    agent any
    stages {
        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        stage('Example Deploy') {
            when {
                allOf {
                    branch 'production'
                    environment name: 'DEPLOY_TO', value: 'production'
                }
            }
            steps {
                echo 'Deploying'
            }
        }
    }
}


Jenkinsfile (Declarative Pipeline)

pipeline {
    agent any
    stages {
        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        stage('Example Deploy') {
            when {
                branch 'production'
                anyOf {
                    environment name: 'DEPLOY_TO', value: 'production'
                    environment name: 'DEPLOY_TO', value: 'staging'
                }
            }
            steps {
                echo 'Deploying'
            }
        }
    }
}


Jenkinsfile (Declarative Pipeline)

pipeline {
    agent any
    stages {
        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        stage('Example Deploy') {
            when {
                expression { BRANCH_NAME ==~ /(production|staging)/ }
                anyOf {
                    environment name: 'DEPLOY_TO', value: 'production'
                    environment name: 'DEPLOY_TO', value: 'staging'
                }
            }
            steps {
                echo 'Deploying'
            }
        }
    }
}


Jenkinsfile (Declarative Pipeline)

pipeline {
    agent none
    stages {
        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        stage('Example Deploy') {
            agent {
                label "some-label"
            }
            when {
                beforeAgent true
                branch 'production'
            }
            steps {
                echo 'Deploying'
            }
        }
    }
}


параллельно

声明式流水线的阶段可以在他们内部声明多隔嵌套阶段, 它们将并行执行。 注意,一个阶段必须只有一个 steps 或 parallel 的阶段。 嵌套阶段本身不能包含进一步的 parallel 阶段, 但是其他的阶段的行为与任何其他 stage 相同。任何包含 parallel 的阶段不能包含 agent 或 tools 阶段, 因为他们没有相关 steps。另外, 通过添加 failFast true 到包含 parallel`stage , вы можете принудительно завершить все параллельные этапы при сбое одного из процессов.

Пример

pipeline {
    agent any
    stages {
        stage('Non-Parallel Stage') {
            steps {
                echo 'This stage will be executed first.'
            }
        }
        stage('Parallel Stage') {
            when {
                branch 'master'
            }
            failFast true
            parallel {
                stage('Branch A') {
                    agent {
                        label "for-branch-a"
                    }
                    steps {
                        echo "On Branch A"
                    }
                }
                stage('Branch B') {
                    agent {
                        label "for-branch-b"
                    }
                    steps {
                        echo "On Branch B"
                    }
                }
            }
        }
    }
}


шаг

Декларативные конвейеры могут использоваться вСправочник по этапам конвейераВсе доступные шаги задокументированы в , который содержит полный список шагов с добавлением перечисленных ниже шагов, которые доступны только в декларативном конвейере.only supported.

сценарий

scriptШаг требует [scripted-pipeline]блокировать и выполнять в декларативном конвейере. В большинстве случаев шаг «скрипт» в декларативном конвейере не нужен, но он может обеспечить полезный «уход». нетривиального размера и/или сложностиscriptблок должен быть перемещен вобщая библиотека.

Пример

Jenkinsfile (Declarative Pipeline)

pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'

                script {
                    def browsers = ['chrome', 'firefox']
                    for (int i = 0; i < browsers.size(); ++i) {
                        echo "Testing the ${browsers[i]} browser"
                    }
                }
            }
        }
    }
}



скриптовый конвейер

Сценарий конвейера с [declarative-pipeline]То же самое, он построен на подсистеме нижележащего конвейера. В отличие от декларативных, скриптовые конвейеры на самом делеGroovyОбщий DSL для сборки [2]. Большая часть функций, предоставляемых языком Groovy, доступна пользователям скриптовых конвейеров. Это означает, что это очень выразительный и гибкий инструмент для написания конвейеров непрерывной доставки.

управление потоком

Сценарий конвейера изJenkinsfileВерхняя часть скрипта начинает последовательно выполняться вниз, как и большинство традиционных скриптов на Groovy или других языках. Следовательно, обеспечение управления потоком зависит от выражений Groovy, таких какif/elseусловия, такие как:

Jenkinsfile (Scripted Pipeline)

node {
    stage('Example') {
        if (env.BRANCH_NAME == 'master') {
            echo 'I only execute on the master branch'
        } else {
            echo 'I execute elsewhere'
        }
    }
}


Другой подход заключается в использовании поддержки обработки исключений Groovy для управления потоком конвейера по сценарию. когдашагВ случае сбоя по какой-либо причине они выдают исключение. При обработке ошибок необходимо использовать Groovytry/catch/finallyблок, например:

Jenkinsfile (Scripted Pipeline)