From 5e2b2779d1d57d23c35c7ba2e94026a47e164ee2 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Mon, 9 Mar 2026 11:30:02 +0000 Subject: [PATCH] refactor(api): add IssueRepoInfo for minimal issue repo queries Add a new IssueRepoInfo function that fetches only the fields needed for issue creation (id, name, owner, hasIssuesEnabled, viewerPermission), avoiding defaultBranchRef and other fields that require Contents:Read. Also add StubIssueRepoInfoResponse helper to httpmock for testing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- api/queries_repo.go | 38 ++++++++++++++++++++++++++++++++++++++ pkg/httpmock/legacy.go | 14 ++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/api/queries_repo.go b/api/queries_repo.go index d358255d8..bbf60a602 100644 --- a/api/queries_repo.go +++ b/api/queries_repo.go @@ -314,6 +314,44 @@ func FetchRepository(client *Client, repo ghrepo.Interface, fields []string) (*R return InitRepoHostname(result.Repository, repo.RepoHost()), nil } +// IssueRepoInfo fetches only the repository fields needed for issue creation, +// avoiding fields like defaultBranchRef that require additional token permissions. +func IssueRepoInfo(client *Client, repo ghrepo.Interface) (*Repository, error) { + query := ` + query IssueRepositoryInfo($owner: String!, $name: String!) { + repository(owner: $owner, name: $name) { + id + name + owner { login } + hasIssuesEnabled + viewerPermission + } + }` + variables := map[string]interface{}{ + "owner": repo.RepoOwner(), + "name": repo.RepoName(), + } + + var result struct { + Repository *Repository + } + if err := client.GraphQL(repo.RepoHost(), query, variables, &result); err != nil { + return nil, err + } + if result.Repository == nil { + return nil, GraphQLError{ + GraphQLError: &ghAPI.GraphQLError{ + Errors: []ghAPI.GraphQLErrorItem{{ + Type: "NOT_FOUND", + Message: fmt.Sprintf("Could not resolve to a Repository with the name '%s/%s'.", repo.RepoOwner(), repo.RepoName()), + }}, + }, + } + } + + return InitRepoHostname(result.Repository, repo.RepoHost()), nil +} + func GitHubRepo(client *Client, repo ghrepo.Interface) (*Repository, error) { query := ` fragment repo on Repository { diff --git a/pkg/httpmock/legacy.go b/pkg/httpmock/legacy.go index ad92d0572..1484734f3 100644 --- a/pkg/httpmock/legacy.go +++ b/pkg/httpmock/legacy.go @@ -22,6 +22,20 @@ func (r *Registry) StubRepoInfoResponse(owner, repo, branch string) { `, repo, owner, branch))) } +func (r *Registry) StubIssueRepoInfoResponse(owner, repo string) { + r.Register( + GraphQL(`query IssueRepositoryInfo\b`), + StringResponse(fmt.Sprintf(` + { "data": { "repository": { + "id": "REPOID", + "name": "%s", + "owner": {"login": "%s"}, + "hasIssuesEnabled": true, + "viewerPermission": "WRITE" + } } } + `, repo, owner))) +} + func (r *Registry) StubRepoResponse(owner, repo string) { r.StubRepoResponseWithPermission(owner, repo, "WRITE") }