fix(tools): cleanup local pr-N branches in merge-pr tool #53
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/tools/merge-pr-cleanup-pr-branches"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что сделано
.opencode/tools/merge-pr.ts: добавлен helpercleanupPrBranch(prNumber, cwd)—guard через
git branch --list pr-N(пустой stdout → skip),git branch -D pr-Nпри наличии, soft fail
⚠️ failed to delete local pr-N branch: <stderr>при ошибке(НЕ блокирует merge). Вызов добавлен во все return-точки после успешного merge
(кроме repo-mismatch path — там локальная очистка пропущена целиком).
tests/_ts_loader.mjs: stubgit branch --listрасширен — для targetpr-*по умолчанию возвращает пустой stdout (существующие тесты не ломаются), override
через
GIT_PR_BRANCH_LIST_STUB(например"pr-45") для тестов pr-N cleanup.tests/test_merge_pr_tool.py: 2 новых теста(
test_merge_pr_cleans_pr_branch,test_merge_pr_no_pr_branch) — покрываютpresence/absence pr-N ветки. Существующие 15 тестов без регрессии.
docs/decisions/098-pr-53-merge-pr-cleanup-pr-branches.md: ADR с обоснованиемfix в
merge-pr.ts(deterministic, single source of truth) vsrun-pipeline/SKILL.mdTemplate D manual cleanup (протокольное изменение, race condition, не покрывает
PR без fix_ci).
Почему
run-pipeline/SKILL.mdTemplate D (fix_ci) создаёт локальные веткиpr-Mчерезgit fetch origin pull/M/head:pr-M, ноmerge-pr.tsчистил только оригинальнуюfeature-ветку (по
headRef), аpr-Mне трогал — ветки копились бесконечно.В репо уже накопилось 9 мусорных веток (
pr-19, pr-25, pr-280, ...).Cleanup в
merge-pr.tsdeterministic: tool вызывается ровно один раз на PR(merge phase), не зависит от того, запускал ли агент fix_ci.
Watch out
pr-${pr_number}(текущего PR) — НЕ всеpr-*ветки(иначе можно удалить pr-N другого PR при parallel work).
pr-39-review(не-стандартное имя с суффиксом) НЕ матчитсяpr-39—existing
pr-39-reviewручная мусорная ветка, не удаляется автоматически.worktreeRepo !== full) → cleanup пропущен целиком(headRef и pr-N) — worktree не принадлежит PR repo.
GIT_PR_BRANCH_LIST_STUBпо умолчанию пустой — это намеренно, чтобысуществующие тесты (не знающие про pr-N cleanup) не видели pr-N ветку
и не получали diff в expected messages. Тесты с pr-N cleanup явно
выставляют stub.
Pending
pr-19, pr-25, pr-280, pr-30, pr-32, pr-39, pr-39-review, pr-45, pr-46) — вне scope (гигиена, отдельный bash).run-pipeline/SKILL.mdTemplate D — без изменений (созданиеpr-Mостаётся;cleanup переезжает в merge-pr tool).
Closes #50
Closes #50
Code Review Summary
Чистый, хорошо документированный PR. Добавляет cleanup локальных
pr-Nветок вmerge-pr.ts(deterministic, single source of truth) вместо manual cleanup вrun-pipeline/SKILL.mdTemplate D. Soft-fail pattern корректный, 2 теста покрывают presence/absence, ADR с обоснованием.Positives
cleanupPrBranch(merge-pr.ts:20-28) — 8 строк, single responsibility, guard черезgit branch --list→ delete → soft fail. Чистая реализация.⚠️ failed to delete local pr-N branch: <stderr>НЕ блокирует merge (merge уже прошёл). Правильный best-effort подход.prCleanupcomputation → cleanup пропущен целиком. Соответствует ADR invariant._ts_loader.mjs:394-401) —target.startsWith("pr-")→ отдельная ветка сGIT_PR_BRANCH_LIST_STUB, не ломает существующийGIT_BRANCH_LIST_STUBдля headRef. Существующие 15 тестов без регрессии.test_merge_pr_cleans_pr_branch(ветка есть → delete вызывается) иtest_merge_pr_no_pr_branch(ветки нет → delete НЕ вызывается, guard срабатывает). Покрывают оба пути.Что сделано,Почему,Watch out,Pending) заполнены осмысленно,Watch outописывает edge cases (parallel work,pr-39-reviewне матчится, repo-mismatch).Cross-file impact
merge-pr.ts(writer) ↔run-pipeline/SKILL.mdTemplate F (reader, вызываетmerge-pr) — change additive (suffix appended to return message), contract не сломан. Paired update не нужен.pipeline-status.pyпарсит### Verdict:в PR comments, не return merge-pr — не затронут.Suggestions (info, not blocking)
docs/decisions/098-pr-53-...md— нет newline at EOF (\ No newline at end of file). Cosmetic, non-blocking.Verdict: APPROVE