😇
На testengineer.ru мы не размещаем рекламу, но над сайтом регулярно работают несколько человек. Поддержите нас, подписавшись на телеграм-канал "Тестировщик от бога"!

Разбираемся в CI/CD

Автор

Дата

Категория

Что такое CI/CD

В конечном счете, цель всякого ИТ-проекта — автоматизация бизнес-процессов.

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

Как ускорить релиз? Все можно делать вручную, при желании достаточно быстро. Например, подключиться к удаленному серверу через SSH, клонировать репозиторий с новым кодом, сделать билд, запустить его из командной строки. Это все еще работает, но это плохой подход. 

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

CI означает Continuous Integration (Непрерывная Интеграция) кода; CD — (Continuous Delivery) Непрерывная Доставка кода.

CI

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

Твоя команда в старые добрые времена, до того как придумали CI

Выделенная на задачу группа людей одновременно вносит правки в код. В конечном счете все изменения вливаются в основную, master-ветку. 

Даже в такой простой модели могут возникнуть вопросы. 

  • Как гарантировать, что код, отправленный в master-ветку, точно скомпилируется?
  • У нас принято, чтобы разработчики писали тесты своего кода. Как гарантировать, что покрытие не снизилось в результате постоянных изменений?
  • Все участники команды должны придерживаться одного стиля написания кода. Как контролировать возможные отклонения от гайдлайнов?

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

CI-подход придумали, чтобы автоматизировать описанный выше контроль.

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

Команда, принявшая CI-подход

CI-процессы, или по крайней мере бОльшая часть, работают по такому алгоритму:

  1. При открытии каждого Pull Request, Git-сервер отправляет уведомление CI-серверу.
  2. CI-сервер клонирует репозиторий, проверяет исходную ветку (например bugfix/wrong-sorting), и сливает код с кодом master-ветке.
  3. Тогда запускается билд-скрипт (сценарий сборки). Например ./gradlew build.
  4. Если эта команда возвращает код ответа “0”, то билд успешно выполнен. (Другой ответ означает ошибку).
  5. CI-сервер направляет уведомление об успешном билде на Git-сервере.
  6. Если билд был успешен, то Pull Request разрешается слить с существующим кодом. (Если не успешен, то, соответственно, не разрешается). 

Такой процесс гарантирует, что любой код, отправляемый в master-ветку, не сломает следующие билды.

Контроль тестового покрытия

Теперь усложняем задачу. Представим, что надо удерживать некое минимальное покрытие кода тестами. Например, в любой момент покрытие кода master-ветки не должно опускаться ниже 50%. Такую проблему иногда помогает решать, например, плагин Jacoco, просто настраиваешь его на “непропуск” билда, если покрытие упало ниже какого-то уровня. 

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

Представим, что работаем на проекте с пятилетней историей. Тогда несколько разработчиков просто писали код и отправляли его, проверки покрытия не было. Тестировщики тестировали код рандомно, без какой-либо системности. Но в один день руководство решило увеличить количество тестов, и покрытие. Поставлен плагин Jacoco, и настроен на минимальное покрытие 60%. Потом какой-то разработчик открывает новый Pull Request, при этом оказывается, тестовое покрытие лишь 30%. В такой ситуации, чтобы успешно “закрыть задачу”, надо обязательно покрыть тестированием как минимум еще 30% всей кодовой базы. Это практически невыполнимая задача, для проекта начатого 5 лет назад. 

А что, если будем проверять (валидировать) только новый, приходящий код, а не весь проект? Если разработчик изменил 200 строк за один свой Pull Request, тестировщикам надо покрыть как минимум 120 строк (если целевое покрытие мы ставили 60%). И нам совсем необязательно трогать код во всех модулях, не касающихся текущей задачи. Надо подходить как-то избирательно, и есть способы как это сделать изящнее: тот же SonarCloud

CI-команда с усовершенствованным CI — с проверкой покрытия

Сервер собирает статистику оценок покрытия; оценивает покрытие с учетом приходящих дополнений, и всего кода. Затем анализ отправляется на CI-сервер, который переправляет его на Git-сервер.

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

С точки зрения стиля кода, процессы примерно такие же. Можно посмотреть на плагин Checkstyle. Он автоматически “фейлит” билд, нарушающий прописанное требование; например, не пропускает билд, если в коде есть неиспользованный импорт библиотек. Потом, можно пробовать облачные сервисы анализа кода, которые удобно выводят результат графически (так же выводит и SonarCloud).

CD

А вот термин Непрерывная доставка описывает процесс автоматического деплоя (развертывания, или еще называют автодеплоя) новых версий продукта. 

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

Хорошая команда сочетает подходы CI и CD

CI-сервер” теперь у нас будет называться “CI/CD-сервер”. Это потому что наши задачи в рамках подходов CI и CD — теперь выполняются одним таск-менеджером. Рассмотрим такой комбинированный подход.

Впрочем бывают исключения; например, команды могут делегировать CI-задачи в GitLab CI, а CD-задачи в Jenkins.

Итак, в правой части схемы у нас CI, который мы обсудили выше. Слева у нас CD. CD-задача у нас это билд проекта (или отработка артефактов, возникших на CI-этапе), и деплой ее на сервер.

Надо отметить, что “сервер” выше — это абстракция. Например, деплой может быть делегирован такой вещи как кластер Kubernetes. То есть, строго говоря, может быть и несколько серверов. 

После завершения этапа деплоя, обычно отправляются email-уведомления. CD-сервер уведомляет подписчиков об успешном (или нет) деплое.

И вот здесь возникает важный вопрос: когда начинать CD-таски? Триггеры на это могут быть разные:

  1. Деплой после каждого Pull Request на слияние (merge) кода.
  2. Деплой по расписанию.
  3. Деплой после каждого слияния по Pull Request-у в какую-то ветку.
  4. Или комбинация этих опций.

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

Важно чётче понимать понятие развертывания (деплоя). Оно необязательно означает, что “что-то где-то запускается”. Если вы пишете какую-то библиотеку, там нет “запуска”. В таком случае “деплой” означает “выпуск новой версии библиотеки”.

Второй пункт у нас “независим” от CI-процесса, поскольку проект деплоится по расписанию. Например каждый день в час ночи.

Третий пункт похож на первый. Хотя есть разница. Представим, что есть две главные ветки в репозитории: develop и master. В ветке develop у нас самые релевантные изменения. А в master — только релизы. Если нам нужно деплоить только master-ветку, нам нет необходимости запускать CD-задачу на слияние в develop.

Последний пункт — это комбинированный подход. Например, develop-ветка может деплоиться по расписанию, в dev-окружение. А master деплоится в продакшен по каждому Pull Request-у на слияние.

Инструменты

На рынке — десятки решений автоматизации CI/CD. Самые важные, которыми желательно владеть

  1. Jenkins. Один из самых важных CI/CD-инструментов, может быть самый важный. Популярен потому что бесплатный и опенсорсный, то есть за него не надо платить. Jenkins позволяет прописывать билд-пайплайны на языке Groovy. С одной стороны, это дает больше гибкости. А с другой, отличается высоким порогом вхождения.
  2. GitHub Actions. Инструменты для CI/CD интегрированы в GitHub и GitHub Enterprise. В отличие от Jenkins, GitHub Actions это “декларативные” билды с YAML-конфигурацией. Помимо того, решение имеет множество интеграций с разными полезными-удобными инструментами контроля качества кода (Quality Assurance Systems — тот же SonarQube). Поэтому билд-скрипт можно написать буквально в несколько строк кода.
  3. GitLab CI. довольно похож на GitHub Actions. Но есть и отличительные особенности. Например Gitlab CI может указывать на отдельные тесты, вызывающие падение билда.
  4. Travis CI. Облачное решение. Много возможностей, не требующих сложной настройки. Например, шифрование данных, которые надо размещать в публичном репозитории. Кроме того, бонус — Travis CI можно применять в публичных опенсорсных проектах на GitHub, GitLab и BitBucket абсолютно бесплатно.

Итого

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

Возможно также будет интересно:

Chrome Developer Tools для тестировщика

Что такое user story и как ее писать?

Собеседование тестировщика — cкользкие вопросы

Какой была ваша первая зарплата в QA и как вы искали первую работу?

Мега обсуждение в нашем телеграм-канале о поиске первой работы. Обмен опытом и мнения.

ОСТАВЬТЕ ОТВЕТ

Пожалуйста, введите ваш комментарий!
пожалуйста, введите ваше имя здесь

$1100*
медианная зарплата в QA в ноябре

*по результатам опроса QA-инженеров в нашем телеграм-канале

Последние публикации

Последние комментарии