Экосистема GitLab: репозиторий, MR, реестр, issues

Разбираем компоненты GitLab, на которые опирается пайплайн, чтобы понимать контекст джоб.

Merge Request (MR) — аналог Pull Request в GitHub: предложение влить ветку, к которому привязан code review и собственный пайплайн.

Почему важно знать платформу

Пайплайн не существует в вакууме. Он реагирует на события репозитория, публикует образы в реестр, привязывается к окружениям деплоя и оставляет следы в Merge Request. Чтобы писать осмысленные пайплайны, нужно представлять, с чем они взаимодействуют.

Удобно держать в голове карту того, как компоненты связаны и кто кого запускает. Репозиторий — источник событий; событие порождает пайплайн; джобы пайплайна пишут в реестр и регистрируют деплои в окружениях; результат всплывает обратно в Merge Request, где его видит человек. Это замкнутый круг: от коммита до работающего приложения и обратно к ревью.

repo (push / MR)
   │
   ▼
pipeline → jobs →→ Container Registry (образы)
                  →→ Environments (деплой + откат)
                  →→ Package Registry (npm/PyPI/...)
   │
   ▼
Merge Request (статус, diff, обсуждение)

Репозиторий и ветки

Git-репозиторий — основа всего. GitLab умеет защищать ветки (protected branches): запрещать прямой push в main, требовать MR и зелёный пайплайн перед слиянием. Это базовый кирпич надёжного процесса, и пайплайн часто настраивают по-разному для защищённых и обычных веток.

Различие «защищённая / обычная ветка» — не формальность, а механизм безопасности. Секретные переменные CI/CD в GitLab можно пометить как protected: тогда они подставляются в джобы только в пайплайнах защищённых веток и тегов. Логика проста: продакшен-ключи нужны лишь джобам деплоя, которые бегут на main, и не должны утекать в пайплайн, запущенный из чужого форка или временной ветки. Поэтому, проектируя пайплайн, всегда держите в уме вопрос «на какой ветке это выполняется и какие права у него должны быть» — он определит, увидит ли джоба нужный секрет.

Merge Requests

MR — центральное место работы команды. В нём виден diff, идёт обсуждение, и прямо здесь отображается статус пайплайна. GitLab умеет блокировать кнопку Merge, пока пайплайн не стал зелёным. Особая фишка GitLab — review apps: на каждый MR можно автоматически развернуть временную копию приложения, чтобы ревьюер посмотрел изменения вживую. Мы дойдём до них в разделе про деплой.

Полезно знать, что для MR GitLab умеет собирать merge request pipeline — пайплайн не на сам коммит ветки, а на результат предполагаемого слияния с целевой веткой. Это ловит коварный класс ошибок: ваша ветка зелёная, целевая ветка зелёная, но вместе после merge они конфликтуют или ломают тест. В GitHub Actions это поведение давно по умолчанию (события pull_request работают с merge-коммитом), а в GitLab его включают явным правилом в конфигурации. Различие стоит запомнить: одинаковый на вид пайплайн на двух платформах может проверять разные вещи.

Container Registry

В каждый проект GitLab встроен реестр Docker-образов. Пайплайн может собрать образ и запушить его туда командой docker push, авторизуясь встроенными переменными. Не нужен внешний Docker Hub — образ лежит рядом с кодом, под теми же правами доступа.

echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
docker build -t "$CI_REGISTRY_IMAGE:latest" .
docker push "$CI_REGISTRY_IMAGE:latest"

Переменные CI_REGISTRY, CI_REGISTRY_USER, CI_REGISTRY_IMAGE GitLab подставляет автоматически — об этом будет урок про предопределённые переменные.

Зачем встроенный реестр вообще нужен и почему это удобнее внешнего Docker Hub? Во-первых, права доступа едины: кто видит код проекта, тот видит и его образы — не надо вести отдельный список доступов. Во-вторых, авторизация бесплатна и автоматична: переменные CI_REGISTRY_* уже в окружении джобы, не надо хранить логин и пароль Docker Hub в секретах. В-третьих, образы тегируют по коммиту или ветке ($CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA), и тогда легко понять, из какого именно коммита собран конкретный образ. Привычка тегировать latest вместо SHA — частый источник путаницы: latest молча перезаписывается, и вы теряете прослеживаемость.

Issues и связь с кодом

Issue-трекер интегрирован с Git: упоминание Closes #42 в сообщении коммита или MR автоматически закроет issue при слиянии. Для CI/CD это менее важно, но показывает идею сквозной связности платформы — от задачи до задеплоенного результата.

Environments и реестры пакетов

GitLab знает понятие environment — именованной цели деплоя (staging, production). Джоба может объявить, что она деплоит в окружение, и тогда в интерфейсе появится история деплоев, кнопка отката и ссылка на работающее приложение. Помимо Container Registry есть и Package Registry для npm, Maven, PyPI и других пакетов.

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

КомпонентЧто хранит / делаетКогда пригодится в пайплайне
Container RegistryDocker-образы проектаджоба build пушит образ, джоба deploy его тянет
Package Registryпакеты npm, Maven, PyPI, NuGetпубликация библиотеки как артефакта релиза
Environmentистория деплоев, откат, ссылка на приложениеджоба deploy объявляет цель и регистрирует развёртывание
Protected branches/varsправила доступа и секретыпускать продакшен-ключи только в пайплайны main

Окружения дают ещё один скрытый бонус — наблюдаемость деплоев. Без environment деплой остаётся просто строчкой в логе джобы: что-то куда-то поехало. С объявленным environment GitLab рисует ленту «кто, когда и какую версию выкатил», показывает текущую активную версию и даёт откатить одной кнопкой на предыдущий успешный деплой. Для команды это превращает «а что сейчас в проде?» из расследования в один взгляд на экран.

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

Все эти компоненты живут в единой базе GitLab и связаны правами доступа проекта. Когда пайплайн пушит образ в реестр или регистрирует деплой в окружение, он действует от лица временного токена джобы (CI_JOB_TOKEN), у которого права ограничены текущим проектом. Поэтому интеграция бесшовна: не нужно вручную раздавать ключи между сервисами.

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

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

  • Считать Container Registry и Package Registry одним и тем же. Первый — для Docker-образов, второй — для пакетов языков.
  • Забывать включить реестр контейнеров в настройках проекта (на self-hosted он может быть выключен администратором).
  • Деплоить без объявления environment — тогда GitLab не покажет историю деплоев и не даст удобного отката.
  • Тегировать образы только как latest и терять связь образа с коммитом; тегируйте по $CI_COMMIT_SHORT_SHA.
  • Полагать, что секретная переменная доступна везде: помеченная protected, она появится лишь в пайплайнах защищённых веток и тегов.

Итоги

  • Пайплайн взаимодействует с репозиторием, MR, реестром, окружениями и issue-трекером — это замкнутый круг от коммита до прода и обратно к ревью.
  • Container Registry встроен в проект; пуш образа авторизуется предопределёнными переменными; тегируйте по коммиту.
  • Environment даёт историю деплоев, откат и ссылку на приложение — наблюдаемость «что сейчас в проде».
  • Интеграция держится на временном CI_JOB_TOKEN с правами текущего проекта — безопаснее личных ключей.
Проверьте себя
1. Что такое review app в GitLab?
AМобильное приложение для код-ревью
BВременная копия приложения, разворачиваемая на каждый Merge Request для просмотра изменений
CОтдельный реестр образов
DИнструмент линтинга YAML
2. Куда пайплайн пушит собранный Docker-образ без внешних сервисов?
AВ Package Registry
BВ issue-трекер
CВо встроенный Container Registry проекта
DВ защищённую ветку