Агент-инженер по репозиторию · Модуль 5 · Урок 5.2
Создание MR через GitHub/GitLab API: человек в контуре, без auto-merge
Зачем (какую проблему чиним)
Зелёный вердикт получен — пора показать результат человеку. Способ показать — открыть MR/PR. Здесь проходит самая важная граница автономии: агент публикует предложение, но не вливает его. MR — это точка, где человек смотрит, одобряет и мёрджит. Автоматический merge мы не делаем никогда.
Решение и альтернативы
Решение: интерфейс Forge с реализациями для GitHub и GitLab. Агент пушит ветку agent/<task-id> и создаёт MR/PR через API: GitHub — POST /repos/{owner}/{repo}/pulls; GitLab — POST /projects/:id/merge_requests. Целевая ветка — main, но никакого auto-merge, никаких merge-эндпоинтов. Токен — из окружения, с минимальными правами (least privilege).
Альтернативы: агент сам мёрджит при зелёном CI — категорически нет: убирает человека из контура, именно так автономия превращается в инцидент. Только локальная ветка без MR — человек не видит предложения в привычном интерфейсе ревью. MR без auto-merge — единственный безопасный вариант. (Версионная пометка: эндпоинты GitHub/GitLab — на момент написания; сверяйтесь с актуальной докой API.)
DIFF
Вводим Forge (GitHub/GitLab), пуш ветки и создание MR без права на merge; токен — из окружения.
⚠ Безопасность
Инвариант: агент НИКОГДА не делает auto-merge. В коде нет вызова merge-эндпоинта — есть только создание MR. MR — обязательная точка human-in-the-loop. Токен берётся из окружения с правами только на push в не-protected ветки и создание PR (защита main — на стороне репозитория: branch protection + required reviews). Агент не должен иметь прав влить в main даже технически.
Проверка
После зелёного verify агент пушит ветку и создаёт MR; в ответ — URL MR. Проверьте, что в кодовой базе нет ни одного вызова merge-эндпоинта. Ветка main защищена branch protection — прямой push в неё отклоняется сервером.
Глубже
Human-in-the-loop, авторизация инструментов, least privilege — курс «Продакшн-разработка», Модуль 5 (гл. 10–11).
+package main
+
+import "context"
+
+// Forge — хостинг репозитория (GitHub/GitLab). НАМЕРЕННО без метода Merge:
+// агент может предложить изменения, но не влить их. Merge — только человек.
+type Forge interface {
+ PushBranch(ctx context.Context, branch string) error
+ CreatePR(ctx context.Context, pr PullRequest) (url string, err error)
+ // FindPR — для идемпотентности (урок 5.3): не плодить дубли.
+ FindPR(ctx context.Context, branch string) (url string, found bool, err error)
+}
+
+// PullRequest — предложение изменений к target (обычно main). Поле автомержа
+// отсутствует сознательно.
+type PullRequest struct {
+ Branch string // agent/<task-id>
+ Target string // main
+ Title string
+ Body string // структурное описание (урок 5.3)
+}
+
+// gitHub.CreatePR вызывает POST /repos/{owner}/{repo}/pulls.
+// НЕТ вызова PUT .../pulls/{n}/merge — auto-merge не существует в этом коде.Anti-patterns
| Грабля | Почему плохо | Как правильно |
|---|---|---|
| Auto-merge при зелёном CI | Убирает человека из контура; ошибка/инъекция вливается в main автоматически | Только создание MR; merge — исключительно человеком. В коде нет merge-эндпоинта |
| Токен с правами на запись в protected-ветки | Агент технически способен влить в main в обход ревью | Least privilege: push в не-protected ветки + создание PR; защита main на стороне репозитория |
| Хранить токен в коде/логах | Утечка прав на репозиторий | Токен из окружения; в логах — никогда |
Практическое задание (RA-v4)
- Ввести
Forge(GitHub/GitLab) без метода merge; пуш ветки и создание MR через API. - Токен — из окружения с минимальными правами; включить branch protection на
mainв репозитории. - Закоммитить:
git commit -m "v4: create MR via forge API, no auto-merge".
Проверка знаний
Почему агент создаёт MR, но никогда не делает auto-merge, даже при зелёном CI?
Верный ответ: B
B. Граница автономии проходит по merge: агент предлагает, человек решает. Auto-merge при зелёном CI всё равно опасен — CI не ловит всё, а инъекция/ошибка может пройти проверки. Поэтому в коде агента merge-эндпоинта просто нет.
Какой набор прав у токена агента соответствует принципу наименьших привилегий?
Верный ответ: B
B. Агенту нужно ровно столько, чтобы запушить свою ветку и открыть PR. Возможность влить в main должна отсутствовать даже технически — её обеспечивают branch protection и обязательное ревью на стороне репозитория. Admin/force-push/удаление (A, C, D) нарушают least privilege.