Skip to content

fix(github): use the GraphQL endpoint on GitHub Enterprise Server - #4272

Merged
IsmaelMartinez merged 1 commit into
The-PR-Agent:mainfrom
MaxFreedomPollard:fix/github-enterprise-graphql-endpoint
Oct 23, 2026
Merged

IsmaelMartinez merged 1 commit into
The-PR-Agent:mainfrom
MaxFreedomPollard:fix/github-enterprise-graphql-endpoint

Conversation

@MaxFreedomPollard

@MaxFreedomPollard MaxFreedomPollard commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

User description

What

pr_agent/git_providers/github_provider.py: the two raw GraphQL calls, the resolveReviewThread mutation in resolve_comment_thread() and the sub-issues query in fetch_sub_issues(), now go through a small _post_graphql() helper. It POSTs to the requester's graphql_url instead of the relative path "/graphql". On github.com the request is unchanged.

tests/unittest/test_github_graphql_endpoint.py: 4 new tests (2 functions, each for github.com and Enterprise Server). They drive a real PyGithub client over a stubbed requests.Session that serves GraphQL only at the documented endpoint, and assert the paths sent and the result. The fake requesters in three existing test files gained the graphql_url attribute that PyGithub's Requester has.

Why

PyGithub resolves a relative URL under the REST prefix of base_url. With the documented Enterprise Server setting GITHUB__BASE_URL=https://github.mycompany.com/api/v3 (docs/docs/installation/github.md), requestJson("POST", "/graphql") goes to /api/v3/graphql. GHES serves GraphQL at /api/graphql. That is the URL PyGithub's graphql_url derives from base_url (PyGithub/PyGithub#2880), and _review_thread_nodes() already reaches it through graphql_query().

So on GHES, within one resolve_comment_thread() call, the thread lookup reaches /api/graphql but the mutation goes to /api/v3/graphql. Reproduced on main with a real Github(base_url="https://github.mycompany.com/api/v3") client (PyGithub 2.10.0, the locked version), over a stub that serves GraphQL only at /api/graphql:

fetch_sub_issues       -> set()   sent: [('POST', '/api/v3/graphql')]
resolve_comment_thread -> False   sent: [('GET', '/api/v3/repos/owner/repo/pulls/comments/123'),
                                         ('POST', '/api/graphql'), ('POST', '/api/v3/graphql')]

The only log output is Issue ID not found for ... and Resolve mutation returned isResolved=false for thread PRRT_1 — possible permission issue. For GHES users this means:

  • /ask_line with pr_questions.resolve_threads = true never resolves a thread, and the warning points at permissions.
  • Ticket analysis (pr_reviewer.require_ticket_analysis_review, on by default) never adds the sub-issues of a linked issue.

With this branch the same script returns the sub-issue and True, and every GraphQL request goes to /api/graphql.

The calls keep requestJson rather than switching to graphql_query(). graphql_query() raises on any errors entry, and fetch_sub_issues() handles the NOT_FOUND payload for PR-number links without a traceback on purpose (TestFetchSubIssuesNullGraphQLFields).

Testing

  • PYTHONPATH=. uv run pytest tests/unittest/test_github_graphql_endpoint.py -q: 4 passed. With only the github_provider.py change reverted: 2 failed (both Enterprise Server cases), 2 passed (github.com).
  • PYTHONPATH=. uv run pytest tests/unittest/test_github_provider_comments.py tests/unittest/test_ticket_extraction_async.py tests/unittest/test_github_provider_exception_narrowing.py -q: 241 passed, both on this branch and with the fix reverted, so the fake changes do not alter what those tests check.
  • PYTHONPATH=. uv run pytest tests/unittest -q: 14134 passed, 33 skipped. The other 46 failures and 1 error come from my offline sandbox, mostly tiktoken failing to download its encoding. Unmodified main fails the same 47 tests there, and none of them is a GitHub provider test.
  • uv run ruff check on the five changed files: All checks passed. The pre-commit-hooks v6.0.0 checks from .pre-commit-config.yaml also pass on them.

All HTTP is stubbed; this was not run against a live GHES instance.

🤖 Generated with Claude Code


PR Type

Bug fix, Tests


Description

  • Route GraphQL requests through PyGithub's derived endpoint.

  • Fix Enterprise thread resolution and sub-issue retrieval.

  • Test endpoint routing across GitHub deployment types.

  • Update existing requester mocks for endpoint compatibility.


Diagram Walkthrough

flowchart LR
  A["Thread resolution and sub-issue retrieval"]
  B["_post_graphql helper"]
  C["PyGithub requester.graphql_url"]
  D["GitHub.com /graphql"]
  E["Enterprise Server /api/graphql"]
  A --> B
  B --> C
  C --> D
  C --> E
Loading

File Walkthrough

Relevant files
Bug fix
github_provider.py
Route GraphQL calls through the derived endpoint                 

pr_agent/git_providers/github_provider.py

  • Add _post_graphql() to send documents to the requester's derived
    graphql_url.
  • Route thread-resolution mutations and sub-issue queries through the
    helper.
  • Avoid incorrectly appending /graphql to Enterprise Server's REST
    prefix.
+12/-5   
Tests
test_github_graphql_endpoint.py
Verify GraphQL routing across GitHub deployment types       

tests/unittest/test_github_graphql_endpoint.py

  • Add four parameterized cases covering GitHub.com and Enterprise
    Server.
  • Exercise real PyGithub clients over a stubbed requests.Session.
  • Assert request paths and successful results for sub-issue retrieval
    and thread resolution.
+96/-0   
test_github_provider_comments.py
Align comment requester mock with PyGithub endpoints         

tests/unittest/test_github_provider_comments.py

  • Add graphql_url to the fake requester.
  • Use that endpoint in the fake requester's graphql_query()
    implementation.
+3/-1     
test_github_provider_exception_narrowing.py
Update malformed GraphQL payload requester fixture             

tests/unittest/test_github_provider_exception_narrowing.py

  • Supply graphql_url in the malformed-payload test requester.
  • Preserve coverage of empty-set fallback for invalid GraphQL responses.
+2/-1     
test_ticket_extraction_async.py
Add GraphQL endpoint to ticket requester mock                       

tests/unittest/test_ticket_extraction_async.py

  • Add graphql_url to the fake requester used for sub-issue null-value
    scenarios.
+2/-0     


⚙️ Agent run details
  • Model: openai/gpt-6.1-sol
  • Tokens: 7,131 in / 557 out / 7,688 total
  • Time cost: 9.9s
  • AI calls: 1

resolve_comment_thread() and fetch_sub_issues() posted their GraphQL
documents to the relative path "/graphql". PyGithub resolves a relative
path under the REST prefix of base_url, so with an Enterprise Server
base URL such as https://github.mycompany.com/api/v3 both requests went
to /api/v3/graphql rather than /api/graphql. The thread lookup in the
same resolve call already reaches /api/graphql through graphql_query().

On GHES, /ask_line thread resolution therefore failed with a "possible
permission issue" warning, and ticket analysis never added the
sub-issues of a linked issue.

Send both requests to the requester's graphql_url, the endpoint PyGithub
derives from base_url, through a small _post_graphql() helper. The
request path on github.com is unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@the-pr-agent-bot

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ No major issues detected

⚙️ Agent run details
  • Model: openai/gpt-6.1-sol
  • Tokens: 8,205 in / 45 out / 8,250 total
  • Time cost: 5.0s
  • AI calls: 1

@IsmaelMartinez IsmaelMartinez left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for tracking the Enterprise Server failures down to the relative "/graphql" path and covering both github.com and GHES with tests that drive a real client; this is good to merge.

@IsmaelMartinez
IsmaelMartinez merged commit f5ffd0e into The-PR-Agent:main Oct 23, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants