ZubrCode в GitLab CI
ZubrCode может работать прямо в ваших пайплайнах GitLab: ревьюить merge
request’ы и разбирать упавшие пайплайны. Шаблоны готовые — подключаются
include в .gitlab-ci.yml, скрипты к себе копировать не нужно. Шаблоны
публикуются на get.zubriq.by с ближайшим выпуском ZubrCode.
Две джобы
Заголовок раздела «Две джобы»zubrcode:review — ревью merge request’а. Джоба забирает диф MR и отдаёт
его агенту; тот ищет только значимое: ошибки, безопасность, потерю данных,
явные регрессии. Находки high и medium постятся обсуждениями прямо на
строках дифа, low — списком в одном сводном комментарии. Сводный
комментарий при повторных прогонах обновляется, а не плодится; обсуждения не
дублируются. Lock-файлы и сгенерированное (*.lock, package-lock.json,
pnpm-lock.yaml, bun.lockb, dist/, vendor/, *.min.*) пропускаются.
zubrcode:doctor — разбор упавшего пайплайна. Стадия .post,
when: on_failure: агент смотрит хвост лога (300 строк) каждой упавшей джобы
и решает — инфраструктура (перезапустить) или код (что именно сломано). Итог —
один комментарий в MR, а если пайплайн не про MR — в лог джобы. С
ZUBRCODE_RETRY_INFRA=1 джобы с вердиктом «инфраструктура» перезапускаются
один раз.
Обе джобы allow_failure: true — ZubrCode никогда не блокирует ваш пайплайн.
Подключение
Заголовок раздела «Подключение»include: - remote: 'https://get.zubriq.by/zubrcode/gitlab/zubrcode-review.yml' - remote: 'https://get.zubriq.by/zubrcode/gitlab/zubrcode-pipeline-doctor.yml'
stages: [test]
test: stage: test script: - npm ci - npm testСкрипты (review.ts, doctor.ts) обе джобы скачивают с get.zubriq.by
(адрес переопределяется ZUBRCODE_SCRIPTS_BASE) — копировать их в свой
репозиторий не нужно.
zubrcode:review живёт в стадии .pre (есть в любом пайплайне),
zubrcode:doctor — в .post. Стадию и другие ключи джоб можно переопределить
после include:
zubrcode:review: stage: testДля проектов ZuBrIQ доступно подключение из нашего репозитория:
include: - project: 'artcloud/zubrcode' ref: main file: - 'gitlab/zubrcode-review.yml' - 'gitlab/zubrcode-pipeline-doctor.yml'Переменные
Заголовок раздела «Переменные»Settings → CI/CD → Variables. Первые две — masked.
| Переменная | Обязательна | Что |
|---|---|---|
ZUBRIQ_API_KEY |
да | ключ ZuBrIQ, по нему списывается расход. Бинарь zubrcode берёт её сам |
ZUBRCODE_GITLAB_TOKEN |
для комментариев | project/group access token со scope api и ролью не ниже Developer. Без него review напишет находки в лог и выйдет с кодом 0, doctor не заработает |
ZUBRCODE_MODEL |
нет | модель в формате провайдер/модель, по умолчанию zubriq/zubr-coder |
ZUBRCODE_MAX_DIFF |
нет | лимит дифа в символах, по умолчанию 60000 |
ZUBRCODE_TIMEOUT_SECONDS |
нет | таймаут агента, по умолчанию 900 |
ZUBRCODE_RETRY_INFRA |
нет | 1 — doctor перезапускает инфра-падения (один раз на джобу) |
ZUBRCODE_SCRIPTS_BASE |
нет | откуда качать скрипты, по умолчанию https://get.zubriq.by/zubrcode/gitlab |
Права токена
Заголовок раздела «Права токена»ZUBRCODE_GITLAB_TOKEN — project access token
или group access token для группы проектов: scope api, роль Developer
или выше. Токен нужен для чтения дифа MR, создания и обновления комментариев и
обсуждений, чтения джоб и логов, перезапуска джоб (doctor). Удобно выдавать
один токен на группу проектов и прятать в group variables.
Стоимость
Заголовок раздела «Стоимость»Запросы идут по вашему ключу ZuBrIQ — по тарифу пространства или балансу
(zubriq.by/chat → Настройки →
Биллинг). Один прогон ревью — примерно
один запрос к модели: диф обрезается до ZUBRCODE_MAX_DIFF символов, агент
может дополнительно читать файлы репозитория.
Ограничения
Заголовок раздела «Ограничения»- Ревью не блокирует MR:
allow_failure: true, находки — только комментарии. - Обсуждения привязываются к строкам нового файла; если GitLab не принял позицию (например, строка вне дифа), находка падает в сводный комментарий.
- Если API недоступен (нет токена и закрытый проект), диф берётся из склонированного репозитория, находки публикуются только в лог.
- Doctor перезапускает джобу не больше одного раза: повторная джоба с тем же
именем или флаг
retriedв API — сигнал, что уже перезапускали. - Ответ агента, который не удалось разобрать как JSON, публикуется как есть (обрезанным до 3000 символов).