- PVSM.RU - https://www.pvsm.ru -
Итак, GitLab CI [1]: что можно ещё рассказать о нём? На хабре уже есть статьи про установку, про настройку раннеров, про командное использование, про GitLab Flow. Пожалуй, не хватает описаний того, как используется GitLab CI в реальном проекте, где задействовано несколько команд. А в современном мире разработки ПО это действительно так: ведь есть (как минимум) разработчики, тестировщики, DevOps- и релиз-инженеры. С подобным разделением на команды мы работаем уже несколько лет. В этой статье я расскажу о том, как мы, используя и улучшая возможности GitLab CI, реализовали и применяем в production для коллектива из нескольких команд процессы непрерывной интеграции (CI) и отчасти доставки приложений (CD).
Если вы сталкивались с CI-системами ранее, то понятие пайплайна вам знакомо — это последовательность выполнения стадий (здесь и далее в статье для термина stage использую перевод «стадия»), каждая из которых включает несколько задач (здесь и далее в статье job — «задача»). От момента внесения изменений в код до выката в production приложение по очереди оказывается в руках разных команд — подобному тому, как это происходит на конвейере. Отсюда и возник термин pipeline («конвейер» — один из вариантов дословного перевода). В нашем случае это выглядит так:
Краткие пояснения по используемым стадиям:
Примечание: Нет ничего совершенно универсального, поэтому для вашего конкретного случая этот пайплайн скорее всего не подходит: он либо избыточен, либо прост. Однако цель статьи не описывать единственно верный вариант, подходящий каждому. Цель — рассказать на примере о том, как можно работать в GitLab CI нескольким командам и какие возможности есть, чтобы реализовать такой пайплайн. На основе этой информации можно разработать свою собственную конфигурацию GitLab CI.
Начну с рассказа о пайплайне с точки зрения его использования — то, что можно назвать user story. Тут выяснится, что на самом деле пайплайна у нас даже два: укороченный для веток и полноценный для тегов. И вот как выглядят эти последовательности:
Роль релиз-инженера в пайплайне
Задачи на стадии build собирают приложение. Для этого мы используем свою разработку — Open Source-утилиту dapp [2] (о её основных возможностях читайте и смотрите в этой статье + видео [3]), которая хорошо ускоряет инкрементальную сборку. Поэтому сборка запускается автоматически для веток с префиксами feature_ (код приложения), infra_ (код инфраструктуры) и тегов, а не только для нескольких традиционно «главных» веток (master/develop/production/release).
Следующая стадия — staging — это набор сред для разработчиков, DevOps-инженеров и тестировщиков. Здесь объявлено несколько задач, разворачивающих приложения из веток с префиксами feature_ и infra_ в урезанных средах для быстрого тестирования новой функциональности или инфраструктурных изменений (код сборки приложения хранится в репозитории приложения).
Стадии pre-production и production доступны только для тегов. Обычно тег вешается после того, как релиз-инженеры принимают несколько merge-запросов из протестированных веток. В целом можно сказать, что мы используем GitLab Flow [4] с тем лишь отличием, что нет автоматического развёртывания на production и потому нет отдельных веток, а используются теги.
Стадия approve — это две задачи: approve и not approve. Первая включает возможность развёртывания на production, вторая — выключает. Эти задачи существуют для того, чтобы в случае проблем на production было видно, что развёртывание происходило не просто так, а с согласия релиз-инженера. Однако суть не в лишении кого-то премии, а в том, что непосредственно развёртывание на production проводит зачастую не сам релиз-инженер, а команда DevOps. Релиз-инженер, запуская задачу approve, разрешает тем самым «нажать на кнопку» deploy to production команде DevOps. Можно сказать, что эта стадия выносит на поверхность то, что могло бы остаться в почтовой переписке или в устной форме.
Такая схема взаимодействия хорошо себя показала в работе, однако пришлось потрудиться, чтобы реализовать её. Как оказалось, GitLab CI не поддерживает из коробки некоторые нужные вещи…
Изучив документацию и различные статьи, можно быстро набросать такой вариант .gitlab-ci.yml [5], соответствующий описанным стадиям пайплайна:
stages:
- build
- testing
- staging
- preprod
- approve
- production
## build stage
build:
stage: build
tags: [deploy]
script:
- echo "Build"
## testing stage
test unit:
stage: testing
tags: [deploy]
script:
- echo "test unit"
test integration:
stage: testing
tags: [deploy]
script:
- echo "test integration"
test selenium:
stage: testing
tags: [deploy]
script:
- echo "test selenium"
## staging stage
.staging-deploy: &staging-deploy
tags: [deploy]
stage: staging
when: manual
script:
- echo $CI_BUILD_NAME
deploy to dev-1:
<<: *staging-deploy
deploy to dev-2:
<<: *staging-deploy
deploy to devops-1:
<<: *staging-deploy
deploy to devops-2:
<<: *staging-deploy
deploy to qa-1:
<<: *staging-deploy
deploy to qa-2:
<<: *staging-deploy
## preprod stage
deploy to preprod:
stage: preprod
tags: [deploy]
when: manual
script:
- echo "deploy to preprod"
## approve stage
approve:
stage: approve
tags: [deploy]
when: manual
script:
- echo "APPROVED"
NOT approve:
stage: approve
tags: [deploy]
when: manual
script:
- echo "NOT APPROVED"
## production stage
deploy to production:
stage: production
tags: [deploy]
when: manual
script:
- echo "deploy to production!"
Всё довольно просто и скорее всего понятно. Для каждой задачи используются следующие директивы:
stage
— определяет стадию, к которой относится задача;script
— действия, которые будут произведены, когда запустится задача;when
— вид задачи (manual
означает, что задача будет запускаться из пайплайна вручную);tags
— теги, которые в свою очередь определяют, на каком раннере будет запущена задача.
Примечание: Раннер — часть GitLab CI, аналогичная другим системам CI, т.е. агент, который получает задачи от GitLab и выполняет их script
.
Слайд про раннеры из презентации «Coding the Next Build [6]» (ⓒ 2016 Niek Palm)
Кстати, заметили этот блок [7]?
.staging-deploy: &staging-deploy
tags: [deploy]
stage: staging
when: manual
script:
- echo $CI_BUILD_NAME
Он демонстрирует возможность формата YAML определять общие блоки и подключать их в нужное место на нужном уровне. Подробнее см. в документации [8].
В описании пайплайна было сказано, что стадии approve и production доступны только для тегов. В .gitlab-ci.yml
это можно сделать с помощью директивы only
. Она определяет ветки, для которых будет создаваться пайплайн, а с помощью ключевого слова tags
можно разрешить создавать пайплайн для тегов. К сожалению, директива only
есть только для задач — её нельзя указать при описании стадии.
Таким образом, задачи на стадиях build, testing, staging, pre-production, которые должны быть доступны для веток infra_, feature_ и тегов, принимают следующий вид:
test unit:
stage: testing
tags: [deploy]
script:
- echo "test unit"
only:
- tags
- /^infra_.*$/
- /^feature_.*$/
А задачи на стадиях approve и production, которые доступны только для тегов, имеют такой вид:
deploy to production:
stage: production
tags: [deploy]
script:
- echo "deploy to production!"
only:
- tags
В полном варианте директива only
вынесена в общий блок (пример такого .gitlab-ci.yml
доступен здесь [9]).
На этом создание .gitlab-ci.yml
для описанного пайплайна затормаживается, т.к. GitLab CI не предоставляет директив, во-первых, для разделения задач по пользователям, а во-вторых, для описания зависимостей выполнения задач от статуса выполнения других задач. Также хотелось бы разрешить изменять .gitlab-ci.yml
только отдельным пользователям.
Полная реализация задуманного стала возможной только благодаря нескольким патчам к GitLab и использованию артефактов задач. Подробнее об этом я расскажу в следующей части статьи (мы опубликуем её в среду).
Автор: diafour
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/open-source/260026
Ссылки в тексте:
[1] GitLab CI: https://docs.gitlab.com/ce/ci/
[2] dapp: https://github.com/flant/dapp
[3] этой статье + видео: https://habrahabr.ru/company/flant/blog/324274/
[4] GitLab Flow: https://habrahabr.ru/company/softmart/blog/316686/
[5] такой вариант .gitlab-ci.yml: https://github.com/flant/gitlab-ci-examples/blob/000_big_pipeline/.gitlab-ci.yml
[6] Coding the Next Build: http://www.slidedeck.io/codethebuild/slides
[7] этот блок: https://github.com/flant/gitlab-ci-examples/blob/000_big_pipeline/.gitlab-ci.yml#L42-L47
[8] документации: https://docs.gitlab.com/ce/ci/yaml/README.html#anchors
[9] здесь: https://github.com/flant/gitlab-ci-examples/blob/001_use_only/.gitlab-ci.yml
[10] Источник: https://habrahabr.ru/post/332712/
Нажмите здесь для печати.