* fix(ship): fall back to gh auth token (parity with parsec doctor) (#281)
parsec ship 이 PARSEC_GITHUB_TOKEN / GITHUB_TOKEN / GH_TOKEN env var 모두 비어있을 때
PR 생성을 거부했지만 parsec doctor 와 tracker 레이어는 이미 `gh auth token` fallback
적용. parity 깨져 사용자가 수동 `gh pr create` 로 추가 작업 필요.
해결:
- src/env.rs: github_token() 의 4번째 우선순위로 gh_auth_token() 추가. 신규
gh_auth_token() helper 는 `gh auth token` shell out — 실패 시 None (binary 없음 /
exit code != 0 / non-UTF8 / 빈 출력 모두 graceful).
- src/github/mod.rs: resolve_github_token 의 env-var/gh fallback 을 GitHub host
(github.com / *.ghe.com / *.github.* GHE) 에만 적용. 신규 is_github_host() helper.
Bitbucket / GitLab remote 가 `gh auth login` 한 환경에서 GitHub 토큰을 잘못 픽업하지
않도록 가드.
- src/cli/commands/doctor.rs: 중복 `gh auth token` shell-out 코드 제거 → env::gh_auth_token()
공통 helper 호출. parity at the helper level.
신규 테스트 (src/env.rs): github_token_priority_order — PARSEC > GITHUB > GH 우선순위
+ 빈값 fallback 4 시나리오 sequential 검사. EnvGuard 로 process-wide env 보존+복원.
gh_auth_token_returns_option_string_or_none — gh binary 가용성에 무관하게 trim 보장.
github_token_returns_none_when_all_missing_and_gh_fails — env 모두 미설정 시 None
또는 valid Some 모두 허용 (CI 와 dev 환경 양립).
검증:
- cargo test: 79 tests PASS (env tests 6 + integration 73)
- cargo clippy --all-targets -- -D warnings: clean
- cargo fmt --check: clean
- bitbucket integration tests: 5/5 PASS (이전 발견된 host-gated 이슈 해결)
회귀 위험: 매우 낮음
- 환경에 gh CLI 미로그인 / 미설치 → 기존과 동일 (None 반환)
- 환경에 gh 로그인됨 + GitHub remote → 신규 fallback 활용 (issue #281 의도)
- 환경에 gh 로그인됨 + Bitbucket/GitLab remote → is_github_host 로 차단, 기존과 동일
Closes #281
* docs(v0.5): open roadmap milestone — visualization release vision
v0.5 마일스톤 공식 출발 마커. README 와 CHANGELOG 양쪽에 향후 비전 명시.
README.md (## Roadmap 섹션 신설, ## Why use it 과 ## Install 사이):
- vision tagline: "parsec = AI agents + human devs both — worktree-native git CLI"
- 4단계 milestone:
· v0.4.0 ✅ Released (2026-05-04): Multi-forge + multi-tracker foundation
· v0.5 🚧 Next — _The visualization release_:
smartlog · TUI dashboard · speculative merge · parsec test · AI PR descriptions
· v1.0 🔜 — _AI-Native Standard_:
MCP server signature, Claude/Cursor/Copilot 가 parsec 을 first-class tool 로 invoke
· v2.0+ 🔮 — _Ecosystem Hub_: plugins · VS Code extension · Linear tracker
- v0.5 milestone link (github.com/erishforG/git-parsec/milestone/3)
CHANGELOG.md (## [Unreleased] 확장):
- ### Added: v0.5 milestone opened, README Roadmap 참조
- ### Fixed: #281 ship gh auth token fallback 노트 (별 commit ae1a2d3 와 동일 entry)
회귀 위험: 0 (문서 변경만)
* fix(env): serialize env-touching tests via process-wide mutex (Windows CI)
PR #289 Windows CI 1건 fail. macOS / Ubuntu Test 통과, Windows Test 만 실패.
원인:
- env::tests 의 github_token_priority_order 와 github_token_returns_none_when_all_
missing_and_gh_fails 가 cargo test 병렬 실행 시 process-wide env vars 를 race.
- priority_order 가 PARSEC=p / GITHUB=g / GH=h 셋업 후 assert 사이에 sibling 테스트의
EnvGuard::new() 가 모든 env 를 clear → assert 가 PARSEC 못 보고 GH=h 반환.
- macOS/Ubuntu 는 timing 우연히 안전, Windows 는 다른 thread scheduling 으로 race
발현 (Some("h") vs Some("p") at src/env.rs:205).
수정:
- std::sync::OnceLock<Mutex<()>> 의 env_lock() 신규 — env 만지는 테스트들 직렬화.
std 만 사용 (외부 deps 추가 X 제약 준수).
- github_token_priority_order 와 github_token_returns_none_when_all_missing_and_gh_fails
를 단일 함수 github_token_priority_order_and_fallback 로 통합 + env_lock() 의
Mutex guard 획득. 5 시나리오 (PARSEC 우선 / GITHUB / GH / 빈값 / 모두 미설정) 직렬 실행.
- gh_auth_token_returns_option_string_or_none 은 env 미터치라 lock 불필요 — 그대로 유지.
- production 로직 (env::github_token / env::gh_auth_token) 변경 0.
검증:
- 로컬 cargo test 78 PASS (env tests 5 + integration 73), clippy clean, fmt clean.
- Windows CI 검증은 force-push 후 PR #289 워크플로우에서 확인.