CI/CD за пять минут и место GitLab в нём

Освежаем понятие CI/CD и смотрим, какую часть конвейера берёт на себя GitLab.

CI/CD — практика автоматически собирать, тестировать и доставлять код при каждом изменении, чтобы релиз был событием рутинным, а не подвигом.

Зачем вообще нужен конвейер

Представьте команду из пяти человек, которые каждый день вливают изменения в общий репозиторий. Без автоматизации кто-то должен вручную скачать новый код, собрать проект, прогнать тесты и выложить на сервер. Это медленно, скучно и ошибкоопасно: человек забудет шаг, перепутает ветку, выложит непротестированное. Непрерывная интеграция (CI) решает первую половину проблемы — на каждый push автоматически запускается сборка и тесты. Непрерывная доставка (CD) — вторую: проверенный артефакт автоматически (или по одному клику) едет в staging и production.

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

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

Если вы проходили наш курс по GitHub Actions, идея вам знакома: триггер → набор шагов → артефакт → деплой. GitLab CI/CD устроен на тех же принципах, но имеет важное отличие в философии, о котором — ниже.

Continuous Delivery против Continuous Deployment

Буква «D» в аббревиатуре скрывает две разные практики. Continuous Delivery (непрерывная доставка) означает, что любой зелёный коммит в любой момент готов поехать в production, но финальную кнопку нажимает человек. Continuous Deployment (непрерывное развёртывание) идёт дальше: зелёный коммит едет в production сам, без ручного подтверждения. Разница в одной строчке — when: manual на джобе деплоя превращает второе в первое. Большинство команд начинают с доставки и держат ручной гейт на production, пока не накопят доверия к своим тестам.

GitLab как единая платформа

GitHub исторически был хостингом репозиториев, а Actions добавили позже как отдельный продукт. GitLab с самого начала позиционирует себя как единая DevOps-платформа: в одном продукте живут репозиторий, issue-трекер, code review (Merge Requests), CI/CD, реестр контейнеров (Container Registry), реестр пакетов, мониторинг и сканеры безопасности. Идея в том, что весь жизненный цикл изменения — от идеи в issue до метрик в production — проходит внутри одной системы без склейки десятка сервисов.

┌─────────────────────────────────────────────┐
│                  GitLab                       │
│                                               │
│  Issues → Merge Request → CI/CD Pipeline      │
│              │                │               │
│           Git repo      Container Registry    │
│              │                │               │
│         Security scans → Environments (deploy)│
└─────────────────────────────────────────────┘

Для нас как авторов пайплайнов это означает приятную вещь: реестр образов, переменные секретов и окружения деплоя уже встроены и интегрированы. Не нужно отдельно настраивать Docker Hub, отдельный vault для секретов и отдельную систему для отслеживания, что и куда задеплоено.

У «всё в одном» есть и оборотная сторона. Связанность экосистемы — это удобство, но и зависимость: уходя с GitLab, вы уносите не только репозиторий, но и пайплайны, реестр, историю окружений. В мире GitHub те же функции часто собраны из независимых кусочков (Actions + Docker Hub + сторонний vault), которые легче заменить по отдельности. GitLab оптимизирует целостность и интеграцию, а связка вокруг GitHub — гибкость выбора; для команды, которая хочет минимум движущихся частей, монолитность GitLab скорее плюс.

GitLab vs GitHub Actions: ключевые различия

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

ИдеяGitLab CI/CDGitHub Actions
Файл конфигурации.gitlab-ci.yml (один на проект)несколько файлов в .github/workflows/
Единица процессаpipelineworkflow
Группировка шаговstages → jobsjobs → steps
Кто исполняетGitLab RunnerGitHub-hosted / self-hosted runner
Переиспользованиевстроенный реестр + includeMarketplace готовых actions
Ревью измененийMerge RequestPull Request

Главное отличие в подходе к переиспользованию: GitHub Actions сделали ставку на маркетплейс готовых блоков, где пайплайн собирают как из кубиков, а GitLab чаще предлагает писать команды оболочки напрямую и подключать готовые куски через include. У первого подхода ниже порог входа, у второго — больше прозрачности: вы видите ровно те команды, что выполняются.

Что приводит конвейер в движение

Ядро GitLab CI/CD — файл .gitlab-ci.yml в корне репозитория. GitLab читает его при каждом событии (push, открытие Merge Request, расписание) и порождает пайплайн — набор джоб, сгруппированных по стадиям. Сами джобы выполняет GitLab Runner — отдельный агент, который берёт задачу, скачивает код и запускает ваши команды. Эту тройку — файл, пайплайн, раннер — мы будем изучать весь курс.

Стоит сразу разделить роли. Сервер GitLab — это мозг: он хранит код, читает YAML и решает, какие джобы создать и в каком порядке их выпускать. Раннер — это руки: отдельная программа, возможно на другой машине, которая физически выполняет команды. Такое разделение даёт масштабируемость — один сервер управляет десятками раннеров — и объясняет, почему пайплайн без подключённого раннера зависает: мозг отдал команду, а рук, чтобы её выполнить, нет.

Как работает под капотом

Когда вы делаете git push, GitLab-сервер получает изменение и проверяет наличие .gitlab-ci.yml. Если файл есть, сервер парсит YAML, строит граф джоб и помещает их в очередь. Свободный раннер забирает джобу, разворачивает чистое окружение (например, контейнер Docker), клонирует репозиторий нужного коммита и выполняет указанные команды. Результат — успех или провал каждой джобы — отправляется обратно на сервер и отображается в интерфейсе Merge Request.

Обратите внимание на слово «чистое окружение». Каждая джоба, как правило, стартует с нуля: свежий контейнер, чистая файловая система, никаких следов предыдущих запусков. Это намеренно — так пайплайн становится воспроизводимым: результат зависит только от кода и конфигурации, а не от того, что осталось на машине после вчерашней сборки. Платой за чистоту служит то, что между джобами ничего не передаётся само собой: если стадии сборки нужны зависимости со стадии тестов, их придётся явно сохранить через cache или artifacts. Пока важно усвоить принцип: изоляция — это фича, а не помеха.

Частые ошибки

  • Думать, что GitLab CI/CD требует отдельной установки. На GitLab.com он включён сразу; в self-hosted GitLab тоже встроен, нужен лишь зарегистрированный раннер.
  • Путать CI и CD. CI — про проверку каждого коммита, CD — про доставку. Можно иметь CI без автоматического деплоя.
  • Ожидать, что пайплайн заработает без раннера. Файл может быть идеальным, но без подключённого раннера джобы останутся в статусе pending.
  • Рассчитывать, что файлы и пакеты сами «переедут» из джобы в джобу. Окружения изолированы; обмен — только через cache и artifacts.
  • Смешивать Continuous Delivery и Continuous Deployment. Первое оставляет ручной гейт на production, второе деплоит автоматически — это сознательный выбор, а не деталь.

Итоги

  • CI автоматизирует сборку и тесты на каждое изменение, CD — доставку артефакта; быстрая обратная связь удешевляет починку.
  • GitLab — единая платформа: репозиторий, MR, CI/CD, реестр, секреты и сканеры в одном месте; плата за интеграцию — связанность.
  • Конвейер описывается в .gitlab-ci.yml, исполняется раннерами, отображается в Merge Request; сервер — мозг, раннер — руки.
  • Джобы изолированы и воспроизводимы; обмен данными между ними — явный, через cache и artifacts.
Проверьте себя
1. Чем философия GitLab принципиально отличается от GitHub в части CI/CD?
AGitLab не поддерживает деплой
BGitLab — единая платформа, где репозиторий, CI/CD, реестр и секреты встроены изначально
CGitLab работает только с Docker
DGitLab не использует YAML
2. Какой файл является ядром описания пайплайна в GitLab?
A.github/workflows/main.yml
BJenkinsfile
C.gitlab-ci.yml
Dgitlab.config.json