← Весь справочник

GitLab CI (.gitlab-ci.yml)

Конвейер GitLab CI — stages, jobs, script, rules, needs, artifacts, cache, extends, include, variables

GitLab CI запускает конвейер (pipeline) по файлу .gitlab-ci.yml в корне репозитория. Конвейер состоит из задач (jobs), задачи группируются в стадии (stages). Стадии идут по очереди, задачи одной стадии — параллельно. Каждая задача выполняет свои команды script на раннере, обычно в чистом Docker-контейнере.

Проверка в песочнице: yamlschema gitlab-ci .gitlab-ci.yml сверяет файл с официальной JSON-схемой GitLab и дополнительно проверяет, что у каждой задачи есть script и что её stage объявлена.

Синтаксис

stages:          # порядок стадий
  - build
  - test

имя_задачи:      # любой ключ верхнего уровня, кроме зарезервированных, — задача
  stage: test
  script:
    - команда

Ключи, начинающиеся с точки (.template), — скрытые: это не задачи, а шаблоны для extends.

Ключи верхнего уровня

КлючЧто задаёт
stagesсписок стадий по порядку; по умолчанию build, test, deploy (плюс служебные .pre и .post)
variablesпеременные для всех задач
defaultзначения по умолчанию для всех задач: image, before_script, after_script, cache, retry, tags…
includeподключить другие YAML-файлы
workflow: rules:запускать ли конвейер вообще

Ключи задачи

Что и где выполнять

КлючЧто задаёт
stageстадия задачи (по умолчанию test)
scriptкоманды оболочки — обязательный ключ (если нет trigger или extends)
before_script / after_scriptкоманды до / после script (after_script выполняется даже при ошибке)
imageDocker-образ, в котором идёт задача
servicesдополнительные контейнеры рядом (БД и т. п.), с alias — имя хоста
variablesпеременные задачи
tagsвыбрать раннер по тегам
extendsунаследовать ключи из шаблона (скрытой задачи)
timeout / retryограничение времени / сколько раз перезапустить при сбое
parallel: matrix:запустить задачу несколько раз с разными наборами переменных
triggerзапустить дочерний конвейер или конвейер другого проекта

Когда выполнять

КлючЧто задаёт
rulesсписок условий; срабатывает первое подходящее
rules: - if:выражение над переменными: $CI_COMMIT_BRANCH == "main", $VAR =~ /^v\d+/
rules: - changes:только если изменились файлы по шаблонам
rules: - exists:только если в репозитории есть файл
whenon_success (по умолчанию), manual (кнопка), always, on_failure, delayed (+ start_in), never
allow_failureпадение задачи не валит конвейер
only / exceptустаревший способ условий (ветки, теги, переменные); с rules в одной задаче не совмещается

Связи и файлы

КлючЧто задаёт
needsзапуститься сразу после указанных задач, не дожидаясь конца стадии; needs: [] — сразу
dependenciesартефакты каких задач скачать ([] — никаких)
artifacts: paths:файлы, которые сохраняются после задачи и передаются следующим
artifacts: expire_in / when / reportsсрок хранения / при каком исходе сохранять / отчёты (junit и др.)
cache: key: paths:кэш между запусками (зависимости), не гарантирован
environmentокружение для деплоя: name, url
resource_groupне запускать параллельно две задачи с одной группой
coverageрегулярное выражение для процента покрытия из лога

Варианты include

ЗаписьОткуда
- local: путь/файл.ymlиз этого же репозитория
- project: группа/проект + file: + ref:из другого проекта GitLab
- remote: https://…/file.ymlпо URL
- template: имя.gitlab-ci.ymlвстроенный шаблон GitLab

Предопределённые переменные

ПеременнаяЗначение
CI_COMMIT_BRANCHветка (пусто для тегов и merge request)
CI_DEFAULT_BRANCHосновная ветка проекта
CI_COMMIT_TAGтег, если конвейер по тегу
CI_COMMIT_SHA / CI_COMMIT_SHORT_SHAхэш коммита
CI_PIPELINE_SOURCEпричина запуска: push, merge_request_event, schedule, web…
CI_PROJECT_DIRкаталог с исходниками внутри задачи
CI_JOB_NAME, CI_PIPELINE_IDимя задачи, номер конвейера
CI_REGISTRY_IMAGEадрес образов проекта в реестре GitLab

Примеры

stages:
  - build
  - test
  - deploy

variables:
  APP_ENV: staging

default:
  image: alpine:3.20

.base:
  before_script:
    - echo "общая подготовка"

build:
  stage: build
  extends: .base
  script:
    - mkdir -p dist
    - echo "built" > dist/app.txt
  artifacts:
    paths:
      - dist/
    expire_in: 1 week

unit:
  stage: test
  needs: [build]
  script:
    - cat dist/app.txt

lint:
  stage: test
  needs: []
  script:
    - echo lint

docs:
  stage: test
  script:
    - echo "docs changed"
  rules:
    - changes:
        - docs/**/*

deploy:
  stage: deploy
  script:
    - echo "deploy to $APP_ENV"
  environment: production
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: manual

Конвейер только для основной ветки, тегов и merge request:

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $CI_COMMIT_TAG
# проверить файл по схеме
yamlschema gitlab-ci .gitlab-ci.yml && echo OK

# типичные сообщения:
# job: job has no script
# job: stage 'tests' is not declared in stages
# job: Additional properties are not allowed ('scripts' was unexpected)

# быстро посмотреть, какие задачи есть в файле
yq 'keys' .gitlab-ci.yml

Подводные камни

  • Задача без script не запустится: GitLab отвергнет весь файл.
  • stage должна быть в stages. Опечатка в имени стадии — ошибка конфигурации. Задача без stage попадает в test.
  • Двоеточие с пробелом внутри команды ломает YAML. - echo "a: b" YAML читает как словарь {'echo "a': 'b"'}. Бери всю строку в одинарные кавычки: - 'echo "a: b"' — или используй блок |.
  • rules и only/except в одной задаче несовместимы, GitLab отклонит конфигурацию. Локальная проверка yamlschema этого не ловит.
  • Если ни одно правило rules не подошло, задача не добавляется в конвейер. Правило без if в конце работает как «иначе».
  • needs ссылается на задачи по имени, и они должны существовать в конвейере. Схема это не проверяет — ошибку покажет только сам GitLab.
  • Артефакты и кэш — разные вещи. Артефакты гарантированно передаются задачам следующих стадий; кэш — лишь ускорение, на него нельзя полагаться для передачи результатов.
  • Задачи не делят файловую систему. То, что создано в одной задаче, в другой появится только через artifacts.
  • after_script выполняется в отдельной оболочке: переменные и cd из script там не видны.
  • Теги вида !reference [.шаблон, script] понимает GitLab, но не обычный YAML-парсер: yamlschema на них выдаст ошибку разбора.

См. также

github-actions · git · yq · docker-compose