GitLab CI/CD и headless-автоматизация
Если в предыдущей статье у нас был готовый claude-code-action — обёртка, которую достаточно добавить в YAML и всё заработает — то с GitLab история другая. Здесь нет готового «action», и это на самом деле плюс: вы работаете напрямую с CLI через headless-режим, что даёт полный контроль над каждым вызовом.
> Статус: Официальная интеграция Claude Code с GitLab CI/CD находится в бета-версии и поддерживается командой GitLab. Актуальный трекер — gitlab.com/gitlab-org/gitlab/-/issues/573776.
Headless-режим: что происходит внутри
Флаг -p (или --print) превращает Claude из интерактивного собеседника в инструмент командной строки: запустил → агентный цикл выполнился → вышел с кодом 0 или ненулевым. Это и есть headless-режим.
# Простейший вызов: прочитать и проанализировать
claude -p "Найди потенциальные баги в src/auth/" --allowedTools "Read,Bash"
# С JSON-выводом — удобно парсить в CI
claude -p "Проверь code style" --output-format json | jq -r '.result'
# Передать данные через pipe
git diff origin/main | claude -p "Сделай ревью этого диффа" --output-format textВ конвейере важны три флага:
--max-turns N— ограничить количество шагов агентного цикла, иначе агент может крутиться неограниченно--max-budget-usd N— жёсткий потолок затрат на один вызов (только в print-режиме)--permission-mode acceptEdits— разрешить запись файлов без подтверждения, что нужно для автоматических правок
sequenceDiagram
participant U as Пользователь / Триггер
participant GL as GitLab CI/CD
participant R as Runner (контейнер)
participant C as claude -p
participant AG as Агентный цикл
participant Repo as Репозиторий
U->>GL: Событие (MR / schedule / web / @claude)
GL->>R: Запуск job: node:24-alpine3.21
R->>R: apk add git curl bash
R->>R: curl install.sh | bash
R->>C: claude -p "$AI_FLOW_INPUT" --allowedTools ...
loop Агентный цикл
C->>AG: Планирование шага
AG->>Repo: Read / Edit / Bash
Repo-->>AG: Результат инструмента
AG->>C: Наблюдение → следующий шаг
end
C-->>R: Итог (text / json)
R->>Repo: git commit + push
Repo->>GL: Новый MR или комментарийБазовая установка в .gitlab-ci.yml
GitLab CI/CD не умеет «скачать action» — вы сами устанавливаете Claude в before_script. Рекомендуемый базовый шаблон:
stages:
- ai
claude:
stage: ai
image: node:24-alpine3.21
rules:
- if: '$CI_PIPELINE_SOURCE == "web"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
variables:
GIT_STRATEGY: fetch
before_script:
- apk update
- apk add --no-cache git curl bash
- curl -fsSL https://claude.ai/install.sh | bash
script:
# GitLab MCP Server (если настроен) — даёт доступ к API GitLab
- /bin/gitlab-mcp-server || true
- >
claude
-p "${AI_FLOW_INPUT:-'Проанализируй изменения и предложи правки'}"
--permission-mode acceptEdits
--allowedTools "Bash Read Edit Write mcp__gitlab"
--max-turns 10
--max-budget-usd 3.00Аутентификация. Зайдите в Settings → CI/CD → Variables, добавьте ANTHROPIC_API_KEY с флагами «Masked» и «Protected». Claude Code подхватывает переменную автоматически — никакого явного --api-key не нужно.
Образ. node:24-alpine3.21 — официально рекомендованный образ. Alpine требует явной установки git и bash через apk, иначе агент упадёт при попытке работать с репозиторием.
Переменные AI_FLOW_*: контекст из тредов
Когда пайплайн запускается через webhook (например, кто-то написал @claude в комментарии к MR), контекст передаётся через специальные переменные:
AI_FLOW_INPUT— текст запроса (что написал пользователь)AI_FLOW_CONTEXT— идентификатор MR, issue или тредаAI_FLOW_EVENT— тип события (note,merge_request, и т.д.)
В script-блоке это выглядит так:
# Логируем контекст для отладки
echo "Запрос: $AI_FLOW_INPUT"
echo "Контекст: $AI_FLOW_CONTEXT, событие: $AI_FLOW_EVENT"
claude -p "$AI_FLOW_INPUT" \
--allowedTools "Bash Read Edit Write mcp__gitlab" \
--permission-mode acceptEditsЕсли AI_FLOW_INPUT не задан (ручной запуск через UI), используйте дефолт через bash-подстановку: ${AI_FLOW_INPUT:-'Дефолтная задача'}.
Три паттерна автоматизации
Паттерн 1: Автоматическое ревью при открытии MR.
Запускается на событие merge_request_event, передаёт диффы через stdin:
mr-review:
stage: ai
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: always
image: node:24-alpine3.21
before_script:
- apk add --no-cache git curl bash
- curl -fsSL https://claude.ai/install.sh | bash
script:
- >
git diff origin/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}...HEAD
| claude -p
"Это diff Merge Request. Найди баги, проблемы безопасности и
нарушения code style. Прокомментируй конкретные строки."
--output-format json
--max-turns 5
--max-budget-usd 2.00
| tee review.json
- jq -r '.result' review.json
artifacts:
paths: [review.json]
expire_in: 7 daysПаттерн 2: Scheduled-обслуживание кодовой базы.
Раз в неделю — обход устаревших TODO и потенциальных улучшений:
weekly-audit:
stage: ai
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
image: node:24-alpine3.21
before_script:
- apk add --no-cache git curl bash
- curl -fsSL https://claude.ai/install.sh | bash
script:
- >
claude --bare
-p "Найди все TODO-комментарии старше месяца, проанализируй
их актуальность и создай список рекомендаций."
--allowedTools "Read,Bash"
--output-format json
--max-turns 8
--no-session-persistence
| jq -r '.result' > weekly-report.md
artifacts:
paths: [weekly-report.md]Паттерн 3: Автоматические правки по запросу.
Через web-триггер с передачей AI_FLOW_INPUT:
auto-fix:
stage: ai
rules:
- if: '$CI_PIPELINE_SOURCE == "web"'
image: node:24-alpine3.21
before_script:
- apk add --no-cache git curl bash jq
- curl -fsSL https://claude.ai/install.sh | bash
# Настройка git для коммитов от агента
- git config user.email "claude-bot@example.com"
- git config user.name "Claude Bot"
script:
- >
claude
-p "${AI_FLOW_INPUT}"
--permission-mode acceptEdits
--allowedTools "Bash Read Edit Write"
--max-turns 15
--max-budget-usd 5.00
# Коммит и push результатов
- git add -A && git commit -m "fix: automated changes by Claude" || echo "Нет изменений"
- git push origin HEAD:${CI_COMMIT_REF_NAME}--bare: ускорение старта в CI
По умолчанию claude -p читает CLAUDE.md, хуки, плагины, MCP-серверы из рабочей директории. В CI это часто лишнее и замедляет запуск.
Флаг --bare отключает всё автообнаружение: CLAUDE.md, хуки, плагины, MCP-серверы, auto memory. Остаётся только то, что вы явно передали через флаги. Результат: воспроизводимые, быстрые запуски — поведение не зависит от того, что случайно лежит в репозитории.
# Без --bare: читает всё из .claude/
claude -p "задача" --allowedTools "Read"
# С --bare: только явно переданное
claude --bare -p "задача" --allowedTools "Read" --append-system-prompt "Ты лаконичный ревьюер."> Официальная документация отмечает: --bare станет дефолтным для -p в будущих версиях. Рекомендуется явно его использовать сейчас.
Есть один нюанс: --bare также отключает чтение CLAUDE.md. Если контекст проекта нужен, передайте его через --append-system-prompt-file ./CLAUDE.md.
Enterprise: Bedrock и Vertex AI
Для корпоративных сред с требованиями к data residency — Claude Code поддерживает те же провайдеры, что и GitHub Actions. Вместо ANTHROPIC_API_KEY используется OIDC-аутентификация:
- Amazon Bedrock: GitLab OIDC → IAM роль через
aws sts assume-role-with-web-identity, временные credentials в переменных среды. Модели с региональным префиксом:us.anthropic.claude-sonnet-4-6. - Google Vertex AI: Workload Identity Federation, без хранения ключей. Переменные
GCP_WORKLOAD_IDENTITY_PROVIDERиGCP_SERVICE_ACCOUNT.
Оба варианта требуют ручной настройки — quickstart через one-liner не работает. Подробные YAML-примеры есть в официальной документации GitLab.
Практические соображения
Стоимость. В отличие от GitHub Actions с фиксированной стоимостью ревью, в GitLab вы платите и за runner-минуты, и за токены API отдельно. --max-budget-usd — ваш главный предохранитель. Запуск на каждый push в MR быстро накапливает расходы; ограничивайте триггеры через rules.
Параллельные пайплайны. Настройте interruptible: true на job-уровне, чтобы новый push отменял предыдущий запуск агента:
claude:
interruptible: true
# ...Логи. Флаг --debug в CI — ваш лучший друг при отладке. Также добавьте --output-format json и сохраняйте артефакты: total_cost_usd в JSON-ответе позволяет отслеживать затраты по каждому запуску без открытия dashboard.
CLAUDE.md в репозитории. Без --bare агент читает его и следует правилам. Это главный способ передать стандарты кода, запрещённые паттерны и специфику проекта — так же, как при локальном запуске. Подробнее — в статье CLAUDE.md и система памяти.
Безопасность. ANTHROPIC_API_KEY — всегда masked переменная. Изменения агента идут через MR, так что команда видит каждый диф и применяются правила branch protection. О рисках bypassPermissions в публичных репозиториях — в Модель разрешений, безопасность и доверие.
See also
- GitHub Actions и автоматический code review — альтернативный подход с готовым action для GitHub
- Headless-режим и скриптинг через CLI — полный справочник по флагам
-pи автоматизации через CLI - CLAUDE.md и система памяти — как задать контекст проекта, который агент читает в CI
- Модель разрешений, безопасность и доверие — режимы разрешений и безопасность в автоматизированных окружениях
- Claude Agent SDK: программная сборка агентов — если нужен программный контроль поверх CLI
- Облачные агенты: web, routines и фоновые задачи — альтернатива CI/CD для задач без привязки к пайплайну
- Практика: GitHub, базы данных и веб-API через MCP — использование MCP-инструментов внутри pipeline-вызовов