[Перевод] Как настроить непрерывную интеграцию в Jenkins при отправке изменений в репозиторий

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

Мы будем интегрировать Jenkins с GitHub, чтобы Jenkins получал уведомления, когда новый код загружается в репозиторий. Когда Jenkins получит уведомление, он проверит код, а затем протестирует его в контейнерах Docker, чтобы изолировать тестовую среду от хост-машины Jenkins. В качестве примера будем использовать приложение Node.js. 

94546913c577685e9f43829494ccf100.jpg

Важно: в рамках этой статьи мы не рассматриваем инсталляцию Jenkins. Узнать, как установить и зайти в веб-интерфейс Jenkins можно здесь.

Вам понадобится

  • настроить для безопасной установки Jenkins сервер Ubuntu 20.04 с объёмом оперативной памяти не менее 1 ГБ;

  • назначить доменное имя сервера Jenkins для защиты веб-интерфейса;

  • установить Docker на сервер после запуска Jenkins (чтобы лучше контролировать среду тестирования). 

«CI/CD c Jenkins»

Добавьте Jenkins User в группу Docker

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

Чтобы исправить это, добавим пользователя jenkins в группу docker с помощью команды usermod:

sudo usermod -aG docker jenkins

Можем перечислить членов группы docker, чтобы подтвердить, что пользователь jenkins  успешно добавлен:

grep docker /etc/group

ece2396f246fcfb70e6308b55e00707b.png

Чтобы Jenkins мог воспользоваться новыми привилегиями, перезапустим его:

sudo systemctl restart jenkins

Если вы устанавливали Jenkins с плагинами по умолчанию, возможно, потребуется проверить, включены ли плагины docker и docker-pipeline. Для этого нажмите »Manage Jenkins» на боковой панели, а затем »Manage Plugins» в меню. Нажмите на »Available» во вкладке плагинов и введите docker в строке поиска. Если в качестве параметров возвращаются и Docker Pipeline, и Docker plugin, но они не выбраны, выберите оба и при появлении запроса разрешите перезапуск Jenkins с включенными плагинами.

cf0fd70bcb73a87dc128ab618884b087.png

Это займёт около минуты, затем страница обновится.

Создайте токен персонального доступа в GitHub

Чтобы Jenkins мог отслеживать ваши проекты в GitHub, нужно создать токен персонального доступа в учётной записи GitHub.

Начнём с входа в учётную запись. Затем нажмём на значок пользователя в правом верхнем углу и выберем «Settings» в выпадающем меню:

57a000525db4c612f2080b7073ab00dc.png

Найдём раздел «Developer settings» в левом меню и выберем «Personal access tokens»:

fae1e8c670464edeff032480bba06a1b.png

Нажмём «Generate new token»:

0486a90cbe47fb504c74b9c4e8c02128.png

После этого мы попадём на страницу, где сможем определить область действия нового токена. В поле «Token Description» добавим описание, которое позволит нам распознать его позже:

4a5ba91fcbf42d1a960a10c2c43c2f4d.png

В разделе «Select scopes» установим флажки repo: status, repo: public_repo и admin: org_hook. Это позволит Jenkins обновлять коммиты и создавать вебхуки. Если вы используете частный репозиторий, нужно выбрать общее разрешение repo вместо подэлементов:

ce4c6bf241b2d91ae251afffdbe62e3a.png

После нажмём «Generate token». Нас перенаправит обратно на страницу «Personal access tokens», и на экране появится новый токен:

02d18d120c42e5ea22819a41aba14dbd.png

Скопируем токен сразу, чтобы мы могли ссылаться на него позже. 

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

Теперь, когда у нас есть токен персонального доступа в учётной записи GitHub, можем настроить Jenkins для просмотра репозитория проекта.

Добавьте токен персонального доступа GitHub к Jenkins

Нам нужно добавить токен на сервер Jenkins, чтобы он мог автоматически настраивать вэбхуки. Для этого войдём в веб-интерфейс Jenkins, используя учётную запись администратора.

Нажмём на имя пользователя в правом верхнем углу, чтобы получить доступ к настройкам, и оттуда выберем Credentials в меню слева:

b7415db16be9b40a178eaabe22e9185b.png

На следующей странице наведём стрелку рядом с (global) в области Jenkins. В появившемся окне кликнем на «Add credentials»:

42b727540575c1aed8c10aa25148054f.png

Мы перейдём к форме для добавления новых учётных данных.

В выпадающем меню «Kind» выберем «Secret text». В поле «Secret» вставим токен персонального доступа к GitHub. Заполним поле описания, чтобы мы могли идентифицировать эту запись позже. Также вы можете оставить Scope как Global, а поле ID пустым:

e9629b8a13cedf8f5dd4b1e7672c1971.png

По завершению нажмём кнопку «ОК». Теперь можем ссылаться на эти учётные данные из других частей Jenkins для помощи в настройке.

Настройте доступ Jenkins к GitHub

Вернёмся на главную панель управления Jenkins и нажмём «Manage Jenkins» в меню слева:

eb85386c0d7a096fddf4c387e41c56dd.png

В списке ссылок на следующей странице выберем «Configure System»:

ce0d5514f23ecd5a455defa88b9194ae.png

Найдём раздел «GitHub». Нажмём кнопку «Add GitHub Server», а затем выберем «GitHub Server»:

904fb52a3623da417d6834608bc8a658.png

Раздел расширится, чтобы запросить дополнительную информацию. В меню «Credentials drop» выберем свой токен персонального доступа GitHub, который добавили ранее:

c893089004b883fc1b9175a11770c720.png

Нажмём кнопку «Test connection». Jenkins выполнит тестовый вызов API для нашей учётной записи и проверит подключение:

3e8086bf214d90e769d85e65095aa8ca.png

По окончанию нажмём кнопку «Save», чтобы сохранить изменения.

Настройте демонстрационное приложение в учётной записи GitHub

Чтобы продемонстрировать, как использовать Jenkins для тестирования приложения, будем использовать программу hello world, созданную с Hapi.js. Поскольку мы настраиваем Jenkins для реагирования на запросы в репозиторий, нужна отдельная копия демонстрационного кода.

Перейдём в репозиторий проекта и нажмём кнопку »Fork» в правом верхнем углу, чтобы создать копию репозитория в своей учётной записи:

11adb1457d529cb9bdffacdb4109c5ea.png

Копия репозитория добавится в вашу учётную запись.

Репозиторий содержит файл package.json, который определяет зависимости среды выполнения и разработки, а также способ запуска выбранного набора тестов. Зависимости можно установить с помощью npm install, а тесты — с помощью npm test.

Также добавим Jenkinsfile  в репозиторий. Jenkins считает этот файл, чтобы определить действия, которые нужно выполнить с репозиторием для сборки, тестирования или развертывания. Он написан с использованием декларативной версии Jenkins Pipeline DSL.

Jenkinsfile, включенный в репозиторий hello-hapi, выглядит так:

#!/usr/bin/env groovy

pipeline {

    agent {
        docker {
            image 'node'
            args '-u root'
        }
    }

    stages {
        stage('Build') {
            steps {
                echo 'Building...'
                sh 'npm install'
            }
        }
        stage('Test') {
            steps {
                echo 'Testing...'
                sh 'npm test'
            }
        }
    }
}

Пайплайн содержит полное определение, которое будет оценивать Дженкинс. Внутри у нас есть раздел agent, указывающий, где будут выполняться действия в пайплайне. Чтобы изолировать среды от хост-системы, будем тестировать в контейнерах Docker, указанных docker  агентом.

Поскольку Hapi.js — это фреймворк для Node.js, будем использовать образ ноды Docker в качестве основы. Укажем пользователя root внутри контейнера, чтобы пользователь мог одновременно записывать как на подключенный том, содержащий извлеченный код, так и на том, на который скрипт записывает свои выходные данные.

Далее в файле определяются два этапа — логическое разделение работы. Назовём первый «Build», а второй «Test». На этапе сборки выводится диагностическое сообщение, а затем выполняется npm install для получения требуемых зависимостей. Шаг тестирования выводит другое сообщение, а затем запускает тесты, как указано в файле package.json.

Теперь, когда у нас есть репозиторий с Jenkinsfile, можем настроить Jenkins для наблюдения за этим репозиторием и запуска файла при внесении изменений.

Создайте новый пайплайн в Jenkins

Далее настроим Jenkins на использование токена персонального доступа GitHub для просмотра нашего репозитория. Вернёмся на главную панель управления Jenkins, выберем «New Item» в меню слева:

efeabb27b64ae1f1c452ba21d27f676e.png

Введём имя для нового пайплайна в поле «Enter an item name». После выберем Pipeline в качестве типа элемента:

caee9348114563527fd2e7fbbfed719f.png

Нажмём кнопку «ОК» внизу, чтобы двигаться дальше.

На следующем экране установим флажок «GitHub project». В появившемся поле «Project url» введём URL репозитория проекта на GitHub.

Примечание: обязательно укажите свою ветку приложения Hello Hapi, чтобы у Jenkins было разрешение на настройку вэбхуков.

09564019998df0d713ff443947008dcd.png

В разделе «Build Triggers» установим флажок «GitHub hook trigger for GITScm polling»:

42a53be3f36d1f97bdaffef6876c34ab.png

В разделе «Pipeline» нужно сказать Jenkins запустить пайплайн, определённый в Jenkinsfile в нашем репозитории. Изменим тип определения на «Pipeline script from SCM».

В появившемся новом разделе выберем «Git» в меню «SCM». В появившемся поле «Repository URL» снова введём URL-адрес нашей ветки репозитория:

fafee1367e8e77e2a737ce49d87d1321.png

Примечание: приведённый пример ссылается на Jenkinsfile из общедоступного репозитория. Если ваш проект не является общедоступным, нужно использовать кнопку »add credentials», чтобы добавить дополнительный доступ к репозиторию. Вы можете добавить токен персонального доступа, как мы сделали с конфигурацией hooks ранее.

По окончанию нажмём кнопку «Save» в нижней части страницы.

Выполните начальную сборку и настройку вэбхуков

Jenkins не настраивает автоматически вэбхуки, когда мы определяем пайплайн для репозитория в интерфейсе. Чтобы заставить Jenkins настроить соответствующие хуки, нужно в первый раз выполнить сборку вручную. На главной странице пайплайна нажмём «Build Now» в меню слева:

f4ad819c45c96521be768f465e5bc49d.png

Будет запланирована новая сборка. В окне «Build History» в левом нижнем углу через мгновение появится новая сборка. Кроме того, в основной области интерфейса начнёт отображаться «Stage View». Это позволит отслеживать ход тестового запуска по мере завершения различных этапов:

В поле «Build History» щёлкнем по номеру, связанному со сборкой, чтобы перейти на страницу сведений о сборке. Здесь можем нажать кнопку «Console Output» в меню слева, чтобы просмотреть подробную информацию о выполненных шагах:

Далее выберем «Back to Project» в меню слева, чтобы вернуться к основному просмотру пайплайна. Теперь, когда мы создали проект вручную, можем попросить Jenkins создавать вэбхуки самостоятельно. Нажмём кнопку «Configure» в меню слева:

Никаких изменений не требуется, просто нажмём кнопку «Save». Теперь, когда у Jenkins есть информация о проекте из первоначального процесса сборки, он зарегистрирует вэбхук в нашем проекте GitHub при сохранении страницы.

Можем убедиться в этом — зайдём в свой репозиторий GitHub и нажмём кнопку «Settings». Затем выберем выберите «Webhooks» в боковом меню. Мы должны увидеть вэбхук сервера Jenkins в главном интерфейсе:

Если по какой-либо причине Jenkins не удалось зарегистрировать хук (например, из-за изменений API или перебоев между Jenkins и Github), можем быстро добавить его самостоятельно, нажав «Add webhook» и убедившись, что для «Payload URL» установлено значение https://my-jenkins-server:8080/github-webhook, а для «Content type» — application/json. Затем снова нажмём «Add webhook».

Ваш url может отличаться в зависимости от того, какое доменное имя вы используете — IP-адрес или localhost. Подробнее

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

Далее на странице нашего репозитория на GitHub нажмём кнопку «Create new file» слева от зеленой кнопки «Clone or download»:

Выберем имя файла и некоторое фиктивное содержимое:

И нажмём кнопку »Commit new file» внизу.

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

Заключение

В статье мы настроили Jenkins для просмотра проекта GitHub и автоматического тестирования любых новых изменений. Jenkins извлекает код из репозитория, а затем запускает процедуры сборки и тестирования из изолированных контейнеров Docker. Полученный код можно развернуть или сохранить, добавив дополнительные инструкции в тот же файл Jenkinsfile.

«CI/CD c Jenkins»

© Habrahabr.ru