Агент-инженер по репозиторию · Модуль 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).

forge.go: создание MR без auto-merge (новый файл, фрагмент)
+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

Грабли публикации MR
ГрабляПочему плохоКак правильно
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?

  • A Auto-merge технически невозможен через API
  • B MR — обязательная точка одобрения человеком (human-in-the-loop); auto-merge убирает человека из контура и автоматически вливает возможную ошибку/инъекцию
  • C Merge дороже по токенам
  • D GitHub запрещает merge ботам

Какой набор прав у токена агента соответствует принципу наименьших привилегий?

  • A Полный admin на репозиторий
  • B Push в не-protected ветки и создание PR; защита main (branch protection, required reviews) — на стороне репозитория
  • C Право force-push в main
  • D Права на удаление репозитория для уборки