fix(batches): don't request unnecessary info that's likely to cause GH errors (#64299)

Closes SRCH-802

After a long and unsuccessful hunt of eventual consistency errors, I
noticed that we don't need the GraphQL fragments that are causing
problems.

I introduced a simplified request, which succeeds reliably. What
customers should see now is one error (see second picture below), which
is followed by a retry, and then success.

Previously we've seen this error, sometimes less often, sometimes more,
but customers saw it so often that it caused their batch changes to
fail.

<img width="1042" alt="Screenshot 2024-08-06 at 14 02 00"
src="https://github.com/user-attachments/assets/c5a099da-d474-43db-ac12-ac7c4f22d4d3">

Customers may still see an initial error, which I've seen to reliably
disappear on the first retry. It should not be a problem

<img width="1039" alt="Screenshot 2024-08-06 at 14 02 48"
src="https://github.com/user-attachments/assets/99f278d4-4020-48ea-b4ac-32cbdfce455d">

## Test plan

Manual testing

## Changelog

- fix(batches): improve GitHub Apps integration reliability by
simplifying the data requested from GitHub
This commit is contained in:
Michael Bahr 2024-08-07 10:47:37 +02:00 committed by GitHub
parent 81fa144f4f
commit 4d6e8949e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 157 additions and 473 deletions

View File

@ -231,7 +231,7 @@ func (s GitHubSource) createChangeset(ctx context.Context, c *Changeset, prInput
if err != nil {
return exists, errors.Wrap(err, "getting repo owner and name")
}
pr, err = s.client.GetOpenPullRequestByRefs(ctx, owner, name, c.BaseRef, c.HeadRef)
pr, err = s.client.GetOpenPullRequestByRefsReduced(ctx, owner, name, c.BaseRef, c.HeadRef)
if err != nil {
return exists, errors.Wrap(err, "fetching existing PR")
}

View File

@ -11,141 +11,33 @@
"Number": 1,
"ReviewDecision": "REVIEW_REQUIRED",
"Author": {
"AvatarURL": "https://avatars.githubusercontent.com/u/1185253?u=35f048c505007991433b46c9c0616ccbcfbd4bff\u0026v=4",
"Login": "mrnugget",
"URL": "https://github.com/mrnugget"
},
"BaseRepository": {
"ID": "MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM=",
"Name": "automation-testing",
"Owner": {
"Login": "sourcegraph"
}
},
"HeadRepository": {
"ID": "MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM=",
"Name": "automation-testing",
"Owner": {
"Login": "sourcegraph"
}
},
"Participants": [
{
"AvatarURL": "https://avatars.githubusercontent.com/u/1185253?u=35f048c505007991433b46c9c0616ccbcfbd4bff\u0026v=4",
"AvatarURL": "https://avatars3.githubusercontent.com/u/1185253?v=4",
"Login": "mrnugget",
"URL": "https://github.com/mrnugget"
},
{
"AvatarURL": "https://avatars.githubusercontent.com/u/19534377?v=4",
"Login": "eseliger",
"URL": "https://github.com/eseliger"
}
],
"Labels": {
"Nodes": []
},
"TimelineItems": [
{
"Type": "PullRequestCommit",
"Item": {
"Commit": {
"OID": "9d04a0d8733dafbb5d75e594a9ec525c49dfc975",
"Message": "Add another file",
"MessageHeadline": "Add another file",
"URL": "https://github.com/sourcegraph/automation-testing/commit/9d04a0d8733dafbb5d75e594a9ec525c49dfc975",
"Committer": {
"AvatarURL": "https://avatars.githubusercontent.com/u/1185253?v=4",
"Email": "mrnugget@gmail.com",
"Name": "Thorsten Ball",
"User": {
"AvatarURL": "https://avatars.githubusercontent.com/u/1185253?u=35f048c505007991433b46c9c0616ccbcfbd4bff\u0026v=4",
"Login": "mrnugget",
"URL": "https://github.com/mrnugget"
}
},
"CommittedDate": "2019-11-12T06:38:55Z",
"PushedDate": "2019-11-12T06:39:00Z"
}
"BaseRepository": {
"ID": "MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM=",
"Name": "automation-testing",
"Owner": {
"Login": "sourcegraph"
}
},
{
"Type": "PullRequestCommit",
"Item": {
"Commit": {
"OID": "37406e7dfa4466b80d1da183d6477aac16b1e58c",
"Message": "Test commit to always have a open PR",
"MessageHeadline": "Test commit to always have a open PR",
"URL": "https://github.com/sourcegraph/automation-testing/commit/37406e7dfa4466b80d1da183d6477aac16b1e58c",
"Committer": {
"AvatarURL": "https://avatars.githubusercontent.com/u/1185253?v=4",
"Email": "mrnugget@gmail.com",
"Name": "Thorsten Ball",
"User": {
"AvatarURL": "https://avatars.githubusercontent.com/u/1185253?u=35f048c505007991433b46c9c0616ccbcfbd4bff\u0026v=4",
"Login": "mrnugget",
"URL": "https://github.com/mrnugget"
}
},
"CommittedDate": "2019-11-12T06:39:23Z",
"PushedDate": "2019-11-12T06:39:33Z"
}
},
"HeadRepository": {
"ID": "MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM=",
"Name": "automation-testing",
"Owner": {
"Login": "sourcegraph"
}
},
{
"Type": "ClosedEvent",
"Item": {
"Actor": {
"AvatarURL": "https://avatars.githubusercontent.com/u/19534377?v=4",
"Login": "eseliger",
"URL": "https://github.com/eseliger"
},
"CreatedAt": "2019-12-04T23:28:16Z",
"URL": "https://github.com/sourcegraph/automation-testing/pull/1#event-2855920542"
}
},
{
"Type": "ReopenedEvent",
"Item": {
"Actor": {
"AvatarURL": "https://avatars.githubusercontent.com/u/1185253?u=35f048c505007991433b46c9c0616ccbcfbd4bff\u0026v=4",
"Login": "mrnugget",
"URL": "https://github.com/mrnugget"
},
"CreatedAt": "2019-12-05T07:09:21Z"
}
},
{
"Type": "RenamedTitleEvent",
"Item": {
"Actor": {
"AvatarURL": "https://avatars.githubusercontent.com/u/1185253?u=35f048c505007991433b46c9c0616ccbcfbd4bff\u0026v=4",
"Login": "mrnugget",
"URL": "https://github.com/mrnugget"
},
"PreviousTitle": "This is a test PR that is always open",
"CurrentTitle": "This is a test PR that is always open (keep it open!)",
"CreatedAt": "2019-12-05T07:09:31Z"
}
}
],
},
"Commits": {
"Nodes": [
{
"Commit": {
"OID": "37406e7dfa4466b80d1da183d6477aac16b1e58c",
"CheckSuites": {
"Nodes": []
},
"Status": {
"State": "",
"Contexts": null
},
"CommittedDate": "2019-11-12T06:39:23Z"
}
}
]
"Nodes": []
},
"Labels": {
"Nodes": []
},
"Participants": [],
"TimelineItems": [],
"IsDraft": false,
"CreatedAt": "2019-11-12T06:40:21Z",
"UpdatedAt": "2023-02-03T20:42:20Z"
}
}

View File

@ -1,204 +0,0 @@
---
version: 1
interactions:
- request:
body: '{"query":"\nfragment actor on Actor {\n avatarUrl\n login\n url\n}\n\nfragment
label on Label {\n name\n color\n description\n id\n}\n\nfragment commit
on Commit {\n oid\n message\n messageHeadline\n committedDate\n pushedDate\n url\n committer
{\n avatarUrl\n email\n name\n user {\n ...actor\n }\n }\n}\n\nfragment
basicCommit on Commit {\n oid\n status {\n state\n contexts {\n id\n context\n state\n description\n }\n }\n checkSuites(last:
10){\n nodes {\n id\n status\n conclusion\n }\n }\n committedDate\n}\n\nfragment
prCommit on PullRequestCommit {\n commit {\n ...basicCommit\n }\n}\n\nfragment
review on PullRequestReview {\n databaseId\n author {\n ...actor\n }\n authorAssociation\n body\n state\n url\n createdAt\n updatedAt\n commit
{\n ...commit\n }\n includesCreatedEdit\n}\n\nfragment pr on PullRequest
{\n id\n title\n body\n state\n url\n number\n createdAt\n updatedAt\n headRefOid\n baseRefOid\n headRefName\n baseRefName\n author
{\n ...actor\n }\n participants(first: 100) {\n nodes {\n ...actor\n }\n }\n labels(first:
100) {\n nodes {\n ...label\n }\n }\n commits(last: 1) {\n nodes
{\n ...prCommit\n }\n }\n timelineItems(first: 250, itemTypes: [ASSIGNED_EVENT,
CLOSED_EVENT, ISSUE_COMMENT, RENAMED_TITLE_EVENT, MERGED_EVENT, PULL_REQUEST_REVIEW,
PULL_REQUEST_REVIEW_THREAD, REOPENED_EVENT, REVIEW_DISMISSED_EVENT, REVIEW_REQUEST_REMOVED_EVENT,
REVIEW_REQUESTED_EVENT, UNASSIGNED_EVENT, LABELED_EVENT, UNLABELED_EVENT, PULL_REQUEST_COMMIT])
{\n nodes {\n __typename\n ... on AssignedEvent {\n actor
{\n ...actor\n }\n assignee {\n ...actor\n }\n createdAt\n }\n ...
on ClosedEvent {\n actor {\n ...actor\n }\n createdAt\n url\n }\n ...
on IssueComment {\n databaseId\n author {\n ...actor\n }\n authorAssociation\n body\n createdAt\n editor
{\n ...actor\n }\n url\n updatedAt\n includesCreatedEdit\n publishedAt\n }\n ...
on RenamedTitleEvent {\n actor {\n ...actor\n }\n previousTitle\n currentTitle\n createdAt\n }\n ...
on MergedEvent {\n actor {\n ...actor\n }\n mergeRefName\n url\n commit
{\n ...commit\n }\n createdAt\n }\n ... on
PullRequestReview {\n ...review\n }\n ... on PullRequestReviewThread
{\n comments(last: 100) {\n nodes {\n databaseId\n author
{\n ...actor\n }\n authorAssociation\n editor
{\n ...actor\n }\n commit {\n ...commit\n }\n body\n state\n url\n createdAt\n updatedAt\n includesCreatedEdit\n }\n }\n }\n ...
on ReopenedEvent {\n actor {\n ...actor\n }\n createdAt\n }\n ...
on ReviewDismissedEvent {\n actor {\n ...actor\n }\n review
{\n ...review\n }\n dismissalMessage\n createdAt\n }\n ...
on ReviewRequestRemovedEvent {\n actor {\n ...actor\n }\n requestedReviewer
{\n ...actor\n }\n requestedTeam: requestedReviewer {\n ...
on Team {\n name\n url\n avatarUrl\n }\n }\n createdAt\n }\n ...
on ReviewRequestedEvent {\n actor {\n ...actor\n }\n requestedReviewer
{\n ...actor\n }\n requestedTeam: requestedReviewer {\n ...
on Team {\n name\n url\n avatarUrl\n }\n }\n createdAt\n }\n ...
on UnassignedEvent {\n actor {\n ...actor\n }\n assignee
{\n ...actor\n }\n createdAt\n }\n ... on LabeledEvent
{\n actor {\n ...actor\n }\n label {\n ...label\n }\n createdAt\n }\n ...
on UnlabeledEvent {\n actor {\n ...actor\n }\n label
{\n ...label\n }\n createdAt\n }\n ... on PullRequestCommit
{\n ...prCommit\n }\n }\n }\n}\nmutation\tCreatePullRequest($input:CreatePullRequestInput!)
{\n createPullRequest(input:$input) {\n pullRequest {\n ... pr\n }\n }\n}","variables":{"input":{"repositoryId":"MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM=","baseRefName":"master","headRefName":"always-open-pr","title":"This
is a test PR","body":"This is the description of the test PR"}}}'
form: {}
headers:
Accept:
- application/vnd.github.antiope-preview+json
Content-Type:
- application/json; charset=utf-8
url: https://api.github.com/graphql
method: POST
response:
body: '{"data":{"createPullRequest":{"pullRequest":null}},"errors":[{"type":"UNPROCESSABLE","path":["createPullRequest"],"locations":[{"line":269,"column":3}],"message":"A
pull request already exists for sourcegraph:always-open-pr."}]}'
headers:
Access-Control-Allow-Origin:
- '*'
Access-Control-Expose-Headers:
- ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining,
X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval,
X-GitHub-Media-Type
Cache-Control:
- no-cache
Content-Security-Policy:
- default-src 'none'
Content-Type:
- application/json; charset=utf-8
Date:
- Wed, 12 Feb 2020 10:50:05 GMT
Referrer-Policy:
- origin-when-cross-origin, strict-origin-when-cross-origin
Server:
- GitHub.com
Status:
- 200 OK
Strict-Transport-Security:
- max-age=31536000; includeSubdomains; preload
Vary:
- Accept-Encoding, Accept
X-Accepted-Oauth-Scopes:
- repo
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- deny
X-Github-Media-Type:
- github.antiope-preview; format=json
X-Github-Request-Id:
- 114D:40410:1F4E5A4:25E1852:5E43D85C
X-Oauth-Scopes:
- read:org, repo
X-Xss-Protection:
- 1; mode=block
status: 200 OK
code: 200
duration: ""
- request:
body: '{"query":"\nfragment actor on Actor {\n avatarUrl\n login\n url\n}\n\nfragment
label on Label {\n name\n color\n description\n id\n}\n\nfragment commit
on Commit {\n oid\n message\n messageHeadline\n committedDate\n pushedDate\n url\n committer
{\n avatarUrl\n email\n name\n user {\n ...actor\n }\n }\n}\n\nfragment
basicCommit on Commit {\n oid\n status {\n state\n contexts {\n id\n context\n state\n description\n }\n }\n checkSuites(last:
10){\n nodes {\n id\n status\n conclusion\n }\n }\n committedDate\n}\n\nfragment
prCommit on PullRequestCommit {\n commit {\n ...basicCommit\n }\n}\n\nfragment
review on PullRequestReview {\n databaseId\n author {\n ...actor\n }\n authorAssociation\n body\n state\n url\n createdAt\n updatedAt\n commit
{\n ...commit\n }\n includesCreatedEdit\n}\n\nfragment pr on PullRequest
{\n id\n title\n body\n state\n url\n number\n createdAt\n updatedAt\n headRefOid\n baseRefOid\n headRefName\n baseRefName\n author
{\n ...actor\n }\n participants(first: 100) {\n nodes {\n ...actor\n }\n }\n labels(first:
100) {\n nodes {\n ...label\n }\n }\n commits(last: 1) {\n nodes
{\n ...prCommit\n }\n }\n timelineItems(first: 250, itemTypes: [ASSIGNED_EVENT,
CLOSED_EVENT, ISSUE_COMMENT, RENAMED_TITLE_EVENT, MERGED_EVENT, PULL_REQUEST_REVIEW,
PULL_REQUEST_REVIEW_THREAD, REOPENED_EVENT, REVIEW_DISMISSED_EVENT, REVIEW_REQUEST_REMOVED_EVENT,
REVIEW_REQUESTED_EVENT, UNASSIGNED_EVENT, LABELED_EVENT, UNLABELED_EVENT, PULL_REQUEST_COMMIT])
{\n nodes {\n __typename\n ... on AssignedEvent {\n actor
{\n ...actor\n }\n assignee {\n ...actor\n }\n createdAt\n }\n ...
on ClosedEvent {\n actor {\n ...actor\n }\n createdAt\n url\n }\n ...
on IssueComment {\n databaseId\n author {\n ...actor\n }\n authorAssociation\n body\n createdAt\n editor
{\n ...actor\n }\n url\n updatedAt\n includesCreatedEdit\n publishedAt\n }\n ...
on RenamedTitleEvent {\n actor {\n ...actor\n }\n previousTitle\n currentTitle\n createdAt\n }\n ...
on MergedEvent {\n actor {\n ...actor\n }\n mergeRefName\n url\n commit
{\n ...commit\n }\n createdAt\n }\n ... on
PullRequestReview {\n ...review\n }\n ... on PullRequestReviewThread
{\n comments(last: 100) {\n nodes {\n databaseId\n author
{\n ...actor\n }\n authorAssociation\n editor
{\n ...actor\n }\n commit {\n ...commit\n }\n body\n state\n url\n createdAt\n updatedAt\n includesCreatedEdit\n }\n }\n }\n ...
on ReopenedEvent {\n actor {\n ...actor\n }\n createdAt\n }\n ...
on ReviewDismissedEvent {\n actor {\n ...actor\n }\n review
{\n ...review\n }\n dismissalMessage\n createdAt\n }\n ...
on ReviewRequestRemovedEvent {\n actor {\n ...actor\n }\n requestedReviewer
{\n ...actor\n }\n requestedTeam: requestedReviewer {\n ...
on Team {\n name\n url\n avatarUrl\n }\n }\n createdAt\n }\n ...
on ReviewRequestedEvent {\n actor {\n ...actor\n }\n requestedReviewer
{\n ...actor\n }\n requestedTeam: requestedReviewer {\n ...
on Team {\n name\n url\n avatarUrl\n }\n }\n createdAt\n }\n ...
on UnassignedEvent {\n actor {\n ...actor\n }\n assignee
{\n ...actor\n }\n createdAt\n }\n ... on LabeledEvent
{\n actor {\n ...actor\n }\n label {\n ...label\n }\n createdAt\n }\n ...
on UnlabeledEvent {\n actor {\n ...actor\n }\n label
{\n ...label\n }\n createdAt\n }\n ... on PullRequestCommit
{\n ...prCommit\n }\n }\n }\n}\nquery {\nrepository(owner: \"sourcegraph\",
name: \"automation-testing\") {\npullRequests(baseRefName: \"master\", headRefName:
\"always-open-pr\", first: 1, states: OPEN) { \nnodes{ ... pr }\n}\n}\n}","variables":null}'
form: {}
headers:
Accept:
- application/vnd.github.antiope-preview+json
Content-Type:
- application/json; charset=utf-8
url: https://api.github.com/graphql
method: POST
response:
body: '{"data":{"repository":{"pullRequests":{"nodes":[{"id":"MDExOlB1bGxSZXF1ZXN0MzM5NzUyNDQy","title":"This
is a test PR that is always open (keep it open!)","body":"Feel free to ignore
this. This is a test PR that is always open.","state":"OPEN","url":"https://github.com/sourcegraph/automation-testing/pull/1","number":1,"createdAt":"2019-11-12T06:40:21Z","updatedAt":"2019-12-05T07:09:31Z","headRefOid":"37406e7dfa4466b80d1da183d6477aac16b1e58c","baseRefOid":"c75943274b322ffef2230df8f8049de84ddf12c1","headRefName":"always-open-pr","baseRefName":"master","author":{"avatarUrl":"https://avatars3.githubusercontent.com/u/1185253?v=4","login":"mrnugget","url":"https://github.com/mrnugget"},"participants":{"nodes":[{"avatarUrl":"https://avatars3.githubusercontent.com/u/1185253?v=4","login":"mrnugget","url":"https://github.com/mrnugget"},{"avatarUrl":"https://avatars0.githubusercontent.com/u/19534377?v=4","login":"eseliger","url":"https://github.com/eseliger"}]},"labels":{"nodes":[]},"commits":{"nodes":[{"commit":{"oid":"37406e7dfa4466b80d1da183d6477aac16b1e58c","status":null,"checkSuites":{"nodes":[{"id":"MDEwOkNoZWNrU3VpdGUzMDY0MTAzODA=","status":"QUEUED","conclusion":null},{"id":"MDEwOkNoZWNrU3VpdGUzMDY0MTAzODM=","status":"QUEUED","conclusion":null}]},"committedDate":"2019-11-12T06:39:23Z"}}]},"timelineItems":{"nodes":[{"__typename":"PullRequestCommit","commit":{"oid":"9d04a0d8733dafbb5d75e594a9ec525c49dfc975","status":null,"checkSuites":{"nodes":[{"id":"MDEwOkNoZWNrU3VpdGUzMDY0MDk4NjE=","status":"QUEUED","conclusion":null},{"id":"MDEwOkNoZWNrU3VpdGUzMDY0MDk4NjI=","status":"QUEUED","conclusion":null}]},"committedDate":"2019-11-12T06:38:55Z"}},{"__typename":"PullRequestCommit","commit":{"oid":"37406e7dfa4466b80d1da183d6477aac16b1e58c","status":null,"checkSuites":{"nodes":[{"id":"MDEwOkNoZWNrU3VpdGUzMDY0MTAzODA=","status":"QUEUED","conclusion":null},{"id":"MDEwOkNoZWNrU3VpdGUzMDY0MTAzODM=","status":"QUEUED","conclusion":null}]},"committedDate":"2019-11-12T06:39:23Z"}},{"__typename":"ClosedEvent","actor":{"avatarUrl":"https://avatars0.githubusercontent.com/u/19534377?v=4","login":"eseliger","url":"https://github.com/eseliger"},"createdAt":"2019-12-04T23:28:16Z","url":"https://github.com/sourcegraph/automation-testing/pull/1#event-2855920542"},{"__typename":"ReopenedEvent","actor":{"avatarUrl":"https://avatars3.githubusercontent.com/u/1185253?v=4","login":"mrnugget","url":"https://github.com/mrnugget"},"createdAt":"2019-12-05T07:09:21Z"},{"__typename":"RenamedTitleEvent","actor":{"avatarUrl":"https://avatars3.githubusercontent.com/u/1185253?v=4","login":"mrnugget","url":"https://github.com/mrnugget"},"previousTitle":"This
is a test PR that is always open","currentTitle":"This is a test PR that is
always open (keep it open!)","createdAt":"2019-12-05T07:09:31Z"}]}}]}}}}'
headers:
Access-Control-Allow-Origin:
- '*'
Access-Control-Expose-Headers:
- ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining,
X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval,
X-GitHub-Media-Type
Cache-Control:
- no-cache
Content-Security-Policy:
- default-src 'none'
Content-Type:
- application/json; charset=utf-8
Date:
- Wed, 12 Feb 2020 10:50:06 GMT
Referrer-Policy:
- origin-when-cross-origin, strict-origin-when-cross-origin
Server:
- GitHub.com
Status:
- 200 OK
Strict-Transport-Security:
- max-age=31536000; includeSubdomains; preload
Vary:
- Accept-Encoding, Accept
X-Accepted-Oauth-Scopes:
- repo
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- deny
X-Github-Media-Type:
- github.antiope-preview; format=json
X-Github-Request-Id:
- 114D:40410:1F4E6D6:25E19A1:5E43D85D
X-Oauth-Scopes:
- read:org, repo
X-Xss-Protection:
- 1; mode=block
status: 200 OK
code: 200
duration: ""

View File

@ -2,216 +2,111 @@
version: 1
interactions:
- request:
body: '{"query":"\nfragment commit on Commit {\n oid\n message\n messageHeadline\n committedDate\n pushedDate\n url\n committer
{\n avatarUrl\n email\n name\n user {\n ...actor\n }\n }\n}\n\nfragment
review on PullRequestReview {\n databaseId\n author {\n ...actor\n }\n authorAssociation\n body\n state\n url\n createdAt\n updatedAt\n commit
{\n ...commit\n }\n includesCreatedEdit\n}\n\nfragment timelineItems on
PullRequestTimelineItems {\n ... on AssignedEvent {\n actor {\n ...actor\n }\n assignee
{\n ...actor\n }\n createdAt\n }\n ... on ClosedEvent {\n actor
{\n ...actor\n }\n createdAt\n url\n }\n ... on IssueComment
{\n databaseId\n author {\n ...actor\n }\n authorAssociation\n body\n createdAt\n editor
{\n ...actor\n }\n url\n updatedAt\n includesCreatedEdit\n publishedAt\n }\n ...
on RenamedTitleEvent {\n actor {\n ...actor\n }\n previousTitle\n currentTitle\n createdAt\n }\n ...
on MergedEvent {\n actor {\n ...actor\n }\n mergeRefName\n url\n commit
{\n ...commit\n }\n createdAt\n }\n ... on PullRequestReview {\n ...review\n }\n ...
on PullRequestReviewThread {\n comments(last: 100) {\n nodes {\n databaseId\n author
{\n ...actor\n }\n authorAssociation\n editor
{\n ...actor\n }\n commit {\n ...commit\n }\n body\n state\n url\n createdAt\n updatedAt\n includesCreatedEdit\n }\n }\n }\n ...
on ReopenedEvent {\n actor {\n ...actor\n }\n createdAt\n }\n ...
on ReviewDismissedEvent {\n actor {\n ...actor\n }\n review {\n ...review\n }\n dismissalMessage\n createdAt\n }\n ...
on ReviewRequestRemovedEvent {\n actor {\n ...actor\n }\n requestedReviewer
{\n ...actor\n }\n requestedTeam: requestedReviewer {\n ...
on Team {\n name\n url\n avatarUrl\n }\n }\n createdAt\n }\n ...
on ReviewRequestedEvent {\n actor {\n ...actor\n }\n requestedReviewer
{\n ...actor\n }\n requestedTeam: requestedReviewer {\n ...
on Team {\n name\n url\n avatarUrl\n }\n }\n createdAt\n }\n ...
on ReadyForReviewEvent {\n actor {\n ...actor\n }\n createdAt\n }\n ...
on UnassignedEvent {\n actor {\n ...actor\n }\n assignee {\n ...actor\n }\n createdAt\n }\n ...
on LabeledEvent {\n actor {\n ...actor\n }\n label {\n ...label\n }\n createdAt\n }\n ...
on UnlabeledEvent {\n actor {\n ...actor\n }\n label {\n ...label\n }\n createdAt\n }\n ...
on PullRequestCommit {\n commit {\n ...commit\n }\n }\n \n ...
on ConvertToDraftEvent {\n actor {\n\t ...actor\n\t}\n\tcreatedAt\n }\n\n}\n\nfragment
actor on Actor {\n avatarUrl\n login\n url\n}\n\nfragment label on Label
{\n name\n color\n description\n id\n}\n\nfragment commitWithChecks on Commit
{\n oid\n status {\n state\n contexts {\n id\n context\n state\n description\n }\n }\n checkSuites(last:
20) {\n nodes {\n id\n status\n conclusion\n checkRuns(last:
20) {\n nodes {\n id\n status\n conclusion\n }\n }\n }\n }\n committedDate\n}\n\nfragment
prCommit on PullRequestCommit {\n commit {\n ...commitWithChecks\n }\n}\n\nfragment
repo on Repository {\n id\n name\n owner {\n login\n }\n}\n\nfragment
pr on PullRequest {\n id\n title\n body\n state\n url\n number\n createdAt\n updatedAt\n headRefOid\n baseRefOid\n headRefName\n baseRefName\n reviewDecision\n isDraft\n author
{\n ...actor\n }\n baseRepository {\n ...repo\n }\n headRepository
{\n ...repo\n }\n participants(first: 100) {\n nodes {\n ...actor\n }\n }\n labels(first:
100) {\n nodes {\n ...label\n }\n }\n commits(last: 1) {\n nodes
{\n ...prCommit\n }\n }\n timelineItems(first: 250, itemTypes: [ASSIGNED_EVENT,
CLOSED_EVENT, ISSUE_COMMENT, RENAMED_TITLE_EVENT, MERGED_EVENT, PULL_REQUEST_REVIEW,
PULL_REQUEST_REVIEW_THREAD, REOPENED_EVENT, REVIEW_DISMISSED_EVENT, REVIEW_REQUEST_REMOVED_EVENT,
REVIEW_REQUESTED_EVENT, UNASSIGNED_EVENT, LABELED_EVENT, UNLABELED_EVENT, PULL_REQUEST_COMMIT,
READY_FOR_REVIEW_EVENT, CONVERT_TO_DRAFT_EVENT]) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes
{\n __typename\n ...timelineItems\n }\n }\n}\nmutation\tCreatePullRequest($input:CreatePullRequestInput!)
{\n createPullRequest(input:$input) {\n pullRequest {\n ... pr\n }\n }\n}","variables":{"input":{"baseRefName":"master","body":"This
is the description of the test PR","draft":false,"headRefName":"always-open-pr","repositoryId":"MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM=","title":"This
is a test PR"}}}'
body: '{"query":"\nfragment actor on Actor {\n avatarUrl\n login\n url\n}\n\nfragment\nreview on PullRequestReview {\n databaseId\n author {\n ...actor\n }\n authorAssociation\n body\n state\n url\n createdAt\n updatedAt\n commit\n{\n ...commit\n }\n includesCreatedEdit\n}\n\nfragment pr on PullRequest\n{\n id\n title\n body\n state\n url\n number\n createdAt\n updatedAt\n headRefOid\n baseRefOid\n headRefName\n baseRefName\n author\n{\n ...actor\n }\n}\nmutation\tCreatePullRequest($input:CreatePullRequestInput!)\n{\n createPullRequest(input:$input) {\n pullRequest {\n ... pr\n }\n }\n}","variables":{"input":{"repositoryId":"MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM=","baseRefName":"master","headRefName":"always-open-pr","title":"This\nis a test PR","body":"This is the description of the test PR"}}}'
form: {}
headers:
Accept:
- application/vnd.github.antiope-preview+json
Cache-Control:
- max-age=0
Content-Type:
- application/json; charset=utf-8
url: https://api.github.com/graphql
method: POST
response:
body: '{"data":{"createPullRequest":{"pullRequest":null}},"errors":[{"type":"UNPROCESSABLE","path":["createPullRequest"],"locations":[{"line":316,"column":3}],"message":"A
pull request already exists for sourcegraph:always-open-pr."}],"extensions":{"warnings":[{"type":"DEPRECATION","message":"The
id MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM= is deprecated. Update your cache to use
the next_global_id from the data payload.","data":{"legacy_global_id":"MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM=","next_global_id":"R_kgDODS5xeQ"},"link":"https://docs.github.com"}]}}'
body: '{"data":{"createPullRequest":{"pullRequest":null}},"errors":[{"type":"UNPROCESSABLE","path":["createPullRequest"],"locations":[{"line":269,"column":3}],"message":"A
pull request already exists for sourcegraph:always-open-pr."}]}'
headers:
Access-Control-Allow-Origin:
- '*'
Access-Control-Expose-Headers:
- ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining,
X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes,
X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO,
X-GitHub-Request-Id, Deprecation, Sunset
X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval,
X-GitHub-Media-Type
Cache-Control:
- no-cache
Content-Security-Policy:
- default-src 'none'
Content-Type:
- application/json; charset=utf-8
Date:
- Fri, 23 Jun 2023 15:36:28 GMT
- Wed, 12 Feb 2020 10:50:05 GMT
Referrer-Policy:
- origin-when-cross-origin, strict-origin-when-cross-origin
Server:
- GitHub.com
Status:
- 200 OK
Strict-Transport-Security:
- max-age=31536000; includeSubdomains; preload
Vary:
- Accept-Encoding, Accept, X-Requested-With
- Accept-Encoding, Accept
X-Accepted-Oauth-Scopes:
- repo
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- deny
X-Github-Media-Type:
- github.v4; param=antiope-preview; format=json
- github.antiope-preview; format=json
X-Github-Request-Id:
- CE3E:5A99:111D549:22E2D0D:6495BBFC
X-Ratelimit-Resource:
- graphql
X-Ratelimit-Used:
- "124"
- 114D:40410:1F4E5A4:25E1852:5E43D85C
X-Oauth-Scopes:
- read:org, repo
X-Xss-Protection:
- "0"
- 1; mode=block
status: 200 OK
code: 200
duration: ""
- request:
body: '{"query":"\nfragment commit on Commit {\n oid\n message\n messageHeadline\n committedDate\n pushedDate\n url\n committer
{\n avatarUrl\n email\n name\n user {\n ...actor\n }\n }\n}\n\nfragment
review on PullRequestReview {\n databaseId\n author {\n ...actor\n }\n authorAssociation\n body\n state\n url\n createdAt\n updatedAt\n commit
{\n ...commit\n }\n includesCreatedEdit\n}\n\nfragment timelineItems on
PullRequestTimelineItems {\n ... on AssignedEvent {\n actor {\n ...actor\n }\n assignee
{\n ...actor\n }\n createdAt\n }\n ... on ClosedEvent {\n actor
{\n ...actor\n }\n createdAt\n url\n }\n ... on IssueComment
{\n databaseId\n author {\n ...actor\n }\n authorAssociation\n body\n createdAt\n editor
{\n ...actor\n }\n url\n updatedAt\n includesCreatedEdit\n publishedAt\n }\n ...
on RenamedTitleEvent {\n actor {\n ...actor\n }\n previousTitle\n currentTitle\n createdAt\n }\n ...
on MergedEvent {\n actor {\n ...actor\n }\n mergeRefName\n url\n commit
{\n ...commit\n }\n createdAt\n }\n ... on PullRequestReview {\n ...review\n }\n ...
on PullRequestReviewThread {\n comments(last: 100) {\n nodes {\n databaseId\n author
{\n ...actor\n }\n authorAssociation\n editor
{\n ...actor\n }\n commit {\n ...commit\n }\n body\n state\n url\n createdAt\n updatedAt\n includesCreatedEdit\n }\n }\n }\n ...
on ReopenedEvent {\n actor {\n ...actor\n }\n createdAt\n }\n ...
on ReviewDismissedEvent {\n actor {\n ...actor\n }\n review {\n ...review\n }\n dismissalMessage\n createdAt\n }\n ...
on ReviewRequestRemovedEvent {\n actor {\n ...actor\n }\n requestedReviewer
{\n ...actor\n }\n requestedTeam: requestedReviewer {\n ...
on Team {\n name\n url\n avatarUrl\n }\n }\n createdAt\n }\n ...
on ReviewRequestedEvent {\n actor {\n ...actor\n }\n requestedReviewer
{\n ...actor\n }\n requestedTeam: requestedReviewer {\n ...
on Team {\n name\n url\n avatarUrl\n }\n }\n createdAt\n }\n ...
on ReadyForReviewEvent {\n actor {\n ...actor\n }\n createdAt\n }\n ...
on UnassignedEvent {\n actor {\n ...actor\n }\n assignee {\n ...actor\n }\n createdAt\n }\n ...
on LabeledEvent {\n actor {\n ...actor\n }\n label {\n ...label\n }\n createdAt\n }\n ...
on UnlabeledEvent {\n actor {\n ...actor\n }\n label {\n ...label\n }\n createdAt\n }\n ...
on PullRequestCommit {\n commit {\n ...commit\n }\n }\n \n ...
on ConvertToDraftEvent {\n actor {\n\t ...actor\n\t}\n\tcreatedAt\n }\n\n}\n\nfragment
actor on Actor {\n avatarUrl\n login\n url\n}\n\nfragment label on Label
{\n name\n color\n description\n id\n}\n\nfragment commitWithChecks on Commit
{\n oid\n status {\n state\n contexts {\n id\n context\n state\n description\n }\n }\n checkSuites(last:
20) {\n nodes {\n id\n status\n conclusion\n checkRuns(last:
20) {\n nodes {\n id\n status\n conclusion\n }\n }\n }\n }\n committedDate\n}\n\nfragment
prCommit on PullRequestCommit {\n commit {\n ...commitWithChecks\n }\n}\n\nfragment
repo on Repository {\n id\n name\n owner {\n login\n }\n}\n\nfragment
pr on PullRequest {\n id\n title\n body\n state\n url\n number\n createdAt\n updatedAt\n headRefOid\n baseRefOid\n headRefName\n baseRefName\n reviewDecision\n isDraft\n author
{\n ...actor\n }\n baseRepository {\n ...repo\n }\n headRepository
{\n ...repo\n }\n participants(first: 100) {\n nodes {\n ...actor\n }\n }\n labels(first:
100) {\n nodes {\n ...label\n }\n }\n commits(last: 1) {\n nodes
{\n ...prCommit\n }\n }\n timelineItems(first: 250, itemTypes: [ASSIGNED_EVENT,
CLOSED_EVENT, ISSUE_COMMENT, RENAMED_TITLE_EVENT, MERGED_EVENT, PULL_REQUEST_REVIEW,
PULL_REQUEST_REVIEW_THREAD, REOPENED_EVENT, REVIEW_DISMISSED_EVENT, REVIEW_REQUEST_REMOVED_EVENT,
REVIEW_REQUESTED_EVENT, UNASSIGNED_EVENT, LABELED_EVENT, UNLABELED_EVENT, PULL_REQUEST_COMMIT,
READY_FOR_REVIEW_EVENT, CONVERT_TO_DRAFT_EVENT]) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes
{\n __typename\n ...timelineItems\n }\n }\n}\nquery {\nrepository(owner:
\"sourcegraph\", name: \"automation-testing\") {\npullRequests(baseRefName:
\"master\", headRefName: \"always-open-pr\", first: 1, states: OPEN) { \nnodes{
... pr }\n}\n}\n}","variables":null}'
body: '{"query":"\n\nfragment\nactor on Actor {\n avatarUrl\n login\n url\n}\n\nfragment\nrepo on Repository {\n id\n name\n owner {\n login\n }\n}\n\nfragment\npr on PullRequest {\n id\n title\n body\n state\n url\n number\n createdAt\n updatedAt\n headRefOid\n baseRefOid\n headRefName\n baseRefName\n reviewDecision\n isDraft\n author\n{\n ...actor\n }\n baseRepository {\n ...repo\n }\n headRepository\n{\n ...repo\n }\n}\nquery {\nrepository(owner:\n\"sourcegraph\", name: \"automation-testing\") {\npullRequests(baseRefName:\n\"master\", headRefName: \"always-open-pr\", first: 1, states: OPEN) { \nnodes{\n... pr }\n}\n}\n}","variables":null}'
form: {}
headers:
Accept:
- application/vnd.github.antiope-preview+json
Cache-Control:
- max-age=0
Content-Type:
- application/json; charset=utf-8
url: https://api.github.com/graphql
method: POST
response:
body: '{"data":{"repository":{"pullRequests":{"nodes":[{"id":"MDExOlB1bGxSZXF1ZXN0MzM5NzUyNDQy","title":"This
is a test PR that is always open (keep it open!)","body":"Feel free to ignore
this. This is a test PR that is always open and is sometimes updated.","state":"OPEN","url":"https://github.com/sourcegraph/automation-testing/pull/1","number":1,"createdAt":"2019-11-12T06:40:21Z","updatedAt":"2023-02-03T20:42:20Z","headRefOid":"37406e7dfa4466b80d1da183d6477aac16b1e58c","baseRefOid":"c75943274b322ffef2230df8f8049de84ddf12c1","headRefName":"always-open-pr","baseRefName":"master","reviewDecision":"REVIEW_REQUIRED","isDraft":false,"author":{"avatarUrl":"https://avatars.githubusercontent.com/u/1185253?u=35f048c505007991433b46c9c0616ccbcfbd4bff&v=4","login":"mrnugget","url":"https://github.com/mrnugget"},"baseRepository":{"id":"MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM=","name":"automation-testing","owner":{"login":"sourcegraph"}},"headRepository":{"id":"MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM=","name":"automation-testing","owner":{"login":"sourcegraph"}},"participants":{"nodes":[{"avatarUrl":"https://avatars.githubusercontent.com/u/1185253?u=35f048c505007991433b46c9c0616ccbcfbd4bff&v=4","login":"mrnugget","url":"https://github.com/mrnugget"},{"avatarUrl":"https://avatars.githubusercontent.com/u/19534377?v=4","login":"eseliger","url":"https://github.com/eseliger"}]},"labels":{"nodes":[]},"commits":{"nodes":[{"commit":{"oid":"37406e7dfa4466b80d1da183d6477aac16b1e58c","status":null,"checkSuites":{"nodes":[]},"committedDate":"2019-11-12T06:39:23Z"}}]},"timelineItems":{"pageInfo":{"hasNextPage":false,"endCursor":"Y3Vyc29yOnYyOpPPAAABbtTkb_gBqjI4NTY3MzIyNjI="},"nodes":[{"__typename":"PullRequestCommit","commit":{"oid":"9d04a0d8733dafbb5d75e594a9ec525c49dfc975","message":"Add
another file","messageHeadline":"Add another file","committedDate":"2019-11-12T06:38:55Z","pushedDate":"2019-11-12T06:39:00Z","url":"https://github.com/sourcegraph/automation-testing/commit/9d04a0d8733dafbb5d75e594a9ec525c49dfc975","committer":{"avatarUrl":"https://avatars.githubusercontent.com/u/1185253?v=4","email":"mrnugget@gmail.com","name":"Thorsten
Ball","user":{"avatarUrl":"https://avatars.githubusercontent.com/u/1185253?u=35f048c505007991433b46c9c0616ccbcfbd4bff&v=4","login":"mrnugget","url":"https://github.com/mrnugget"}}}},{"__typename":"PullRequestCommit","commit":{"oid":"37406e7dfa4466b80d1da183d6477aac16b1e58c","message":"Test
commit to always have a open PR","messageHeadline":"Test commit to always have
a open PR","committedDate":"2019-11-12T06:39:23Z","pushedDate":"2019-11-12T06:39:33Z","url":"https://github.com/sourcegraph/automation-testing/commit/37406e7dfa4466b80d1da183d6477aac16b1e58c","committer":{"avatarUrl":"https://avatars.githubusercontent.com/u/1185253?v=4","email":"mrnugget@gmail.com","name":"Thorsten
Ball","user":{"avatarUrl":"https://avatars.githubusercontent.com/u/1185253?u=35f048c505007991433b46c9c0616ccbcfbd4bff&v=4","login":"mrnugget","url":"https://github.com/mrnugget"}}}},{"__typename":"ClosedEvent","actor":{"avatarUrl":"https://avatars.githubusercontent.com/u/19534377?v=4","login":"eseliger","url":"https://github.com/eseliger"},"createdAt":"2019-12-04T23:28:16Z","url":"https://github.com/sourcegraph/automation-testing/pull/1#event-2855920542"},{"__typename":"ReopenedEvent","actor":{"avatarUrl":"https://avatars.githubusercontent.com/u/1185253?u=35f048c505007991433b46c9c0616ccbcfbd4bff&v=4","login":"mrnugget","url":"https://github.com/mrnugget"},"createdAt":"2019-12-05T07:09:21Z"},{"__typename":"RenamedTitleEvent","actor":{"avatarUrl":"https://avatars.githubusercontent.com/u/1185253?u=35f048c505007991433b46c9c0616ccbcfbd4bff&v=4","login":"mrnugget","url":"https://github.com/mrnugget"},"previousTitle":"This
is a test PR that is always open","currentTitle":"This is a test PR that is
always open (keep it open!)","createdAt":"2019-12-05T07:09:31Z"}]}}]}}}}'
body: '{ "data": { "repository": { "pullRequests": { "nodes": [ { "id": "MDExOlB1bGxSZXF1ZXN0MzM5NzUyNDQy", "title": "This is a test PR that is always open (keep it open!)", "body": "Feel free to ignore this. This is a test PR that is always open and is sometimes updated.", "state": "OPEN", "url": "https://github.com/sourcegraph/automation-testing/pull/1", "number": 1, "createdAt": "2019-11-12T06:40:21Z", "updatedAt": "2023-02-03T20:42:20Z", "headRefOid": "37406e7dfa4466b80d1da183d6477aac16b1e58c", "baseRefOid": "c75943274b322ffef2230df8f8049de84ddf12c1", "headRefName": "always-open-pr", "baseRefName": "master", "reviewDecision": "REVIEW_REQUIRED", "isDraft": false, "author": { "avatarUrl": "https://avatars3.githubusercontent.com/u/1185253?v=4", "login": "mrnugget", "url": "https://github.com/mrnugget" }, "baseRepository": { "id": "MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM=", "name": "automation-testing", "owner": { "login": "sourcegraph" } }, "headRepository": { "id": "MDEwOlJlcG9zaXRvcnkyMjExNDc1MTM=", "name": "automation-testing", "owner": { "login": "sourcegraph" } } } ] } } }}'
headers:
Access-Control-Allow-Origin:
- '*'
Access-Control-Expose-Headers:
- ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining,
X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes,
X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO,
X-GitHub-Request-Id, Deprecation, Sunset
X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval,
X-GitHub-Media-Type
Cache-Control:
- no-cache
Content-Security-Policy:
- default-src 'none'
Content-Type:
- application/json; charset=utf-8
Date:
- Fri, 23 Jun 2023 15:36:29 GMT
- Wed, 12 Feb 2020 10:50:06 GMT
Referrer-Policy:
- origin-when-cross-origin, strict-origin-when-cross-origin
Server:
- GitHub.com
Status:
- 200 OK
Strict-Transport-Security:
- max-age=31536000; includeSubdomains; preload
Vary:
- Accept-Encoding, Accept, X-Requested-With
- Accept-Encoding, Accept
X-Accepted-Oauth-Scopes:
- repo
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- deny
X-Github-Media-Type:
- github.v4; param=antiope-preview; format=json
- github.antiope-preview; format=json
X-Github-Request-Id:
- CE3E:5A99:111D5A6:22E2DDC:6495BBFC
X-Ratelimit-Resource:
- graphql
X-Ratelimit-Used:
- "127"
- 114D:40410:1F4E6D6:25E19A1:5E43D85D
X-Oauth-Scopes:
- read:org, repo
X-Xss-Protection:
- "0"
- 1; mode=block
status: 200 OK
code: 200
duration: ""

View File

@ -996,6 +996,54 @@ func (c *V4Client) GetOpenPullRequestByRefs(ctx context.Context, owner, name, ba
return &pr, nil
}
// GetOpenPullRequestByRefsReduced fetches the pull request associated with the supplied,
// but only the fields that are required to determine if the PR is open. It does not include
// the timeline items, participants, labels and commits (and returns empty lists instead).
func (c *V4Client) GetOpenPullRequestByRefsReduced(ctx context.Context, owner, name, baseRef, headRef string) (*PullRequest, error) {
version := c.determineGitHubVersion(ctx)
prFragment, err := pullRequestFragmentsSimple(version)
if err != nil {
return nil, err
}
var q strings.Builder
q.WriteString(prFragment)
q.WriteString("query {\n")
q.WriteString(fmt.Sprintf("repository(owner: %q, name: %q) {\n",
owner, name))
q.WriteString(fmt.Sprintf("pullRequests(baseRefName: %q, headRefName: %q, first: 1, states: OPEN) { \n",
abbreviateRef(baseRef), abbreviateRef(headRef),
))
q.WriteString("nodes{ ... pr }\n}\n}\n}")
var results struct {
Repository struct {
PullRequests struct {
Nodes []*struct {
PullRequest
}
}
}
}
err = c.requestGraphQL(ctx, q.String(), nil, &results)
if err != nil {
return nil, err
}
if len(results.Repository.PullRequests.Nodes) != 1 {
return nil, errors.Errorf("expected 1 pull request, got %d instead", len(results.Repository.PullRequests.Nodes))
}
node := results.Repository.PullRequests.Nodes[0]
pr := node.PullRequest
// Initialize lists that would otherwise be nil, to match downstream expectations to use the len function.
pr.Commits.Nodes = []CommitWithChecks{}
pr.Participants = []Actor{}
pr.TimelineItems = []TimelineItem{}
pr.Labels.Nodes = []Label{}
return &pr, nil
}
const createPullRequestCommentMutation = `
mutation CreatePullRequestComment($input: AddCommentInput!) {
addComment(input: $input) {
@ -1503,6 +1551,59 @@ fragment pr on PullRequest {
}
`
const pullRequestFragmentsFmtstrSimple = `
fragment actor on Actor {
avatarUrl
login
url
}
fragment repo on Repository {
id
name
owner {
login
}
}
fragment pr on PullRequest {
id
title
body
state
url
number
createdAt
updatedAt
headRefOid
baseRefOid
headRefName
baseRefName
reviewDecision
%s
author {
...actor
}
baseRepository {
...repo
}
headRepository {
...repo
}
}
`
func pullRequestFragmentsSimple(version *semver.Version) (string, error) {
if ghe220Semver.Check(version) {
// Don't ask for isDraft for ghe 2.20.
return fmt.Sprintf(pullRequestFragmentsFmtstrSimple, ""), nil
}
if ghe221PlusOrDotComSemver.Check(version) {
return fmt.Sprintf(pullRequestFragmentsFmtstrSimple, "isDraft"), nil
}
return "", errors.Errorf("unsupported version of GitHub: %s", version)
}
func pullRequestFragments(version *semver.Version) (string, error) {
timelineItemTypes, err := timelineItemTypes(version)
if err != nil {