e
В статье разбираем, как устроена практика CI/CD, какие у нее нюансы и преимущества использования. А также расписываем пошаговый процесс использования CI/CD в GitLab и практический пример реализации.
CI/CD (Continuous Integration/Continuous Deployment) в переводе означает «непрерывная интеграция и непрерывная доставка». Под этим понятием подразумевают практики и принципы, которые позволяют сделать тестирование автоматизированным, а новые модули сразу доставлять всем, кому нужно: DevOps-инженерам, программистам, тимлидам, пользователям и так далее.
CI/CD состоит из двух частей:
Это практика, согласно которой разработчики могут предлагать изменения в основной код проекта. При этом делать это могут фактически неограниченное количество раз в день. Для создания такого предложения существует отдельная сущность — MR (Merge Request, в некоторых системах вроде GitHub она же называется PR — Pull Request). Она содержит предложенное изменение и необходимый набор сопровождающих комментариев.
Другие члены команды могут провести процесс ревью кода (Code Review) — то есть посмотреть, что именно предлагается изменить в проекте и задать вопросы или принять это изменение. При этом при создании MR может выполняться запуск автоматического процесса сборки и тестирования.
С помощью этого процесса новые изменения могут проверяться на корректность синтаксиса, отсутствие логических ошибок и дополнительно проверяются человеком во время ревью кода.
CD дополняет практику CI за счет того, что после сборки проекта с внесенными после прохождения CI изменениями, артефакты сборки автоматически развертываются на серверы. А главная задача CD — оперативно и без перебоев доставлять обновления пользователям без необходимости включения разработчика или прерывания работоспособности сервиса.
Прежде чем приступать к процессу CI/CD, нужно написать новый код или внести изменения в существующий. Разработчики работают в локальных ветках, где они могут безопасно вносить изменения без влияния на основную ветку проекта. Затем разработчики тестируют код — в ручном режиме или запускают уже существующие или написанные ими же тесты. После этого переходят к следующему этапу.
После внесения изменений разработчик коммитит их в локальную ветку и отправляет в удаленный репозиторий, размещенный, в нашем примере, в GitLab — так можно сохранить свои изменения, например для продолжения работы на следующий день, не переживая за локальную копию. Затем, для запуска процесса CI и, возможно, запроса ревью кода со стороны других членов команды, нужно создать MR.
Каждый MR в репозитории автоматически запускает пайплайн CI, который описан в файле .gitlab-ci.yml.
Первый этап пайплайна CI обычно включает сборку кода. В зависимости от технологии проекта это может быть проверка синтаксиса посредством запуска линтеров, компиляция, сборка образов контейнеров или другие действия.
Здесь проводятся юнит-тесты, интеграционные тесты, которые помогают обнаружить ошибки и баги на ранних стадиях разработки.
Когда тесты заканчиваются успешно, разработчик получает уведомление об успешном прохождении CI для своего изменения. Если тесты или сборка проекта завершаются с ошибкой, разработчик видит детальные данные об этой ошибке и может оперативно внести изменения.
Также на этом этапе код может посмотреть заказчик и другие участники проекта. Если все в порядке, разработчик приступает к следующему этапу. В противном случае в код вносят исправления.
После того, как этапы CI успешно пройдены, изменения нужно смержить (слить) с основной веткой проекта, как правило это master или main. После чего запускается часть CD, которая автоматически развертывает изменения на тестовый или продакшн сервер.
Если присутствует этап развертывания в тестовое окружение, то там приложение может быть отдельно проверено на совместимость с остальными компонентами — например, в рамках этапа e2e тестирования в тестовой среде. После чего приложение разворачивается в продакшн-окружение, то есть доставляется конечному потребителю.
Технология CI/CD помогает решать рутинные задачи проще, автоматизируя их. Благодаря этому, команды могут быстрее выпускать новые версии. А если понадобятся изменения, они так же легко и просто проходят по пайплайну внесения изменений.
В CI/CD активно используются автоматические тесты. Это позволяет находить баги на ранних стадиях. В итоге растет общее качество кода, снижается число ошибок. А сам продукт становится стабильнее.
За счет прозрачной работы CI/CD, командная коммуникация тоже становится значительно проще. Так, каждый сотрудник знает, что внедренные изменения будут проверены и корректны в работе. А значит снизится количество конфликтов и вырастет общая продуктивность команды.
Чем больше процессы автоматизированы, тем меньше вероятность человеческой ошибки. Это тоже работает на безопасность всех процессов: от разработки до развертывания.
CI/CD позволяет легко масштабировать процессы разработки и адаптироваться к постоянно меняющимся требованиям бизнеса, внося и тестируя изменения разных масштабов от одной строчки до, фактически, бесконечности.
CI/CD — это технология, для использования которой есть разные инструменты. Вот несколько популярных вариантов:
В нашем примере мы будем разбирать использование CI/CD в GitLab, потому что это один из наиболее популярных, масштабируемых и гибких инструментов используемых в компаниях по всему миру. Он позволяет получить в self-hosted варианте систему, по функциональности достигающую уровня коммерческих сервисов совершенно бесплатно в GitLab Community Edition.
Файлы .gitlab-ci.yml — центральный элемент GitLab CI/CD. С помощью него описываются все этапы сборки, тестирования и развертывания проекта. Он размещается в корневой папке проекта и написан на языке разметки YAML.
Файл .gitlab-ci.yml состоит из нескольких секций, которые определяют различные аспекты пайплайна). У каждый секции файла своя функция, выполняющаяся во время CI/CD:
Этапы определяют порядок выполнения различных групп задач и делают так, чтобы они выполнялись последовательно. А еще этапы помогают грамотно организовать задачи (jobs) в группы: например, сборка, тестирование и развертывание.
Пример:
stages:
- build
- test
- deploy
Это часть пайплайна, которая дает инструкции к выполнению задач. Как мы уже говорили, задачи распределены по этапам. Если у двум задачам назначить этап один, задачи будут запускаться параллельно, если нет обратных условий. Например, задача на этапе сборки может компилировать код, а задача на этапе тестирования — запускать тесты. В приведенном примере описаны три задачи (Job): build_job, test_job, deploy_job с соответствующими, назначенными им этапами.
Пример:
build_job:
stage: build
script:
- echo "Сборка кода..."
test_job:
stage: test
script:
- echo "Запуск тестов..."
deploy_job:
stage: deploy
script:
- echo "Развертывание приложения..."
Определяет набор команд, выполняющихся в одной задаче. Можно назвать эту часть конфигурации одной из самых важных — именно тут прописываются все команды, которые должны быть выполнены в конкретной задаче.
Пример:
build:
image: ubuntu:24.04
stage: build
tags:
- cloud-runner
script:
- docker build -t "image:tag" -t "image:latest" --push.
Эти ключи определяют команды, которые выполняются до (before_script) и после (after_script) выполнения всех задач в пайплайне. Например, перед выполнением задач можно войти в реестр Docker, а после — выйти из него.
Пример:
before_script:
- docker login -u <username> -p ${password} index.docker.io
after_script:
- docker logout index.docker.io
С помощью этого элемента устанавливаются переменные окружения. Их можно использовать на каждом этапе пайплайна. За счет переменных можно устанавливать параметры для задач — так становится проще настраивать и управлять конфигурацией. Из самого простого: можно назначить переменную для URL базы данных, а затем использовать ее и в других задачах.
Пример:
variables:
DATABASE_URL: "postgres://user:password@hostname:5432/dbname"
Дает возможность включить внешние YAML-файлы, чтобы использовать конфигурации по нескольку раз. Это помогает управлять крупными пайплайнами. Например, можно использовать одну конфигурацию в нескольких проектах или разделить крупный файл конфигурации на несколько частей и переиспользовать их.
Пример:
include:
- project: 'my-group/my-project'
ref: master
file: '/templates/.template.yml'
- local: '/ci/common.yml'
Элемент GitLab Artifacts — файлы, которые создаются во время выполнения задачи. Они сохраняются, а затем их можно использовать повторно в других задачах. Так, можно сохранить результаты тестирования или передать скомпилированные файлы между задачами.
Пример:
artifacts:
paths:
- build/
expire_in: 1 week
Дает возможность сохранить в кэше зависимости или любые иные сложно воспроизводимые данные, созданные во время выполнения задач. С помощью этой функции можно ускорить выполнения пайплайнов за счет отсутствия необходимости выполнять долгие операции каждый раз.
Пример:
cache:
paths:
- project-venv
Указывает образ контейнера, который будет использоваться для выполнения задачи. Это заранее настроенное окружение с установленными зависимостями. Например, можно использовать образ с установленной версией Ruby для задач, связанных с этим языком программирования.
Пример:
image: ruby:2.7
Позволяют запускать дополнительные контейнеры, которые нужны для выполнения задач, например, базы данных. Элемент помогает в тестировании, когда требуется наличие внешнего работающего сервиса.
Пример:
services:
- mysql:9
Эти ключи выделяют условия для выполнения или пропуска задач. Например, задачи могут выполняться только на определённых ветках репозитория или, наоборот, пропускаться для определенных тегов.
Пример:
only:
- master
- develop
except:
- v.*
Правила предлагают более гибкие условия для выполнения задач по сравнению с only и except. Например, можно задать условия выполнения задач в зависимости от имени ветки или результата предыдущих задач.
Пример:
rules:
- if: $CI_COMMIT_BRANCH
exists:
- Dockerfile
Теги используются для определения, какие GitLab Runner'ы (агенты, выполняющие задачи) будут запускать задачи. Это помогает распределять задачи по различным агентам в зависимости от их возможностей.
Пример:
tags:
- docker
- linux
Окружение управляет развертыванием задач в определенные среды, например, в тестовую или продакшн. Это помогает автоматически разворачивать и тестировать код в различных условиях.
Пример:
environment:
name: production
url: https://prod.example.com
Этот ключ позволяет прерывать задачи, если запускается новая сборка. Это полезно для экономии ресурсов, когда более старая сборка уже не актуальна.
build:
stage: build
script:
- echo "This build can be canceled."
interruptible: true
Параллельность позволяет запускать несколько экземпляров задачи одновременно. Например, можно параллельно запускать тесты с различными параметрами, чтобы ускорить процесс.
Пример:
parallel:
matrix:
- TEST_SUITE: ["unit", "integration"]
Итак, мы разобрали главные составляющие файла .gitlab-ci.yml. На самом деле, их гораздо больше, а сам GitLab CI/CD дает множество опций для настройки и создания многоуровневых пайплайнов. Постоянное изучение CI/CD поможет углубить знания и использовать лучшие практики.
Перед тем, как приступить к разбору практического примера, нам нужно настроить CI/CD в GitLab. В нашем блоге уже есть подробная инструкция по установке CI/CD на облачный сервер. Рекомендуем начать с нее.
В этом блоке приведем пример YAML-конфигурации для GitLab CI. Как выше упоминалось, CI/CD-пайплайны в GitLab описываются с помощью YAML-файлов, именованных особым образом и находящихся в определенном месте.
Для создания первого пайплайна в уже существующем проекте необходимо создать файл “.gitlab-ci.yml” в корне проекта, в нем будет описано что запускать и как запускать. Например:
build:
image: ubuntu:24.04
stage: build
tags:
- cloud-runner
before_script:
- echo "Before run"
script:
- echo "Run"
after_script:
- echo "After run"
В этом примере мы в базовом образе ubuntu:24.04 выполняем три скрипта:
Попробуем пример чуть сложнее: протестируем свой проект на Python, с тестами, которые бы запускались только в случае коммита в ветку и при наличии файла requirements.txt:
python-test:
image: python:3.12
stage: test
tags:
- linux
- docker
before_script:
- pip install -r requirements.txt
script:
- pytest -vvv
rules:
- if: $CI_COMMIT_BRANCH
exists:
- requirements.txt
Для работы вышеописанного примера в репозитории должен быть файл requirements.txt с добавленным pytest.
GitLab предоставляет удобные и гибкие инструменты для реализации CI/CD-пайплайнов практически любой сложности. При этом он упрощает разработку самих пайплайнов за счет хранения конфигурации CI/CD вместе с кодом в одном Git-репозитории. В свою очередь, сама практика CI/CD позволяет увеличить производительность команд разработки и эксплуатации за счет автоматизации процессов ревью, тестирования и развертывания приложений. Это позволяет бизнесу быть гибким и оперативно вносить изменения в свои программные продукты.
Ксения Иванчикова
Один способ позволяет отслеживать каждую деталь изделия, другой – сфокусироваться на брендинге и маркетинге. Разбираемся…
Рассказываем, как помогли российскому разработчику систем аналитики мигрировать в частное облако и сократить затраты на…
Рассказываем, как создать сайт-визитку и какой должна быть структура. Внутри — инструкция, которая поможет предпринимателям.
Онлайн-карты — хорошая площадка для привлечения аудитории в бизнес. Рассказываем об инструментах продвижения в геосервисах.
Можно стартовать с багажом знаний из найма или практически без опыта. Рассказываем, что нужно делать:…
Что такое наука о данных, чем занимается Data Scientist и можно ли обучиться этой специальности…