Перейти к контенту

GitLab: Основы написания Pipeline 1/3

DevOps Иван Ашихмин 31

Первая из трёх статья посвящённая разбору отличий GitLab CI от GitHub Action и основам написания Pipeline. 

GitLab: Основы написания Pipeline 1/3
DevOps Иван Ашихмин 31

Всем привет!

Так вышло, что в месте, где я преподаю и занимаюсь менторством стажёров, начался переход с GitHub-репозиториев на GitLab, развёрнутый на собственных серверах. Пока что перенесли не все проекты, но даже этого оказалось достаточно, чтобы у стажёров возникло немало вопросов — особенно в части настройки CI/CD-процессов.

Формально CI/CD в GitHub и GitLab решают одну и ту же задачу, но на практике подходы, терминология и детали конфигурации отличаются. Из-за этого попытки «сделать как в GitHub Actions» часто приводят к путанице и ошибкам.

У меня уже есть статья про CI/CD и workflow, но она целиком посвящена GitHub Actions. Чтобы сократить количество вопросов, разночтений и бессонных ночей у стажёров, я решил написать отдельную статью про CI/CD именно в GitLab — с учётом его особенностей и типичных подводных камней.

Если вам интересны подобные материалы, подписывайтесь на Telegram-канал «Код на салфетке». Там я делюсь гайдами для новичков, полезными инструментами и практическими примерами из реальных проектов. А прямо сейчас у нас там ещё и проходит новогодний розыгрыш.


Вместо теории про CI/CD и раннеры

Чтобы не повторяться и не превращать эту статью в ещё один учебник по CI/CD «с нуля», я сознательно опущу базовую теорию. Если вы пока не очень хорошо понимаете, что такое pipeline, job, runner и зачем всё это вообще нужно — лучше сначала ознакомиться с вводными материалами.

Рекомендую начать с этих двух статей:

  1. «CI/CD: основы написания workflow» — базовые принципы CI/CD, которые актуальны вне зависимости от конкретного сервиса.
  2. «Подключаем runner для CI/CD в Gitea» — практический разбор работы раннеров и их роли в CI/CD.

Даже если вы не работали с Gitea, статья про раннеры будет полезна: сама концепция в GitLab устроена очень похоже.

А дальше мы переходим непосредственно к GitLab и его особенностям.


Что нужно знать о GitLab CI перед тем, как начать

Если вы уже читали мою предыдущую статью про GitHub Actions, то при работе с GitLab CI довольно быстро заметите: подход вроде бы похожий, но нюансов хватает. Эти отличия не критичны, но если не разобраться в них заранее, можно долго «спотыкаться» на ровном месте.

Давайте разберём ключевые моменты — это сильно упростит адаптацию к GitLab.

GitLab CI как часть единой платформы

Одно из главных различий между GitHub Actions и GitLab CI заключается в архитектуре.

GitHub Actions — это отдельный инструмент, который интегрирован в GitHub. 
GitLab CI — это встроенная и неотъемлемая часть GitLab как DevOps-платформы.

В GitLab нет разделения на условный «GitLab» и «GitLab CI» — это один цельный продукт. CI/CD здесь изначально задуман как базовая функциональность, а не как дополнительный модуль.

Практический плюс такого подхода в том, что всё находится в одном месте:

  • Управление доступами.
  • Реременные окружения.
  • Runners.
  • логи выполнения.
  • Артефакты сборки.

Вам не нужно прыгать между разными сервисами и интерфейсами — вся цепочка CI/CD живёт внутри GitLab.

Один конфиг вместо множества файлов

В GitHub Actions обычно используется несколько YAML-файлов в директории .github/workflows/. Каждый файл описывает отдельный workflow: тесты, деплой, линтеры и так далее.

В GitLab CI подход другой: вся конфигурация CI/CD по умолчанию описывается в одном файле — .gitlab-ci.yml, который лежит в корне репозитория.

На первый взгляд это может выглядеть непривычно, особенно если вы привыкли дробить логику по разным workflow. Однако на практике у такого подхода есть плюс: вся CI/CD-логика проекта находится в одном месте, и общая картина пайплайна видна сразу.

Важно понимать, что GitLab не ограничивает вас одним файлом навсегда. Для крупных проектов есть механизм include, который позволяет выносить части конфигурации в отдельные файлы и подключать их при необходимости. К этому мы ещё вернёмся позже.

Терминология: Pipeline, Jobs, Stages

Термины в GitLab немного отличаются от GitHub Actions, и к этому нужно привыкнуть.

  • Workflow в GitHub Actions ≈ Pipeline в GitLab.
  • StepsJobs.
  • Плюс появляется дополнительный уровень — Stages.

Stages — это логическая группировка job’ов по этапам выполнения.

Схематично это выглядит так:

Pipeline (весь процесс)
├── Stage: Test
│   ├── Job: unit-tests
│   ├── Job: integration-tests
│   └── Job: lint
├── Stage: Build
│   ├── Job: compile
│   └── Job: package
└── Stage: Deploy
    └── Job: deploy-to-production

Jobs внутри одного stage выполняются параллельно (если хватает runner’ов и ресурсов). 
Stages же выполняются последовательно — следующий stage не начнётся, пока полностью не завершится предыдущий.

Этот механизм дисциплинирует пайплайн и делает его поведение более предсказуемым.

Runners — похоже, но с особенностями

Концептуально runners в GitLab выполняют ту же роль, что и runners в GitHub Actions, но организация у них другая.

В GitHub Actions вы обычно пишете что-то вроде runs-on: ubuntu-latest и выбираете среду из заранее подготовленных вариантов.

В GitLab подход более «инфраструктурный»: вы разворачиваете runners сами (на своих серверах, VM или в Docker) и присваиваете им tags — метки, описывающие возможности runner’а.

В job’е вы явно указываете, какие tags ему нужны:

job_name:
  tags:
    - docker
    - linux

Runner с подходящими tags возьмёт эту job в работу. Такой подход даёт намного больше контроля над тем, где и как выполняется код, но требует более осознанной настройки инфраструктуры.

Встроенные переменные и секреты

GitLab предоставляет большой набор встроенных CI-переменных, которые автоматически доступны в каждом job’е: CI_COMMIT_SHA, CI_PROJECT_ID, CI_PIPELINE_ID, CI_MERGE_REQUEST_ID и многие другие.

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

Для секретов и чувствительных данных используется раздел 
Settings → CI/CD → Variables в интерфейсе GitLab.

Там вы можете:

  • Создавать переменные окружения.
  • Помечать их как protected (доступны только для protected-веток и тегов).
  • Помечать как masked (значения не выводятся в логах).

Это стандартный и безопасный способ хранения токенов, ключей и паролей.

Артефакты и кэширование

GitLab чётко разделяет два понятия: артефакты и кэш — и это одно из его сильных мест.

  • Артефакты — это результаты работы job’ов, которые нужны дальше: собранные бинарники, отчёты, файлы сборки. Они сохраняются в GitLab и доступны через UI или для последующих job’ов.
  • Кэш — это временные данные для ускорения повторных запусков (например, зависимости). Кэш обычно хранится на стороне runner’а и не считается результатом сборки.

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


Структура проекта в GitLab для CI/CD

Прежде чем писать конфигурацию CI/CD, имеет смысл разобраться, где именно в GitLab всё находится: какой файл отвечает за пайплайн, где смотреть результаты, логи и статусы, и в каких разделах настраиваются переменные и runner’ы.

Это избавит от лишнего «тыкания» по интерфейсу и сэкономит много времени.

Главный файл: .gitlab-ci.yml

Файл .gitlab-ci.yml должен находиться в корне репозитория и в той ветке, для которой вы хотите запускать CI/CD (чаще всего это main или master).

Это единственный обязательный файл, в котором описывается вся логика CI/CD для проекта.

Пример структуры репозитория:

my-project/
├── .gitlab-ci.yml          ← главный файл CI/CD
├── src/
├── tests/
├── Dockerfile
└── ...

GitLab автоматически отслеживает наличие и изменения этого файла. Как только он появляется в репозитории или вы вносите в него правки, GitLab сам применяет конфигурацию и запускает pipeline при следующем коммите.

Никаких дополнительных «включений» CI/CD делать не нужно — если файл существует, CI считается активным.

 

Где смотреть логи и результаты

Все результаты работы CI/CD доступны прямо в интерфейсе проекта.

Основные разделы, которые вам понадобятся:

Build → Pipelines — список всех pipeline’ов проекта с их текущим статусом (успешно, с ошибкой, в процессе и т.д.).

 

Build → Jobs — список всех job’ов, включая их статус, длительность выполнения и доступ к логам.

 

Deployments → Environments — используется, если в пайплайне задействованы environment’ы (например, staging, production).

Типовой сценарий работы выглядит так:

  1. Открываете нужный pipeline.
  2. Видите список job’ов и stages.
  3. Кликаете по конкретному job’у.
  4. Смотрите полный лог его выполнения.

 

Если job упал — именно здесь вы увидите причину ошибки.

Где настраивать переменные и секреты

Все переменные окружения для CI/CD настраиваются в разделе:

Settings → CI/CD → Variables

Здесь можно задать:

  • Глобальные переменные для проекта.
  • protected-переменные (доступны только в protected-ветках и тегах).
  • masked-переменные (значение скрывается в логах).
  • Переменные, привязанные к конкретным environment’ам (например, разные значения для staging и production).

 

Пример добавления переменной:

  1. Перейдите в Settings → CI/CD → Variables.
  2. Нажмите Add variable.
  3. Укажите ключ и значение.
  4. При необходимости отметьте Protected и/или Masked.
  5. Сохраните переменную.

 

После этого переменная будет доступна во всех job’ах как $VARIABLE_NAME — как обычная переменная окружения внутри скриптов.

Где смотреть runner'ы

Информация о runner’ах находится в разделе:

Settings → CI/CD → Runners

Здесь вы увидите:

 

  • Список всех runner’ов, доступных проекту.
  • Тх текущий статус (online / offline).
  • Tags, назначенные каждому runner’у.

Если у вас есть права администратора GitLab, то управлять runner’ами на уровне всего инстанса можно в разделе 
Admin → CI/CD → Runners.

Для стажёров чаще всего достаточно проектного уровня — главное понимать, какие runner’ы доступны и с какими tags они работают.

Артефакты и их загрузка

После завершения job’а GitLab может сохранить артефакты — файлы, которые были указаны в конфигурации CI/CD.

Скачать их можно несколькими способами:

  • Через Build → Pipelines → выбрать pipeline → Download artifacts.
  • Через Build → Jobs → открыть конкретный job → раздел Artifacts.

Артефакты хранятся ограниченное время (по умолчанию — 30 дней), после чего автоматически удаляются. Это поведение можно настраивать в .gitlab-ci.yml.

 


Простой пример: Hello World Pipeline

Начнём с самого простого пайплайна — его задача не собрать проект и не задеплоить сервис, а просто проверить, что CI/CD в принципе работает и runner успешно выполняет job.

Создаём минимальный .gitlab-ci.yml

Создайте файл .gitlab-ci.yml в корне репозитория со следующим содержимым:

stages:
  - hello

hello_world:
  stage: hello
  tags:
    - shell-185
  script:
    - echo "Hello from GitLab CI!"

Разберём, что здесь происходит:

  • stages — список этапов пайплайна. Даже если этап всего один, его всё равно нужно объявить явно.
  • hello_world — имя job’а (может быть любым).
  • stage: hello — указывает, к какому stage относится job.
  • tagsкритически важный момент: job будет выполнен только тем runner’ом, у которого есть все указанные tags. Если ни один runner не подходит — job зависнет в статусе pending.
  • script — набор команд, которые будут выполнены runner’ом. В данном случае — обычный echo.

Важно: tag shell-185 — это пример. В вашем проекте он должен совпадать с tag’ами реально подключённого runner’а. Если теги не совпадают, pipeline не запустится.

Коммитим и пушим изменения

После создания файла закоммитьте и отправьте его в репозиторий:

git add .gitlab-ci.yml
git commit -m "Add CI/CD config"
git push

Как только изменения попадут в репозиторий, GitLab автоматически создаст новый pipeline.

 

Проверяем запуск pipeline

Перейдите в интерфейсе GitLab в:

Build → Pipelines

Вы должны увидеть новый pipeline со статусом running или passed.

 

Откройте pipeline — внутри будет список job’ов, в нашем случае он всего один.

 

Смотрим лог выполнения

Нажмите на job hello_world. В логе выполнения вы должны увидеть строку:

Hello from GitLab CI!

 

Если вы видите этот вывод и job завершился успешно — значит:

  • .gitlab-ci.yml корректен.
  • Runner подключён и доступен.
  • Теги указаны правильно.
  • CI/CD в проекте работает.

Поздравляю, ваш первый CI/CD pipeline в GitLab успешно запущен. Дальше можно переходить к более полезным и сложным сценариям.


Структура файла .gitlab-ci.yml

Теперь, когда вы понимаете ключевые отличия GitLab CI от GitHub Actions, пора разобрать сам файл конфигурации. Именно .gitlab-ci.yml является сердцем всей CI/CD-системы проекта — всё, что происходит в пайплайне, в итоге описывается здесь.

Расположение, имя файла и базовый синтаксис

Файл должен называться строго .gitlab-ci.yml и находиться в корне репозитория
Это обычный YAML-файл (.yml или .yaml) — текстовый формат для описания конфигураций.

GitLab автоматически проверяет наличие этого файла и запускает pipeline при каждом push (если конфигурация валидна). Никаких дополнительных галочек или кнопок в интерфейсе нажимать не нужно.

Важная заметка про YAML-синтаксис

Если вы раньше редко работали с YAML, запомните два критически важных правила — они спасут вам много времени:

  • Отступы имеют значение. Используются только пробелы, табуляции недопустимы.
  • После двоеточия всегда идёт пробел — это обязательное требование синтаксиса.

Пример с ошибками:

stages:build    # нет пробела после двоеточия
 - build        # неправильный отступ

Корректный вариант:

stages:
  - build       # два пробела отступа
  - test        # одинаковые отступы для элементов одного уровня

Если GitLab не может распарсить YAML-файл, pipeline даже не запустится, а вы увидите ошибку конфигурации.

Основная структура: главные секции

Файл .gitlab-ci.yml состоит из нескольких логических секций. Часть из них опциональна, часть — используется почти всегда, а job’ы вообще являются обязательными.

Пример типовой структуры:

# 1. Глобальные переменные (опционально)
variables:
  LOG_LEVEL: info

# 2. Условия запуска всего pipeline (опционально)
workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE  "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH  "main"'

# 3. Этапы pipeline (почти всегда используется)
stages:
  - build
  - test
  - deploy

# 4. Значения по умолчанию для всех jobs (опционально)
default:
  image: python:3.9
  timeout: 1h

# 5. Сами job'ы (обязательно)
test_job:
  stage: test
  script:
    - echo "Testing..."

build_job:
  stage: build
  script:
    - echo "Building..."

deploy_job:
  stage: deploy
  script:
    - echo "Deploying..."

Коротко по смыслу:

  • variables — глобальные переменные окружения, доступные во всех job’ах.
  • workflow — правила, определяющие, когда вообще создаётся pipeline.
  • stages — последовательность этапов выполнения.
  • default — значения по умолчанию для всех job’ов (чтобы не дублировать одно и то же).
  • job’ы — конкретные задачи, которые выполняет CI/CD.

Дальше давайте разберём каждую из этих секций подробнее и посмотрим, зачем они нужны на практике.

Раздел variables — глобальные переменные

В этом разделе вы определяете переменные окружения, которые будут доступны во всех job’ах пайплайна.

variables:
  LOG_LEVEL: "info"
  DATABASE_URL: "postgres://localhost/mydb"
  DOCKER_REGISTRY: "registry.example.com"
  ENVIRONMENT_NAME: "staging"

Эти переменные автоматически подставляются в окружение каждого job’а и могут использоваться в скриптах:

variables:
  LOG_LEVEL: "info"

test_job:
  script:
    - echo "Log level is $LOG_LEVEL"   # Выведет: Log level is info

Когда имеет смысл использовать глобальные переменные:

  • Для значений, одинаковых для всех job’ов.
  • Для конфигурации проекта (пути, имена сервисов, флаги).
  • Для часто меняющихся параметров (версии, имена окружений и т.п.).

Важно: значения из variables хранятся прямо в репозитории и видны всем, кто имеет доступ к .gitlab-ci.yml
Никогда не кладите сюда пароли, токены, API-ключи и другие секреты.

Для чувствительных данных используйте Settings → CI/CD → Variables в интерфейсе GitLab — именно там переменные можно защитить и скрыть из логов. К этому мы ещё вернёмся в разделе про секреты.

Раздел stages — этапы pipeline

Stage (этап) — это логическая группа job’ов, которые могут выполняться параллельно. 
Сами stage’и при этом выполняются строго последовательно.

stages:
  - test
  - build
  - deploy

Такое описание означает следующее:

  1. Сначала запускаются все job’ы с stage: test.
  2. Если все они завершились успешно, запускаются job’ы с stage: build.
  3. После успешного build начинается deploy.

Если хотя бы один job внутри stage завершится с ошибкой, следующий stage не запустится, если только для этого job’а явно не указано allow_failure: true.

Пример с более детальной разбивкой:

stages:
  - prepare
  - build
  - test
  - integration_test
  - deploy
  - post_deploy

Вы можете объявить столько stage’ов, сколько требуется вашему процессу. На практике чаще всего встречаются:

  • prepare / build — подготовка окружения, установка зависимостей, сборка.
  • test — unit-тесты, линтеры, статический анализ.
  • deploy — развёртывание приложения.
  • post_deploy — проверки после деплоя, уведомления, очистка ресурсов.

Чёткая структура stages делает пайплайн читаемым и предсказуемым.

Раздел default — значения по умолчанию

Чтобы не дублировать одни и те же параметры в каждом job’е, в GitLab CI существует секция default. Все job’ы наследуют значения, указанные в этом блоке, если не переопределяют их явно.

default:
  image: python:3.11
  timeout: 1h
  retry: 1
  tags:
    - docker

build_job:
  stage: build
  script:
    - echo "This job uses Python 3.11 image by default"

test_job:
  stage: test
  script:
    - echo "This job also uses Python 3.11 image"
  timeout: 30m  # Переопределяем timeout только для этого job'а

В этом примере:

  • build_job наследует image, timeout, retry и tags из default.
  • test_job наследует всё то же самое, но переопределяет timeout.

Обратите внимание: если параметр указан и в default, и в job’е — всегда выигрывает значение из job’а.

Что обычно задают в default:

  • image — Docker-образ, в котором выполняются job’ы.
  • timeout — максимальное время выполнения.
  • retry — количество повторных попыток при ошибке.
  • tags — теги runner’ов.
  • variables — общие переменные окружения.
  • cache — правила кэширования.
  • И большинство других параметров job’ов.

Практический совет: если вы видите, что копируете один и тот же параметр в несколько job’ов — почти наверняка ему место в default. Это делает конфигурацию короче, чище и проще для понимания.

Раздел workflow — условия запуска pipeline

Секция workflow отвечает за самое первое решение: нужно ли вообще создавать pipeline
Это уровень выше, чем условия у отдельных job’ов — если pipeline не создан, никакие job’ы даже не будут рассмотрены.

workflow:
  rules:
    # Запускаем pipeline для merge request'ов
    - if: '$CI_PIPELINE_SOURCE  "merge_request_event"'
    # Запускаем для push'ей в ветку main
    - if: '$CI_COMMIT_BRANCH  "main"'
    # Запускаем для тегов
    - if: '$CI_COMMIT_TAG'
    # Во всех остальных случаях pipeline не создаём
    - when: never

В этом примере pipeline будет создан только для:

  • Merge request’ов.
  • Push’ей в main.
  • Тегов.

Все остальные события (например, push в feature-ветку) будут проигнорированы.

Более гибкий и часто используемый пример:

workflow:
  rules:
    # Не запускаем pipeline, если в сообщении коммита есть [skip ci]
    - if: '$CI_COMMIT_MESSAGE =~ /\[skip ci\]/'
      when: never
    # Во всех остальных случаях запускаем
    - when: always

Такой подход позволяет разработчику осознанно пропускать CI/CD для отдельных коммитов.

Переменные, которые чаще всего используются в workflow:

  • $CI_PIPELINE_SOURCE — источник pipeline (push, merge_request_event, schedule, web, api и др.).
  • $CI_COMMIT_BRANCH — имя текущей ветки (для pipeline’ов, запущенных от веток).
  • $CI_COMMIT_TAG — имя тега (если pipeline запущен по тегу).
  • $CI_COMMIT_MESSAGE — сообщение коммита.

Важно: если секция workflow не указана, GitLab создаёт pipeline по умолчанию для большинства событий (push, merge request и т.д.), при условии что .gitlab-ci.yml валиден.

Раздел jobs — определение задач

Job’ы — это основа всей конфигурации CI/CD. Каждый job описывает конкретную задачу, которую должен выполнить runner.

Для job’а можно определить:

  • Что выполнять (script).
  • На каком этапе (stage).
  • На каком runner’е (tags).
  • В каком окружении (image).
  • Какие переменные использовать.
  • Какие артефакты сохранить.
  • Зависимости от других job’ов и многое другое.

Пример:

stages:
  - build
  - test

build_app:
  stage: build
  image: node:18
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 day

run_tests:
  stage: test
  image: node:18
  script:
    - npm install
    - npm run test
  needs:
    - build_app  # Ждём выполнения build_app и получаем его артефакты

Здесь важно несколько моментов:

  • build_app сохраняет результат сборки (dist/) как артефакт.
  • run_tests указывает needs: build_app, поэтому:
    • job не ждёт завершения всего stage build, а стартует сразу после build_app.
    • артефакты build_app будут автоматически доступны.

Это позволяет ускорять pipeline и делать зависимости между job’ами более явными.

Иерархия и наследование параметров

В GitLab CI параметры и переменные наследуются сверху вниз с возможностью переопределения на каждом уровне.

Пример:

# Уровень 1: Глобальные переменные
variables:
  APP_NAME: "my-app"

# Уровень 2: Параметры по умолчанию
default:
  image: python:3.11
  variables:
    LOG_LEVEL: "info"

# Уровень 3: Конкретные job'ы
job_one:
  stage: build
  variables:
    LOG_LEVEL: "debug"  # Переопределяем для этого job'а
  script:
    - echo $APP_NAME
    - echo $LOG_LEVEL

job_two:
  stage: test
  script:
    - echo $APP_NAME
    - echo $LOG_LEVEL

Результат будет таким:

  • job_one:
    • APP_NAME"my-app" (из глобальных переменных).
    • LOG_LEVEL"debug" (переопределён на уровне job’а).
  • job_two:
    • APP_NAME"my-app".
    • LOG_LEVEL"info" (унаследован из default).

Приоритет переменных (от низшего к высшему):

  1. Встроенные переменные GitLab (CI_COMMIT_SHA, CI_PROJECT_ID и т.д.).
  2. Переменные из Settings → CI/CD → Variables.
  3. Глобальные переменные (variables в .gitlab-ci.yml).
  4. Переменные из default.
  5. Переменные, объявленные непосредственно в job’е.

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

Полный пример простого конфига

Теперь давайте соберём всё вместе и посмотрим на целостный, реалистичный пример CI/CD-конфига для простого проекта.

# Глобальные переменные
variables:
  DOCKER_IMAGE: "myapp:latest"
  CACHE_DIR: ".cache"

# Условия запуска pipeline
workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE  "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH  "main"'
    - if: '$CI_COMMIT_TAG'

# Этапы pipeline
stages:
  - build
  - test
  - deploy

# Значения по умолчанию
default:
  image: python:3.11
  timeout: 1h
  cache:
    key: "$CI_COMMIT_REF_SLUG"
    paths:
      - .cache/pip

# Job'ы
install_dependencies:
  stage: build
  script:
    - pip install -r requirements.txt
  artifacts:
    paths:
      - .venv/
    expire_in: 1 day

run_tests:
  stage: test
  script:
    - pip install -r requirements.txt
    - pytest tests/
  needs:
    - install_dependencies

run_linter:
  stage: test
  script:
    - pip install -r requirements.txt
    - pylint src/
  needs:
    - install_dependencies

deploy_to_production:
  stage: deploy
  image: alpine:latest
  script:
    - echo "Deploying to production..."
    - ./scripts/deploy.sh
  only:
    - main
  when: manual  # Запускается вручную

Разберём, что здесь происходит:

  1. Stage build — запускается job install_dependencies. Он устанавливает зависимости и сохраняет их как артефакты, чтобы следующие job’ы могли их использовать.
  2. Stage test — job’ы run_tests и run_linter запускаются параллельно. Оба зависят от install_dependencies (needs), поэтому стартуют сразу после него и получают доступ к его артефактам.
  3. Stage deploy — после успешного завершения test становится доступен job deploy_to_production. Он:
    • Выполняется только для ветки main.
    • Не запускается автоматически, а требует ручного подтверждения (when: manual).

Такой подход часто используется для production-деплоя, чтобы избежать случайных выкладок.

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

Ниже — набор классических ошибок, которые почти гарантированно встречаются у новичков.

Ошибка 1: Забыли пробел после двоеточия

# Неправильно
stages:build

# Правильно
stages:
  - build

YAML требует пробел после : — без него файл считается невалидным.

Ошибка 2: Неправильные отступы

# Неправильно
stages:
 - build        # 1 пробел
  - test        # 2 пробела — разные уровни!

# Правильно
stages:
  - build       # 2 пробела
  - test        # 2 пробела — одинаково

Все элементы одного уровня должны иметь одинаковые отступы.

Ошибка 3: Забыли слово script:

# Неправильно
test_job:
  stage: test
  echo "test"    # Это просто строка, а не команда

# Правильно
test_job:
  stage: test
  script:
    - echo "test"

Без script GitLab просто не знает, что именно нужно выполнять.

Ошибка 4: табуляции вместо пробелов

YAML не поддерживает табуляции. Если вы копируете конфиг из документации, чата или IDE — убедитесь, что используются именно пробелы.

Одна скрытая табуляция может сломать весь pipeline и привести к ошибке парсинга.


Заключение

В статье мы разобрали, чем отличается GitLab от GitHub, с терминологией и расположением разделов в интерфейсе. Также, мы разобрались в устройстве .gitlab-ci.yml - основного файла CI/CD пайплайна. Однако, это только часть того, что нужно знать при работе с GitLab.

Это была первая часть, оставшиеся две (или три?) выйдут с перерывом в два дня.

Если вам интересны подобные материалы, подписывайтесь на Telegram-канал «Код на салфетке». Там я делюсь гайдами для новичков и полезными инструментами. А прямо сейчас у нас ещё и проходит новогодний розыгрыш.

Аватар автора

Автор

Иван Ашихмин

Программист, фрилансер и автор гайдов. Занимаюсь разработкой ботов, сайтов и не только.

Войдите, чтобы оставить комментарий.

Комментариев пока нет.