fix(github): propagate GHES GraphQL endpoint#405
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 51a9eae806
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| auth = await deps.validateGitHubToken(ghToken, "gh", { | ||
| apiUrl: githubGraphqlEndpoint?.resolvedEndpoint, |
There was a problem hiding this comment.
Request gh tokens for the configured GHES host
When tracker.endpoint points at GHES and no GITHUB_GRAPHQL_TOKEN is set, this path now validates the token returned by deps.getGhToken({ allowEnv: false }) against the resolved GHES GraphQL endpoint. That token is still obtained via gh auth token without a hostname, and the GitHub CLI docs state that without --hostname the default host is chosen, so in a common multi-host setup (github.com plus github.example) doctor validates a github.com token against the enterprise endpoint and reports auth/project failures even though gh auth login --hostname github.example is valid. Derive the host from the resolved endpoint and pass it through to the gh status/scopes/token calls.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Resolved in b2bbdeb. doctor now derives the gh hostname from the resolved GraphQL endpoint and passes it into checkGhAuthenticated, checkGhScopes, and getGhToken, so a GHES endpoint such as https://github.example/api/graphql uses gh auth status --hostname github.example and gh auth token --hostname github.example.
There was a problem hiding this comment.
Addressed in 94ee775: doctor now derives the hostname from the resolved GraphQL endpoint and passes it to gh auth status, scope inspection, and gh auth token as --hostname <host> when falling back to gh CLI auth. The remediation text now also includes the same hostname.
hojinzs
left a comment
There was a problem hiding this comment.
✅ Approve — PR #405 (Fixes #388)
요구사항/수용조건 검증 (모두 충족)
원본 이슈 #388의 "Proposed fix" 3개 항목이 빠짐없이 반영됨:
- 워커 환경 전파 —
githubProjectTrackerAdapter.buildWorkerEnvironment가tracker.apiUrl을GITHUB_GRAPHQL_API_URL로 주입 (orchestrator-adapter.ts:43-50, trim 처리 + 빈 값 생략). E2E 체인 확인:service.ts:1598에서 워커 env로 spread →buildProjectExecutionEnv에서 explicitEnv가 process.env보다 우선 → 워커측tool-github-graphql/src/tool.ts:134가process.env.GITHUB_GRAPHQL_API_URL사용. 더 이상api.github.com으로 폴백하지 않음. ✔ - doctor 진단 —
github_graphql_endpoint체크 신설: resolved endpoint 출력 + tracker/env 불일치 시warn. 또한 auth 검증을 해석된 엔드포인트 대상(validateGitHubToken(..., { apiUrl }),createClient(..., { apiUrl }))으로 수행하도록 순서 재배치 — GHES 사용자의 "green doctor + runtime 실패" 문제 해소. ✔ - 문서화 — README에 GHES 단일 소스 설정 경로 추가(
tracker.endpoint, 우선순위, dispatch 주입 설명). ✔
Smoke / 품질 검사 (로컬 e2e)
pnpm --filter @gh-symphony/cli test→ 437 passed,tracker-github→ 56 passed (신규 TC 2건 포함: 엔드포인트 전파 / 불일치 warn).pnpm lint✅ ·pnpm typecheck✅ ·pnpm build✅- CI: Test ✅ · Container Smoke ✅ (copilot reviewer는 진행 중이나 비차단).
- precedence 검증: tracker.apiUrl이 inherited env보다 우선 → doctor의 "tracker authoritative" 경고 의미와 일치.
의견
구현이 깔끔하고 테스트가 충분하며 스펙(Integration 레이어) 경계를 잘 지킴. 인라인으로 남긴 엔드포인트 정규화(trailing slash/host case) 건은 머지 차단이 아닌 후속 개선 권장 사항입니다. Approve.
Generated by Claude Code
| mismatch: | ||
| trackerApiUrl !== null && | ||
| envApiUrl !== null && | ||
| trackerApiUrl !== envApiUrl, |
There was a problem hiding this comment.
Nit (non-blocking): the mismatch check is a raw string compare after trim(), so cosmetically-equivalent endpoints will raise a false warn — e.g. https://github.example/api/graphql vs https://github.example/api/graphql/ (trailing slash), or a host-case difference. Since the same resolvedEndpoint is what feeds validateGitHubToken/createClient, the two values would still hit the same host while doctor reports them as disagreeing. Consider normalizing (strip trailing slash, lowercase host) before the comparison. Not required for merge — the common copy/paste case is already covered.
Generated by Claude Code
There was a problem hiding this comment.
Resolved in b2bbdeb. doctor now normalizes GraphQL endpoints before comparison: it trims, lowercases the host, strips trailing slashes, and removes query/hash components before deciding whether tracker.apiUrl and GITHUB_GRAPHQL_API_URL disagree.
There was a problem hiding this comment.
Addressed in 94ee775: doctor now normalizes the tracker/env GraphQL endpoints before display and mismatch comparison by lowercasing the host, stripping trailing slashes, and dropping query/fragment noise. Added focused coverage for equivalent https://GitHub.Example/api/graphql/ vs https://github.example/api/graphql spellings.
There was a problem hiding this comment.
Pull request overview
This PR improves GitHub Enterprise Server (GHES) support by ensuring a configured GitHub GraphQL endpoint flows consistently from WORKFLOW.md into the orchestrator, CLI diagnostics (doctor), and dispatched workers—addressing the Integration/Configuration boundary called out in #388.
Changes:
- Propagates
tracker.apiUrl(fromWORKFLOW.mdtracker.endpoint) into worker env asGITHUB_GRAPHQL_API_URLfor GitHub workers. - Enhances
gh-symphony doctorto resolve/report the effective GitHub GraphQL endpoint and warn on config/env mismatches, and to validate auth against the resolved endpoint. - Documents the intended “single source of truth” GHES setup path and adds a CLI changeset.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents GHES endpoint configuration via WORKFLOW.md and how doctor/workers consume it. |
| packages/tracker-github/src/tracker-github.test.ts | Adds coverage ensuring the GitHub worker env includes GITHUB_GRAPHQL_API_URL when configured. |
| packages/tracker-github/src/orchestrator-adapter.ts | Injects GITHUB_GRAPHQL_API_URL into worker environment based on project.tracker.apiUrl. |
| packages/cli/src/github/gh-auth.ts | Allows passing an apiUrl into token validation so doctor can validate against GHES. |
| packages/cli/src/github/client.ts | Exposes the default GraphQL endpoint constant and threads apiUrl through client creation. |
| packages/cli/src/commands/doctor.ts | Adds endpoint resolution/diagnostics and uses the resolved endpoint for auth and GitHub checks. |
| packages/cli/src/commands/doctor.test.ts | Adds tests for endpoint-based auth validation and mismatch warning behavior. |
| .changeset/github-ghes-graphql.md | Publishes a patch release note for the CLI behavior change. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const trackerApiUrl = input.trackerApiUrl?.trim() || null; | ||
| const envApiUrl = input.envApiUrl?.trim() || null; | ||
|
|
||
| return { | ||
| resolvedEndpoint: | ||
| trackerApiUrl ?? envApiUrl ?? DEFAULT_GITHUB_GRAPHQL_API_URL, | ||
| source: trackerApiUrl ? "tracker" : envApiUrl ? "env" : "default", | ||
| trackerApiUrl, | ||
| envApiUrl, | ||
| mismatch: | ||
| trackerApiUrl !== null && | ||
| envApiUrl !== null && | ||
| trackerApiUrl !== envApiUrl, | ||
| }; |
There was a problem hiding this comment.
Resolved in b2bbdeb. The endpoint resolver now normalizes equivalent spellings before comparison and before surfacing the resolved endpoint. Added coverage for https://GitHub.Example/api/graphql/ matching https://github.example/api/graphql without a warning.
There was a problem hiding this comment.
Addressed in 94ee775: endpoint mismatch comparison is now based on normalized endpoint spellings, so equivalent trailing-slash and host-case variants no longer warn. The resolved endpoint surfaced by doctor uses the normalized spelling.
| const client = deps.createClient(auth.token, { | ||
| apiUrl: githubGraphqlEndpoint?.resolvedEndpoint, | ||
| }); |
There was a problem hiding this comment.
Resolved in b2bbdeb. The CLI GitHub client now derives REST base URLs through deriveGitHubRestApiUrl, mapping GHES https://<host>/api/graphql to https://<host>/api/v3 for token validation, repository metadata, and label lookups. Added focused client coverage for that mapping.
There was a problem hiding this comment.
Addressed in 94ee775: the CLI GitHub client now derives REST base URLs from GraphQL endpoints explicitly. Public GitHub still maps to https://api.github.com, while GHES https://<host>/api/graphql maps to https://<host>/api/v3 for token validation, repo lookups, labels, and project detail REST calls. Added client.test.ts coverage for the GHES /api/graphql to /api/v3 mapping.
…into feat/388-ghes-graphql-endpoint # Conflicts: # packages/cli/src/commands/doctor.ts # packages/cli/src/github/client.test.ts # packages/cli/src/github/client.ts # packages/cli/src/github/gh-auth.ts
TL;DR
Propagates configured GHES GraphQL endpoints into dispatched GitHub workers, adds
doctorendpoint diagnostics, and tightens GHES doctor auth so it uses the configured enterprise host consistently.변경 지점 다이어그램
WORKFLOW.md tracker.endpoint/tracker.apiUrl→ GitHub tracker adapter → worker envGITHUB_GRAPHQL_API_URL→ worker-sidegithub_graphqltooldoctor→ resolved workflow tracker endpoint + env endpoint → normalized endpoint summary/mismatch warning → GHES-awaregh auth --hostname+ REST/api/v3validation여기부터 보세요
packages/tracker-github/src/orchestrator-adapter.tspackages/cli/src/commands/doctor.tspackages/cli/src/github/client.tspackages/cli/src/github/gh-auth.tsREADME.md위험 & 롤백
doctorvalidates against when workflow configuration is present.변경 파일
packages/tracker-github/src/orchestrator-adapter.tspackages/tracker-github/src/tracker-github.test.tspackages/cli/src/commands/doctor.tspackages/cli/src/commands/doctor.test.tspackages/cli/src/github/client.tspackages/cli/src/github/client.test.tspackages/cli/src/github/gh-auth.tspackages/cli/src/github/gh-auth.test.tsREADME.md.changeset/github-ghes-graphql.mdEvidence
pnpm exec vitest run packages/cli/src/commands/doctor.test.ts packages/cli/src/github/client.test.ts packages/cli/src/github/gh-auth.test.ts— pass.pnpm lint && pnpm test && pnpm typecheck && pnpm build— pass.AGENT_TEST.md— pass:docker compose -f docker-compose.e2e.yml -f docker-compose.e2e.events.yml up -d --build;/healthzreturned{"ok":true}; injectede2e/fixtures/happy-path.json; observed worker running, implementation completion, continuation retry, fixture cleanup; final statehealth=idle,activeRuns=0,retryQueue=[],lastError=null.docs/symphony-spec.mdtracker integration/configuration boundaries; no upstream spec divergence identified.Issues — Closed #388
Fixes #388
머지 후/사람 확인