fix(tools): pass head field in create-pr for Forgejo POST /pulls #18
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/create-pr/head-field"
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?
Что сделано
Исправлен баг #9:
create-prtool не передавалheadfield в Forgejo POST /pulls → HTTP 422[Head]: Required..opencode/tools/create-pr.ts: добавлено автоопределение текущей git-ветки черезgit -C <cwd> rev-parse --abbrev-ref HEADи передача--head <branch>вrunGh(). Detached HEAD → понятная ошибка, без обращения к API..opencode/tools/_shared.ts: вcallForgejoGhдляpr createполеheadтеперь required — если--headотсутствует в argv, возвращается явная ошибка валидации (НЕ тихо опускается из POST body).baseостаётся опциональным (Forgejo default).tests/_ts_loader.mjs: добавлен stub-перехват дляgit rev-parse --abbrev-ref HEAD(возвращаетfeature/test-branchпо умолчанию, переопределяется черезGIT_HEAD_STUBenv var для тестов detached HEAD / git failure).tests/test_create_pr_tool.py: 4 новых теста — head field в POST body, explicit override, detached HEAD error, git failure error. Обновлены 2 существующих теста (теперь 2 git-вызова: rev-parse + remote lookup).tests/test_create_pr_tool.ts: обновлён список зеркалируемых тест-кейсов.Почему
Forgejo POST /pulls требует поле
head(название ветки источника) — без него возвращает HTTP 422.ghCLI автоопределяет head из текущей ветки, но dispatch-путь в_shared.tsпарсит--headиз argv, аcreate-pr.tsего не передавал →headundefined → опускался из POST body (...(head ? {head} : {})) → Forgejo 422. Workaround (raw curl с ручнымheadfield) использовался для PR #12, #13, #14, #15, #17 — теперь tool работает нативно.Watch out
create-prтеперь делает 2 git-вызова вместо 1 (rev-parse для head + config remote для repo при опущенномrepo). С explicitrepo— только 1 (rev-parse для head)._shared.tsтеперь fail-loud на отсутствующий--head: если другой tool вызоветrunGh(["pr","create",...])без--head, получит явную ошибку вместо тихого 422 от Forgejo.baseостаётся опциональным — Forgejo использует default_branch репо (обычноmain).check-permissions.py:114(no-any-return) не затронут — на main, вне scope.Pending
memory-syncerобновит memory-файлopencode-config-004.mdпосле merge (запись о PR#18 + закрытие бага #9).Closes #9
Code Review Summary
Исправление бага #9 корректное:
create-prтеперь автоопределяет текущую ветку черезgit rev-parse --abbrev-ref HEADи передаёт--headв Forgejo dispatch path, а_shared.tsfail-loud требуетheadдляpr create(вместо тихого пропуска → HTTP 422). 4 новых теста + 2 обновлённых, все 18 pass; 72 теста в других tool-тестах (commit, create-issue, post-review, merge-pr, create-readme, draw-image) тоже pass — stub в_ts_loader.mjsне ломает shared loader.Positives
_shared.ts:190-198):headrequired дляpr create— явная ошибка вместо malformed POST. Правильный подход (better than silent 422).create-pr.ts:66):branchRes.status !== 0 || !head || head === "HEAD"— покрывает все 3 случая (git error, empty output, detached). Ошибка до API-вызова, без сетевого round-trip.spawnSyncс array args (create-pr.ts:62): args передаются как массив, не shell-строка → нет injection risk для branch names с пробелами/спецсимволами._ts_loader.mjs:345): условиеargs.includes("rev-parse") && args.includes("--abbrev-ref")— перехватывает только--abbrev-ref, не ломает--show-toplevel(используется в pipeline-status/spec-status, но те тесты stubsubprocess.runнапрямую, не через loader).create-pr.tsпередаёт--head) и reader (_shared.tsпарсит--head) обновлены в одном PR — окно сломанного main закрыто.-Cдля обоих git-вызовов. Docstrings объясняют "почему" (issue #9, Forgejo 422), не "что".baseостаётся опциональным (_shared.ts:202):...(base ? { base } : {})— Forgejo default_branch используется, если--baseне передан.Suggestions (info, not blocking)
test_head_explicit_override— имя предполагает, что override существует, но docstring и assertions подтверждают обратное ("no user-facing head override — the tool is self-contained"). Тест проверяет, что auto-detected branch отправляется. Имя вводит в заблуждение; лучшеtest_head_auto_detected_no_overrideилиtest_head_always_auto_detected.test_detached_head_errorиtest_git_failure_no_headдублируют boilerplatesubprocess.run(...)вместо_run_exec, т.к. нужно переопределитьGIT_HEAD_STUBenv var. Можно расширить_run_execопциональнымenvпараметром (_run_exec(args, responses, env=None)→ merge вos.environ). Не критично — 2 теста, ~15 строк дубликата.Verdict: APPROVE