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 выполняется даже при ошибке) |
image | Docker-образ, в котором идёт задача |
services | дополнительные контейнеры рядом (БД и т. п.), с alias — имя хоста |
variables | переменные задачи |
tags | выбрать раннер по тегам |
extends | унаследовать ключи из шаблона (скрытой задачи) |
timeout / retry | ограничение времени / сколько раз перезапустить при сбое |
parallel: matrix: | запустить задачу несколько раз с разными наборами переменных |
trigger | запустить дочерний конвейер или конвейер другого проекта |
Когда выполнять
| Ключ | Что задаёт |
|---|---|
rules | список условий; срабатывает первое подходящее |
rules: - if: | выражение над переменными: $CI_COMMIT_BRANCH == "main", $VAR =~ /^v\d+/ |
rules: - changes: | только если изменились файлы по шаблонам |
rules: - exists: | только если в репозитории есть файл |
when | on_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