Навигация
CI/CD - продвинутое
Matrix-сборки, retry, concurrency, условия запуска, runner'ы, K8s auto-scaling
Этот раздел описывает продвинутые возможности CI/CD: матричные сборки, повторы при сбоях, управление параллельностью, условия запуска, внешние раннеры и автомасштабирование в Kubernetes.
Базовые понятия (workflow, jobs, triggers, artifacts, cache) описаны в разделе CI/CD пайплайны.
Матричные сборки
Когда нужно протестировать проект на нескольких версиях языка, ОС или конфигурациях - используйте матрицу. GitRiver создаст отдельную задачу для каждой комбинации.
jobs:
test:
strategy:
matrix:
os: [ubuntu, alpine]
rust: ['1.80', '1.93', stable]
fail_fast: false
max_parallel: 4
image: rust:${{ matrix.rust }}
steps:
- run: cargo test
Это создаст 6 задач (2 ОС × 3 версии Rust). Значения доступны через ${{ matrix.ключ }}.
- fail_fast - если
true(по умолчанию), при первом провале остальные задачи отменяются. Установитеfalseчтобы дождаться всех. - max_parallel - ограничение параллельности (по умолчанию без лимита).
Добавление и исключение комбинаций
strategy:
matrix:
os: [ubuntu, alpine]
rust: [stable, nightly]
include:
- os: ubuntu
rust: nightly
features: experimental
exclude:
- os: alpine
rust: nightly
include добавляет комбинации с дополнительными переменными. exclude убирает ненужные.
Условия запуска задач
По значению переменной
Запускать деплой только из ветки main:
jobs:
deploy:
if: $CI_COMMIT_BRANCH == "main"
steps:
- run: ./deploy.sh
При ошибке предыдущей задачи
Отправить уведомление если тесты провалились:
jobs:
notify:
needs: [test]
if: failure()
steps:
- run: curl -X POST $SLACK_WEBHOOK -d '{"text":"Тесты упали!"}'
Доступные выражения
| Выражение | Когда срабатывает |
|---|---|
$CI_COMMIT_BRANCH == "main" | Точное сравнение строк |
$CI_COMMIT_TAG =~ /^v\d+/ | Совпадение по регулярному выражению |
success() | Все предыдущие задачи успешны |
failure() | Хотя бы одна предыдущая задача провалилась |
always() | Всегда (даже при отмене пайплайна) |
cancelled() | Пайплайн был отменён |
Правила запуска (rules)
Правила - более гибкий вариант условий. Они проверяются сверху вниз; первое совпавшее определяет, что произойдёт с задачей.
Зачем нужны: когда одно условие if недостаточно - например, для main деплоить автоматически, при изменении src/ - ждать ручного запуска, а для всего остального - не запускать.
rules:
- if: "$CI_COMMIT_BRANCH == 'main'"
when: always
- changes:
- "src/**"
when: manual
- when: never
Значение when | Что происходит |
|---|---|
always | Задача запускается автоматически |
never | Задача не запускается |
manual | Задача ждёт ручного запуска (кнопка «Запустить» в интерфейсе) |
on_success | Запуск если зависимости успешны (по умолчанию) |
on_failure | Запуск если зависимости провалились |
Повторы при сбоях (retry)
Если задача может упасть из-за нестабильной сети или flaky-тестов - настройте автоматический повтор:
jobs:
test:
retry:
max: 2
when: [script_failure, stuck_or_timeout_failure]
steps:
- run: npm test
- max - максимум повторов (0-2)
- when - при каких ошибках повторять:
script_failure- команда вернула ненулевой кодstuck_or_timeout_failure- задача зависла или превысила таймаутalways- при любой ошибке (пустой список =always)
Управление параллельностью (concurrency)
Проблема: при быстрых push подряд запускается несколько пайплайнов одновременно, и деплой может выполняться параллельно - это опасно.
Решение: группа параллельности. Задачи с одинаковым group не запускаются параллельно.
concurrency:
group: deploy-$CI_COMMIT_BRANCH
cancel_in_progress: true
Если cancel_in_progress: true - при новом запуске предыдущий автоматически отменяется. Это полезно для CI-тестов: зачем дождёмся старый результат, если уже есть новый push.
Допускаемый сбой (allow_failure)
Если задача не критична для пайплайна (например, линтер, который вы только внедряете):
jobs:
lint:
allow_failure: true
steps:
- run: cargo clippy -- -D warnings
Провал этой задачи не сделает пайплайн красным - он останется зелёным.
Прерываемые задачи (interruptible)
Чтобы задача автоматически отменялась при новом push в тот же ref:
jobs:
test:
interruptible: true
steps:
- run: cargo test
Работает вместе с concurrency - при новом push в ветку старая задача прерывается.
Передача данных между задачами (outputs)
Задача может передать значения следующим задачам. Например, одна задача определяет версию, а другая использует её при деплое.
Запись - через файл $CI_OUTPUT:
jobs:
prepare:
steps:
- run: |
VERSION=$(cat VERSION)
echo "version=$VERSION" >> $CI_OUTPUT
deploy:
needs: [prepare]
steps:
- run: echo "Деплой версии $NEEDS_PREPARE_OUTPUTS_VERSION"
Имя переменной формируется автоматически: NEEDS_<ИМЯ_ЗАДАЧИ>_OUTPUTS_<КЛЮЧ> (всё в верхнем регистре).
Внешние раннеры
По умолчанию GitRiver выполняет CI-задачи на том же хосте через Docker. Для масштабирования или изоляции можно подключить внешние раннеры - отдельные машины, которые забирают задачи с сервера.
Регистрация раннера
- Откройте Администрирование -> «Раннеры»
- Нажмите «Добавить раннер»
- Укажите имя, описание и метки (например:
linux,gpu,arm64) - Сохраните токен - он показывается только один раз
Установка раннера
На машине, где будет выполняться раннер:
gitriver-runner --token <ТОКЕН> --server https://git.example.com
Раннер регулярно опрашивает сервер (каждые 3 секунды по умолчанию), забирает задачи с подходящими метками и выполняет их в Docker.
Маршрутизация задач по меткам
В workflow укажите, на каком раннере выполнять задачу:
jobs:
gpu-test:
runs_on: [self-hosted, linux, gpu]
steps:
- run: python train.py
Задача будет назначена раннеру, у которого есть все указанные метки.
K8s Auto-Scaling Runners
Для автоматического масштабирования раннеров в Kubernetes - GitRiver создаёт K8s Jobs по мере поступления CI-задач и удаляет поды после завершения.
Настройка
- Подключите кластер: Администрирование -> «Кластеры» -> «Добавить кластер»
- Укажите API URL и сертификат CA, или загрузите kubeconfig
- Нажмите «Тест подключения» для проверки
- Создайте конфигурацию: Администрирование -> «K8s Runners» -> «Добавить»
- Укажите:
- Кластер - в каком кластере создавать поды
- Namespace - в каком namespace
- Docker image - образ для раннера
- Label (runs_on) - метка для маршрутизации задач
- Макс. pods - ограничение одновременных подов
- Ресурсы CPU/RAM, tolerations, node selector (опционально)
Как это работает
- CI-задача с меткой
runs_on: [k8s]попадает в очередь - GitRiver создаёт K8s Job в указанном кластере/namespace
- Pod запускается, забирает задачу, выполняет и отправляет результат
- После завершения pod удаляется
Веб-терминал (Web Terminal)
Веб-терминал позволяет подключиться к работающему CI-контейнеру в реальном времени - для отладки, проверки состояния файловой системы или ручного запуска команд.
Когда доступен
- Задача выполняется (Running)
- У задачи указан Docker-образ (
image:) - У вас есть права на запись в репозиторий
Как использовать
- Откройте выполняющуюся задачу во вкладке «CI/CD»
- Нажмите кнопку «Терминал» (появляется рядом с логами)
- Откроется интерактивный терминал в браузере
- Вы можете выполнять любые команды внутри контейнера
Терминал поддерживает полноценный PTY: автодополнение по Tab, стрелки для навигации по истории, Ctrl+C для прерывания.
Ограничения
- Терминал закрывается автоматически при завершении задачи
- Размер терминала: 24×80 символов
- Доступен только для Docker-задач (не для задач без
image:)
Множественные workflow-файлы
В одном репозитории может быть несколько workflow:
.gitriver/
workflows/
ci.yml - тесты при каждом push
release.yml - сборка при push тега
nightly.yml - ночные тесты по расписанию
deploy.yml - деплой в production
При push GitRiver проверяет все файлы и запускает те, чьи триггеры совпали.
Максимум 20 workflow-файлов на репозиторий.