Основные сведения о CI/CD-пайплайнах

Если вы знакомы с понятиями непрерывной интеграции, доставки и развертывания, которые вместе обозначаются сокращением CI/CD, то наверняка уже сталкивались с термином «автоматизированный пайплайн» и знаете, что он играет ключевую роль в реализации концепции CI/CD. Давайте разберемся, что же такое пайплайн непрерывной интеграции и доставки и как его создать.

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

Что такое CI/CD-пайплайн?

Говоря о CI/CD-пайплайне мы подразумеваем ряд этапов, через которые проходит код: от выхода с компьютера разработчика через тестирование вплоть до доставки пользователями.

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

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

Этапы билд-пайплайна

Конкретная конфигурация вашего CI/CD-пайплайна зависит от типа продукта, который вы разрабатываете, и от требований вашей организации, однако есть общие для всех пайплайнов принципы, которые мы описываем ниже.

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

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

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

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

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

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

Теперь давайте подробнее рассмотрим некоторые аспекты каждого из этапов.

Флаги и ветки

Первый шаг к внедрению непрерывной интеграции — перенос всей кодовой базы в систему контроля версий, например в Git, Mercurial или Perforce. После этого всем членам команды нужно выработать привычку часто делать коммиты изменений. Каждый коммит в ветку master запускает пайплайн, сборку и тестирование нового кода, позволяя быстро получить обратную связь.

Частые коммиты — важный аспект CI/CD, но, если работа над какой-то большой функцией занимает несколько дней или даже недель, регулярные коммиты до завершения работы могут оказаться палкой о двух концах.

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

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

Обойти эту проблему помогут флаги и функциональные ветки. Флаги позволяют выбрать среды, в которых пользователи увидят ваш код. Изменения по-прежнему отправляются в ветку master и видны всей команде, но вы можете решить, в какой момент функция станет доступна в тестовой и производственной среде.

Используя функциональные ветки, можно разрабатывать функцию в отдельной ветке, пользуясь всеми преимуществами автоматической сборки и тестирования. Запуская CI/CD-пайплайн при каждом коммите в функциональную ветку, как при коммите в master, можно быстро получить обратную связь по новой сборке.

Сборки и тесты

После запуска нового экземпляра пайплайна при коммите следующие этапы — сборка и тестирование. Автоматизированные юнит-тесты, как правило, запускаются перед сборкой вместе с проверками кода и статическим анализом.

Используемые инструменты сборки (например, Ant или Maven) и особенности шагов сборки зависят от конкретного языка и фреймворка. Запуская автоматическую сборку на выделенном билд-сервере, можно избежать дальнейших проблем с пропущенными зависимостями — классических ошибок типа «а у меня все работает».

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

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

Контейнеры и виртуальные машины

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

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

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

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

Чтобы избежать этих проблем, можно на первом этапе создания сборки упаковать код в контейнер. Контейнер включает в себя все зависимости, необходимые для запуска программы. Тем самым вы гарантируете портативность: ПО можно развернуть в разных средах.

Если вы используете для CI/CD собственную инфраструктуру, вам все равно понадобятся ВМ, в которых можно будет развернуть контейнеры, но вы потратите меньше сил на подготовку тестовой среды и сократите время на выполнение пайплайна. Если же пайплайн запущен в облаке, контейнеры позволят использовать управляемые сервисы, оставив заботы об инфраструктуре провайдеру.

Предпроизводственные среды

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

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

Например, тестовые среды должны обновляться с каждой новой сборкой, а предпроизводственные среды можно обновлять реже — например, раз в день или раз в неделю с использованием самой свежей успешной сборки.

Развертывание

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

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

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

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

Выводы

CI/CD повышает эффективность разработки ПО, помогая как можно раньше выявлять проблемы. За счет более быстрого взаимодействия и получения обратной связи удается устранять ошибки на раннем этапе (принцип "сдвига влево" — shifting left). Реализовать это можно благодаря автоматизации пайплайна.

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

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