Статьи

Повторное знакомство с Jenkins: автоматизированное тестирование с конвейерами

Эта статья была рецензирована Кристофером Томасом и Питером Найссеном . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!


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

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

  1. Запустите composer install чтобы убедиться, что зависимости установлены
  2. Запустите php -l каждого PHP-файла в базе кода, чтобы проверить наличие синтаксических ошибок.
  3. Запустите PHPUnit для модульного тестирования
  4. Запустите Codeception для функционального тестирования

Логотип Дженкинс

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

Чтобы помочь преодолеть это, вы можете ввести сервер сборки в свой рабочий процесс разработки. На сервере сборки запускается часть программного обеспечения, которая позволяет вам снова и снова запускать серию шагов в фоновом режиме, и в случае сбоя одного из шагов сервер сборки может сообщить вам о проблеме. Если вы участвовали в проекте с открытым исходным кодом, возможно, вы видели сервер сборки, такой как TravisCI или CircleCI, в действии. Например, каждый запрос на извлечение проекта Laravel проверяется TravisCI, чтобы убедиться, что изменение не нарушает никаких тестов, а затем StyleCI гарантирует, что изменение кода соответствует стилю кода проекта.

Laravel-checks.png

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

Конвейер — это набор полностью настраиваемых шагов, которые можно выполнить для тестирования и сборки кода. Конвейеры написаны на языке сценариев Groovy, который имеет очень простой синтаксис, с которым легко освоиться. Например, если вы хотите описать шаги тестирования, описанные ранее, как конвейер, это может выглядеть примерно так:

 node { stage("composer_install") { sh 'composer install' } stage("php_lint") { sh 'find . -name "*.php" -print0 | xargs -0 -n1 php -l' } stage("phpunit") { sh 'vendor/bin/phpunit' } stage("codeception") { sh 'vendor/bin/codecept run' } } 

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

Из этого простого примера вы можете легко добавить дополнительные этапы в другие тесты, сказать Jenkins, чтобы они отправляли уведомление Slack об успешных или неудачных сборках, помещать успешно протестированный код в ветку релиза или помечать запрос на извлечение как хороший для объединения.

Установка Дженкинс

Jenkins очень прост в установке, и в этом уроке мы будем использовать Laravel Homestead, чтобы создать согласованную виртуальную среду, чтобы вы могли играть с Jenkins локально.

Первым шагом является установка Laravel Homestead — здесь есть полезное руководство . Вам нужно только запустить и запустить виртуальную машину, нам не нужно настраивать сайты в файле homestead.yaml .

Когда ваша виртуальная машина Homestead запущена и работает, используйте SSH с помощью vagrant ssh .

Homestead поставляется со всеми необходимыми нам зависимостями, а именно Git, PHP и Composer, поэтому нам просто нужно установить Jenkins сам. Следуя руководству по пакету Jenkins Debian, мы должны выполнить следующие шаги.

Запустите wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add - wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add - . Эта команда добавляет ключ подписи кода в Aptitude, чтобы пакеты Jenkins из этого хранилища были доверенными.

Затем необходимо обновить список источников пакетов, чтобы Aptitude знал о репозитории пакетов Jenkins. Выполнить echo "deb https://pkg.jenkins.io/debian-stable binary/" | sudo tee -a /etc/apt/sources.list echo "deb https://pkg.jenkins.io/debian-stable binary/" | sudo tee -a /etc/apt/sources.list .

Наконец, нам нужно Aptitude обновить свой кеш доступных пакетов, а затем установить Jenkins:

 sudo apt-get update && sudo apt-get install jenkins 

Установка Jenkins займет около пяти минут, так как она имеет множество зависимостей, которые также необходимо установить.

После установки Jenkins откройте http://192.168.10.10:8080 в своем браузере (или URL-адрес, настроенный для вашего виртуального хоста, например homestead.app ), и вы увидите страницу под названием «Unlock Jenkins».

Разблокировка-jenkins.png

Внутри виртуальной машины выполните следующую команду — sudo cat /var/lib/jenkins/secrets/initialAdminPassword и на консоль будет sudo cat /var/lib/jenkins/secrets/initialAdminPassword случайная строка цифр и букв. Скопируйте и вставьте эту строку в текстовое поле в браузере и нажмите «Продолжить» .

подгоняет-jenkins.png

Вам будет предложено два варианта — выберите «Установить предлагаемые плагины» и подождите несколько минут, пока плагины будут загружены и установлены.

создание-админ-User.png

На следующем экране введите данные пользователя-администратора и нажмите «Сохранить и завершить» .

Дженкинс-dashboard.png

Jenkins теперь установлен и настроен!

Создание вашей первой работы

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

  1. Проверьте последнюю сборку laravel/framework
  2. Установите зависимости Composer
  3. Запустите PHPUnit

Нажмите ссылку «Создать новые рабочие места» на панели инструментов (или ссылку «Новый элемент» — они оба выполняют одно и то же).

создавать новые-item.png

Введите имя laravel , выберите «Трубопровод», затем нажмите «ОК» .

Теперь вы увидите редактор конфигурации для работы. Прокрутите вниз до раздела Конвейер и введите следующий скрипт:

 node { stage('preparation') { // Checkout the master branch of the Laravel framework repository git branch: 'master', url: 'https://github.com/laravel/framework.git' } stage("composer_install") { // Run `composer update` as a shell script sh 'composer install' } stage("phpunit") { // Run PHPUnit sh 'vendor/bin/phpunit' } } 

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

первый-build.png

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

Если вы щелкнете по этапу, появится наложение с выводом журнала для этого этапа, что действительно полезно для отладки. Кроме того, вы можете нажать на задание в левом меню и нажать «Консоль» .

Все задания Jenkins имеют свое собственное рабочее пространство, в котором вы можете безопасно создавать любые временные файлы, которые могут вам понадобиться как часть вашей области сборки. Расположение рабочей области для этой работы можно найти в /var/lib/jenkins/workspace/laravel . По умолчанию Jenkins не очищает это рабочее пространство для каждой сборки. Если вам нужно это сделать, вы можете добавить этап в начало сценария конвейера следующим образом:

 stage('cleanup') { // Recursively delete all files and folders in the workspace // using the built-in pipeline command deleteDir() } 

Дженкинсфайл

Для нашей первой работы мы отредактировали конвейерный скрипт в интерфейсе настроек задания. Однако было бы гораздо полезнее сохранить этот скрипт вместе с нашим кодом в управлении версиями.

С помощью конвейеров Jenkins вы можете написать свой конвейер в виде сценария Jenkinsfile в корне репозитория вашего кода, который будет обнаружен и запущен. По своей .travis.yml .circleci.yml файл .travis.yml или .circleci.yml которым вы, возможно, уже знакомы.

На странице проекта laravel / framework Github нажмите кнопку «fork» в правом верхнем углу, а затем нажмите на свой профиль во всплывающем окне.

Создайте новую ветку с именем jenkinsfile , затем создайте новый файл (вы можете сделать это прямо в Github, вам не нужно клонировать репозиторий, если вы этого не хотите).

создание-jenkinsfile.png

Введите следующий скрипт и зафиксируйте файл:

 node { stage("composer_install") { // Run `composer update` as a shell script sh 'composer install' } stage("phpunit") { // Run PHPUnit sh 'vendor/bin/phpunit' } } 

Теперь вернитесь к Дженкинсу и нажмите кнопку «Настроить» в меню слева. Прокрутите вниз до раздела Конвейер и обновите выпадающий список «Определение» до Pipeline script from SCM .

газопровод-с-scm.png

Введите данные для вашего разветвленного хранилища, затем нажмите «Сохранить» .

второй-build.png

На экране обзора работ нажмите «Построить сейчас» в меню слева. Вы должны иметь успешную сборку.

Многоотраслевые трубопроводные проекты

Большинство программных проектов используют несколько веток в хранилище для определения различных этапов проекта. Например:

  • Основная ветвь представляет текущий выпуск продукции
  • Ветвь develop представляет текущий промежуточный выпуск
  • Ветвь feature/new-profile-page может представлять функцию незавершенного производства.

Для каждой ветви вам может потребоваться выполнить ряд пользовательских действий — например, когда есть фиксация master или develop ветви, вы хотите, чтобы выполнялся полный набор тестов модульных и интеграционных тестов, тогда как во всех других ветвях только модульные тесты. достаточно.

Jenkinsfile написан на языке программирования Groovy, что означает, что у нас есть полноценный язык сценариев, с которым можно играть.

В этом примере я добавил оператор if для проверки имени ветви; если это master или develop , то Дженкинс должен запустить этап integration_tests .

После этого есть оператор switch, который в зависимости от имени ветви создает другой архив развертывания и регистрирует его в службе развертывания кода (в этом примере я демонстрирую, как это будет работать со службой CodeDeploy веб-службы Amazon).

 node { stage("composer_install") { // Run `composer update` as a shell script sh 'composer update' } stage("phpunit") { // Run PHPUnit sh 'vendor/bin/phpunit' } // If this is the master or develop branch being built then run // some additional integration tests if (["master", "develop"].contains(env.BRANCH_NAME)) { stage("integration_tests") { sh 'vendor/bin/behat' } } // Create new deployment assets switch (env.BRANCH_NAME) { case "master": stage("codedeploy") { sh "aws deploy push --application-name My_App_Production --s3-location s3://my-app-production/build-${env.BUILD_NUMBER}.zip" } break case "develop": stage("codedeploy") { sh "aws deploy push --application-name My_App_Staging --s3-location s3://my-app-staging/build-${env.BUILD_NUMBER}.zip" } break default: // No deployments for other branches break } } 

Задания многоотраслевого конвейера так же легко настроить — при создании проекта выберите «Многоотраслевой конвейер» в качестве типа:

Многоотраслевая-pipeline.png

Затем на экране конфигурации установите раскрывающийся список определения Pipeline script from SCM и введите сведения о хранилище.

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

Вещи дальше

Дженкинс во многом обязан своей популярности обширной экосистеме плагинов.

На главном экране Jenkins нажмите «Управление Jenkins» в меню слева, затем нажмите «Менеджер плагинов».

Дженкинс-plugins.png

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

Например, если ваша команда использует Slack, вы можете включить плагин Slack Notification . Настройте его на главном экране настроек Jenkins ( «Управление Jenkins» -> «Настроить систему» ), после чего вы сможете отправлять сообщения Slack как часть вашего конвейерного скрипта:

 node { slackSend color: '#4CAF50', channel: '#devops', message: "Started ${env.JOB_NAME} (<${env.BUILD_URL}|build ${env.BUILD_NUMBER}>)" try { stage("composer_install") { // Run `composer update` as a shell script sh 'composer update' } stage("phpunit") { // Run PHPUnit sh 'vendor/bin/phpunit' } slackSend color: '#4CAF50', channel: '#devops', message: "Completed ${env.JOB_NAME} (<${env.BUILD_URL}|build ${env.BUILD_NUMBER}>) successfully" } catch (all) { slackSend color: '#f44336', channel: '#devops', message: "Failed ${env.JOB_NAME} (<${env.BUILD_URL}|build ${env.BUILD_NUMBER}>) - <${env.BUILD_URL}console|click here to see the console output>" } } 

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

Для проектов Github убедитесь, что плагин Github установлен и включен, а затем в настройках своего репозитория Github включите интеграцию сервиса со службой «Jenkins (плагин Github)».

Для Bitbucket это немного сложнее, и я подробно описал шаги, необходимые для моего блога .

Вы также должны убедиться, что ваш сервер Jenkins должным образом защищен — вы можете либо создать пользователей в Jenkins вручную, делегировать аутентификацию на Github или Bitbucket с помощью OAuth или подключить Jenkins к каталогу LDAP вашей организации. Аналогично, вы всегда должны запускать Jenkins через SSL, чтобы ваш доступ к Jenkins не мог быть легко перехвачен.

Ваша установка Jenkins также поставляется с «Генератором фрагментов», который позволяет вам просматривать все включенные функции конвейера (такие как sh , slackSend , deleteDir() и slackSend , которые мы уже использовали). Вы можете найти ссылку на нее в левом меню на экране обзора работы.

Резюме

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

Если ваша команда замедляется тестами, выполнение которых занимает более пяти минут, перенесите это тестирование на Дженкинса.

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

Если вы хотите следить за качеством кода и отслеживать регрессию раньше, чем ваши клиенты, то Jenkins готова помочь.

Пожалуйста, оставляйте любые вопросы или комментарии ниже, и расскажите нам о ваших самых креативных конвейерах Jenkins!