opencode-config/docs/handoff/pr-53-git-insteadof.md
Sergey 02f0863a24
fix(memory): persist git insteadOf helper for GITHUB_TOKEN in setup-memory.sh (#53)
* fix(memory): add git insteadOf helper for GITHUB_TOKEN in setup-memory.sh

* test(memory): add tests for git insteadOf helper

* docs(handoff): add handoff + ADR-022 for git insteadOf helper

* docs(handoff): set PR number 53 in handoff + ADR-022

* style: ruff format test_setup_memory.py

---------

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

31 lines
No EOL
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
pr: 53
title: persist git insteadOf helper for GITHUB_TOKEN in setup-memory.sh
---
# PR 53: persist git insteadOf helper for GITHUB_TOKEN in setup-memory.sh
## Что сделано
- `.opencode/scripts/setup-memory.sh:29-33` — перед `git clone` добавлен guarded блок `git config --global url."https://x-access-token:${GITHUB_TOKEN}@github.com/".insteadOf https://github.com/`. Срабатывает только если `GITHUB_TOKEN` непустой (`if [ -n "${GITHUB_TOKEN:-}" ]`), иначе пропускается без ошибки. Расположен ВНУТРИ ветки clone (`if [ ! -d "$MEMORY_DIR/.git" ]`), т.к. insteadOf нужен только при первом клонировании remote — pull на существующем репо уже авторизован через `origin` URL.
- `tests/test_setup_memory.py` — 4 новых теста:
- `test_script_contains_git_insteadof` — grep check: скрипт содержит `git config --global url.` + `.insteadOf https://github.com/`, и блок стоит ДО `git clone --origin` (позиционная проверка `insteadof_pos < clone_pos`).
- `test_script_contains_github_token_check` — grep check: скрипт содержит `GITHUB_TOKEN` и это guarded check (`-n "${GITHUB_TOKEN:-}"`), а не hard-fail.
- `test_insteadof_idempotent` — функциональный тест: запускает скрипт 2x с fake `GITHUB_TOKEN` против mock remote (isolated `HOME`), проверяет что `~/.gitconfig` содержит ровно 1 `insteadOf` entry (не дублируется). `git config --global` перезаписывает значение, idempotent by git semantics.
- `test_no_github_token_skips_insteadof` — когда `GITHUB_TOKEN` unset, `~/.gitconfig` либо не создаётся, либо не содержит `insteadOf` (skip без ошибки).
- ADR-022 + этот handoff.
## Почему
При миграции opencode-config на linux-1 `setup-memory.sh` падал с `could not read Username for 'https://github.com'` при клонировании memory repo — git не подставляет `GITHUB_TOKEN` автоматически для HTTPS, и в non-interactive контексте (container, нет tty) prompts блокируют clone. Временный fix (`git config --global url.insteadOf`) применялся вручную, но `~/.gitconfig` живёт в overlay container filesystem и теряется при `docker compose restart` — после рестарта memory-clone снова падал.
Решение: встроить insteadOf helper в сам `setup-memory.sh` (детерминированный flow, вызывается через memory-setup tool при старте opencode). Скрипт idempotent — `git config --global` перезаписывает значение, не дублирует. Guarded check на `GITHUB_TOKEN` — если token отсутствует (локальная dev-среда), скрипт не падает, клон идёт как обычно (для mock/file remotes).
Альтернатива (Dockerfile ENTRYPOINT / `.bashrc` hack) отклонена — `setup-memory.sh` вызывается детерминированно через tool, а `.bashrc` требует interactive shell (non-interactive container его не читает).
## Pending
— (нет)
## Watch out
- **insteadOf внутри clone-ветки** — helper стоит внутри `if [ ! -d "$MEMORY_DIR/.git" ]`, т.е. срабатывает только при первом клонировании. На последующих запусках (pull path) вместо него не выполняется — это намеренно: `origin` URL уже сохранён в `.git/config` клона, pull идёт через него. Если remote URL не содержит token (HTTPS без auth), pull упадёт — но это уже проблема конфигурации remote, а не скрипта. Для fresh clone вместоOf переписывает `https://github.com/` на `https://x-access-token:TOKEN@github.com/` в момент clone.
- **Isolated HOME в тестах** — `test_insteadof_idempotent` и `test_no_github_token_skips_insteadof` используют `HOME=$tmp_path/home`, чтобы `git config --global` не писал в реальный `~/.gitconfig` CI-раннера. Без этого тест загрязнил бы глобальный gitconfig.
- **ADR number = 022** (sequential, следующий после 021), НЕ PR number.
- Существующие 358 тестов не сломаны — полный suite: 362 passed (358 + 4 новых).