Skip to content

fix(github): propagate GHES GraphQL endpoint#405

Merged
moncher-dev merged 5 commits into
mainfrom
feat/388-ghes-graphql-endpoint
Jun 22, 2026
Merged

fix(github): propagate GHES GraphQL endpoint#405
moncher-dev merged 5 commits into
mainfrom
feat/388-ghes-graphql-endpoint

Conversation

@moncher-dev

@moncher-dev moncher-dev commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

TL;DR

Propagates configured GHES GraphQL endpoints into dispatched GitHub workers, adds doctor endpoint diagnostics, and tightens GHES doctor auth so it uses the configured enterprise host consistently.

변경 지점 다이어그램

WORKFLOW.md tracker.endpoint/tracker.apiUrl → GitHub tracker adapter → worker env GITHUB_GRAPHQL_API_URL → worker-side github_graphql tool

doctor → resolved workflow tracker endpoint + env endpoint → normalized endpoint summary/mismatch warning → GHES-aware gh auth --hostname + REST /api/v3 validation

여기부터 보세요

  • packages/tracker-github/src/orchestrator-adapter.ts
  • packages/cli/src/commands/doctor.ts
  • packages/cli/src/github/client.ts
  • packages/cli/src/github/gh-auth.ts
  • README.md

위험 & 롤백

  • Risk: GHES endpoint normalization changes which GraphQL/REST host doctor validates against when workflow configuration is present.
  • Rollback: revert this PR to restore previous GitHub.com-default behavior.

변경 파일

  • packages/tracker-github/src/orchestrator-adapter.ts
  • packages/tracker-github/src/tracker-github.test.ts
  • packages/cli/src/commands/doctor.ts
  • packages/cli/src/commands/doctor.test.ts
  • packages/cli/src/github/client.ts
  • packages/cli/src/github/client.test.ts
  • packages/cli/src/github/gh-auth.ts
  • packages/cli/src/github/gh-auth.test.ts
  • README.md
  • .changeset/github-ghes-graphql.md

Evidence

  • 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.
  • Docker E2E blackbox TC from AGENT_TEST.md — pass: docker compose -f docker-compose.e2e.yml -f docker-compose.e2e.events.yml up -d --build; /healthz returned {"ok":true}; injected e2e/fixtures/happy-path.json; observed worker running, implementation completion, continuation retry, fixture cleanup; final state health=idle, activeRuns=0, retryQueue=[], lastError=null.
  • Spec conformance check — aligns with docs/symphony-spec.md tracker integration/configuration boundaries; no upstream spec divergence identified.

Issues — Closed #388

Fixes #388

머지 후/사람 확인

  • Confirm a real GHES project workflow reports and uses the expected GraphQL endpoint.

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 39.14% 28483 / 72762
🔵 Statements 39.14% 28483 / 72762
🔵 Functions 71.75% 1392 / 1940
🔵 Branches 76.4% 5826 / 7625
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/cli/src/commands/doctor.ts 78.37% 73.55% 97.95% 78.37% 294-296, 303-309, 384-385, 395-396, 491-498, 509-510, 559-561, 600-601, 614-615, 619-629, 675-676, 703-706, 756, 777, 797-807, 810-820, 847-859, 873-886, 902-906, 913-914, 921-922, 939, 949, 980-983, 994-1000, 1009-1010, 1056, 1072-1092, 1139-1148, 1200-1202, 1235, 1301, 1306, 1354-1364, 1367-1377, 1380-1390, 1424-1436, 1439-1447, 1466-1476, 1479-1489, 1537-1549, 1556-1564, 1780, 1808, 1825, 1841-1849, 1871-1879, 1914, 1919, 1955-1956, 1975-1994, 2197-2198, 2204-2205, 2246-2255, 2276-2285, 2297, 2301-2309, 2312-2321, 2328-2337, 2349-2364, 2387-2397, 2400-2410, 2440-2456, 2459-2471, 2497, 2499-2500, 2502-2521, 2549, 2553, 2587, 2590, 2599-2610, 2612-2624, 2637, 2656, 2667, 2673-2690, 2707-2710, 2721-2722, 2751-2752
packages/cli/src/github/client.ts 46.44% 60.56% 76.47% 46.44% 120-133, 160-165, 173-275, 297-334, 352-360, 370-375, 419-420, 422-425, 438-439, 454-456, 460-461, 472-473, 520-522, 526-527, 542-546, 564-662, 681-686, 694-729, 732-733
packages/cli/src/github/gh-auth.ts 85.77% 72.58% 95.65% 85.77% 77-81, 123, 153-155, 164-165, 172, 181, 191, 197-201, 228-229, 284-285, 308-309, 328, 348-349, 353-358, 400-409, 438-439, 447-451, 504-506, 542-548, 574-575
packages/tracker-github/src/orchestrator-adapter.ts 92.8% 77.19% 100% 92.8% 21-22, 37-38, 95-96, 146-149, 210-211, 239-242, 300-301
Generated in workflow #288 for commit 94ee775 by the Vitest Coverage Report Action

@moncher-dev moncher-dev marked this pull request as ready for review June 22, 2026 16:18
@hojinzs hojinzs requested a review from Copilot June 22, 2026 16:18

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +1778 to +1779
auth = await deps.validateGitHubToken(ghToken, "gh", {
apiUrl: githubGraphqlEndpoint?.resolvedEndpoint,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 hojinzs left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Approve — PR #405 (Fixes #388)

요구사항/수용조건 검증 (모두 충족)

원본 이슈 #388의 "Proposed fix" 3개 항목이 빠짐없이 반영됨:

  1. 워커 환경 전파githubProjectTrackerAdapter.buildWorkerEnvironmenttracker.apiUrlGITHUB_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:134process.env.GITHUB_GRAPHQL_API_URL 사용. 더 이상 api.github.com으로 폴백하지 않음. ✔
  2. doctor 진단github_graphql_endpoint 체크 신설: resolved endpoint 출력 + tracker/env 불일치 시 warn. 또한 auth 검증을 해석된 엔드포인트 대상(validateGitHubToken(..., { apiUrl }), createClient(..., { apiUrl }))으로 수행하도록 순서 재배치 — GHES 사용자의 "green doctor + runtime 실패" 문제 해소. ✔
  3. 문서화 — README에 GHES 단일 소스 설정 경로 추가(tracker.endpoint, 우선순위, dispatch 주입 설명). ✔

Smoke / 품질 검사 (로컬 e2e)

  • pnpm --filter @gh-symphony/cli test437 passed, tracker-github56 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,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 (from WORKFLOW.md tracker.endpoint) into worker env as GITHUB_GRAPHQL_API_URL for GitHub workers.
  • Enhances gh-symphony doctor to 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.

Comment thread packages/cli/src/commands/doctor.ts Outdated
Comment on lines +380 to +393
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,
};

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +1918 to +1920
const client = deps.createClient(auth.token, {
apiUrl: githubGraphqlEndpoint?.resolvedEndpoint,
});

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Steve Lee added 3 commits June 23, 2026 02:05
…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
@moncher-dev moncher-dev merged commit 0c1b0b8 into main Jun 22, 2026
2 checks passed
@moncher-dev moncher-dev deleted the feat/388-ghes-graphql-endpoint branch June 22, 2026 23:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GitHub tracker does not propagate the GHES endpoint to the worker (github_graphql falls back to api.github.com)

3 participants