Add closingIssuesReferences JSON field to pr view (#10544)

* [gh pr view] Support `closingIssuesReferences` JSON field

* Support pagination

* Support pagination

* Fix typo

* Add more fields
This commit is contained in:
Azeem Sajid 2025-04-29 15:48:20 +05:00 committed by GitHub
parent e1387821af
commit 9ed733fa5e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 172 additions and 0 deletions

View file

@ -139,6 +139,25 @@ func (pr *PullRequest) ExportData(fields []string) map[string]interface{} {
}
}
data[f] = &requests
case "closingIssuesReferences":
items := make([]map[string]interface{}, 0, len(pr.ClosingIssuesReferences.Nodes))
for _, n := range pr.ClosingIssuesReferences.Nodes {
items = append(items, map[string]interface{}{
"id": n.ID,
"number": n.Number,
"url": n.URL,
"repository": map[string]interface{}{
"id": n.Repository.ID,
"name": n.Repository.Name,
"owner": map[string]interface{}{
"id": n.Repository.Owner.ID,
"login": n.Repository.Owner.Login,
},
},
})
}
data[f] = items
default:
sf := fieldByName(v, f)
data[f] = sf.Interface()

View file

@ -245,6 +245,70 @@ func TestPullRequest_ExportData(t *testing.T) {
}
`),
},
{
name: "linked issues",
fields: []string{"closingIssuesReferences"},
inputJSON: heredoc.Doc(`
{ "closingIssuesReferences": { "nodes": [
{
"id": "I_123",
"number": 123,
"url": "https://github.com/cli/cli/issues/123",
"repository": {
"id": "R_123",
"name": "cli",
"owner": {
"id": "O_123",
"login": "cli"
}
}
},
{
"id": "I_456",
"number": 456,
"url": "https://github.com/cli/cli/issues/456",
"repository": {
"id": "R_456",
"name": "cli",
"owner": {
"id": "O_456",
"login": "cli"
}
}
}
] } }
`),
outputJSON: heredoc.Doc(`
{ "closingIssuesReferences": [
{
"id": "I_123",
"number": 123,
"repository": {
"id": "R_123",
"name": "cli",
"owner": {
"id": "O_123",
"login": "cli"
}
},
"url": "https://github.com/cli/cli/issues/123"
},
{
"id": "I_456",
"number": 456,
"repository": {
"id": "R_456",
"name": "cli",
"owner": {
"id": "O_456",
"login": "cli"
}
},
"url": "https://github.com/cli/cli/issues/456"
}
] }
`),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View file

@ -93,6 +93,8 @@ type PullRequest struct {
Reviews PullRequestReviews
LatestReviews PullRequestReviews
ReviewRequests ReviewRequests
ClosingIssuesReferences ClosingIssuesReferences
}
type StatusCheckRollupNode struct {
@ -107,6 +109,26 @@ type CommitStatusCheckRollup struct {
Contexts CheckContexts
}
type ClosingIssuesReferences struct {
Nodes []struct {
ID string
Number int
URL string
Repository struct {
ID string
Name string
Owner struct {
ID string
Login string
}
}
}
PageInfo struct {
HasNextPage bool
EndCursor string
}
}
// https://docs.github.com/en/graphql/reference/enums#checkrunstate
type CheckRunState string

View file

@ -132,6 +132,25 @@ var prCommits = shortenQuery(`
}
`)
var prClosingIssuesReferences = shortenQuery(`
closingIssuesReferences(first: 100) {
nodes {
id,
number,
url,
repository {
id,
name,
owner {
id,
login
}
}
}
pageInfo{hasNextPage,endCursor}
}
`)
var autoMergeRequest = shortenQuery(`
autoMergeRequest {
authorEmail,
@ -287,6 +306,7 @@ var PullRequestFields = append(sharedIssuePRFields,
"baseRefName",
"baseRefOid",
"changedFiles",
"closingIssuesReferences",
"commits",
"deletions",
"files",
@ -366,6 +386,8 @@ func IssueGraphQL(fields []string) string {
q = append(q, StatusCheckRollupGraphQLWithoutCountByState(""))
case "statusCheckRollupWithCountByState": // pseudo-field
q = append(q, StatusCheckRollupGraphQLWithCountByState())
case "closingIssuesReferences":
q = append(q, prClosingIssuesReferences)
default:
q = append(q, field)
}

View file

@ -239,6 +239,11 @@ func (f *finder) Find(opts FindOptions) (*api.PullRequest, ghrepo.Interface, err
return preloadPrComments(httpClient, f.baseRefRepo, pr)
})
}
if fields.Contains("closingIssuesReferences") {
g.Go(func() error {
return preloadPrClosingIssuesReferences(httpClient, f.baseRefRepo, pr)
})
}
if fields.Contains("statusCheckRollup") {
g.Go(func() error {
return preloadPrChecks(httpClient, f.baseRefRepo, pr)
@ -452,6 +457,45 @@ func preloadPrComments(client *http.Client, repo ghrepo.Interface, pr *api.PullR
return nil
}
func preloadPrClosingIssuesReferences(client *http.Client, repo ghrepo.Interface, pr *api.PullRequest) error {
if !pr.ClosingIssuesReferences.PageInfo.HasNextPage {
return nil
}
type response struct {
Node struct {
PullRequest struct {
ClosingIssuesReferences api.ClosingIssuesReferences `graphql:"closingIssuesReferences(first: 100, after: $endCursor)"`
} `graphql:"...on PullRequest"`
} `graphql:"node(id: $id)"`
}
variables := map[string]interface{}{
"id": githubv4.ID(pr.ID),
"endCursor": githubv4.String(pr.ClosingIssuesReferences.PageInfo.EndCursor),
}
gql := api.NewClientFromHTTP(client)
for {
var query response
err := gql.Query(repo.RepoHost(), "closingIssuesReferences", &query, variables)
if err != nil {
return err
}
pr.ClosingIssuesReferences.Nodes = append(pr.ClosingIssuesReferences.Nodes, query.Node.PullRequest.ClosingIssuesReferences.Nodes...)
if !query.Node.PullRequest.ClosingIssuesReferences.PageInfo.HasNextPage {
break
}
variables["endCursor"] = githubv4.String(query.Node.PullRequest.ClosingIssuesReferences.PageInfo.EndCursor)
}
pr.ClosingIssuesReferences.PageInfo.HasNextPage = false
return nil
}
func preloadPrChecks(client *http.Client, repo ghrepo.Interface, pr *api.PullRequest) error {
if len(pr.StatusCheckRollup.Nodes) == 0 {
return nil

View file

@ -37,6 +37,7 @@ func TestJSONFields(t *testing.T) {
"changedFiles",
"closed",
"closedAt",
"closingIssuesReferences",
"comments",
"commits",
"createdAt",