opencode-config/docs/handoff/pr-55-parse-remote-url.md
Sergey e413a6c132
fix(pipeline-status): parse_remote_url breaks with git insteadOf userinfo (#55)
* fix(pipeline-status): handle git insteadOf userinfo in parse_remote_url

* test(pipeline-status): add tests for URL with userinfo

* docs(handoff): set PR number 55 in handoff + ADR-023

---------

Co-authored-by: opencode-agent <agent@slaid098.dev>
2026-07-24 21:47:39 +03:00

4.7 KiB
Raw Permalink Blame History

pr title
55 fix parse_remote_url breaking with git insteadOf userinfo

PR 55: fix parse_remote_url breaking with git insteadOf userinfo

Что сделано

  • .opencode/scripts/pipeline-status.py:171 — в parse_remote_url HTTPS-regex изменён с r"https?://([^/]+)/([^/]+)/(.+?)(?:\.git)?$" на r"https?://(?:[^/@]*@)?([^/]+)/([^/]+)/(.+?)(?:\.git)?$". Опциональная non-capturing группа (?:[^/@]*@)? пропускает user:password@ userinfo перед host, не ломая plain-URL случай (группа опциональна).
  • .opencode/scripts/spec-status.py:129 — тот же regex fix (функция parse_remote_url дублирована в spec-status.py, используется в Phase 8 gh issue view --repo).
  • tests/test_pipeline_status.py — 4 новых теста:
    • test_parse_remote_url_https_with_userinfo — URL https://x-access-token:github_pat_TOKEN@github.com/slaid098/opencode-config.git("github.com", "slaid098", "opencode-config").
    • test_parse_remote_url_https_without_userinfo — plain URL работает (regression guard).
    • test_parse_remote_url_https_userinfo_no_git_suffix — userinfo + нет .git suffix.
    • test_get_memory_file_path_with_userinfoget_memory_file_path() строит repos/github.com/slaid098/opencode-config.md (без x-access-token/github_pat_TOKEN в пути).
  • tests/test_spec_status.py — 3 новых теста:
    • test_parse_remote_url_https_with_userinfo — same URL → correct tuple.
    • test_parse_remote_url_https_without_userinfo — regression guard.
    • test_get_repo_full_name_with_userinfoget_repo_full_name()slaid098/opencode-config (не x-access-token:...@github.com/...).
  • ADR-023 + этот handoff.

Почему

PR#53 (ADR-022) добавил git config --global url.insteadOf в setup-memory.sh для non-interactive HTTPS auth при клонировании memory repo в Docker. После этого git remote get-url origin возвращает rewritten URL с встроенным userinfo: https://x-access-token:TOKEN@github.com/slaid098/opencode-config.git. Старый regex [^/]+ жадно матчит x-access-token:TOKEN@github.com как host (символ @ не входит в исключения [^/]), поэтому:

  • get_memory_file_path() строил путь repos/x-access-token:TOKEN@github.com/slaid098/opencode-config.md (не существует) → check_memory в pipeline-status возвращал "memory file не существует" для ВСЕХ будущих PR.
  • get_repo_full_name() в spec-status случайно работал (возвращает org/repo, host отбрасывается), но фикс всё равно применён для консистентности и на случай future callers.

Это латентная регрессия — влияет на каждый pipeline_status вызов после PR#53, пока insteadOf активен. Тесты test_parse_remote_url_* покрывали только plain URLs, поэтому CI на PR#53 не поймал regression.

Fix выбрал минимальный — regex-only, без env coupling (вариант "использовать git config --get remote.origin.url вместо git remote get-url" ломается если кто-то задаст remote URL с token напрямую; вариант url.split('@')[-1] хрупкий при @ в path).

Pending

— (нет)

Watch out

  • (?:[^/@]*@)? опциональна — для plain https://github.com/... группа не матчится (нет @), host = github.com. Для https://user:token@github.com/... группа матчит user:token@ и отбрасывается (non-capturing), host = github.com. [^/@] внутри userinfo не матчит ни / ни @, поэтому корректно останавливается на первом @.
  • Дублирование parse_remote_url — функция идентична в pipeline-status.py и spec-status.py. Fix применён в обоих. Рефакторинг в shared module выходит за рамки этого PR (риск для ADR-010 cwd-aware logic).
  • ADR number = 023 (sequential, следующий после 022), НЕ PR number.
  • Существующие 362 теста не сломаны — полный suite: 369 passed (362 + 7 новых).
  • PR number в filename — issue #54 → PR #55. Handoff/ADR первично scaffold'нуты как pr-54-* (по issue number), после gh pr create переименованы в pr-55-* (по PR number, по конвенции репо).