Avoid querying statusCheckRollup or reviewDecision on unsupported GHE

We first ask the GHE server for whether it supports these fields.
This commit is contained in:
Mislav Marohnić 2020-09-30 19:04:09 +02:00
parent 091d550cde
commit bed9d11f7a

View file

@ -241,6 +241,52 @@ func (c Client) PullRequestDiff(baseRepo ghrepo.Interface, prNumber int) (io.Rea
return resp.Body, nil return resp.Body, nil
} }
type pullRequestFeature struct {
HasReviewDecision bool
HasStatusCheckRollup bool
}
func determinePullRequestFeatures(httpClient *http.Client, hostname string) (prFeatures pullRequestFeature, err error) {
if !ghinstance.IsEnterprise(hostname) {
prFeatures.HasReviewDecision = true
prFeatures.HasStatusCheckRollup = true
return
}
var featureDetection struct {
PullRequest struct {
Fields []struct {
Name string
} `graphql:"fields(includeDeprecated: true)"`
} `graphql:"PullRequest: __type(name: \"PullRequest\")"`
Commit struct {
Fields []struct {
Name string
} `graphql:"fields(includeDeprecated: true)"`
} `graphql:"Commit: __type(name: \"Commit\")"`
}
v4 := graphQLClient(httpClient, hostname)
err = v4.Query(context.Background(), &featureDetection, nil)
if err != nil {
return
}
for _, field := range featureDetection.PullRequest.Fields {
switch field.Name {
case "reviewDecision":
prFeatures.HasReviewDecision = true
}
}
for _, field := range featureDetection.Commit.Fields {
switch field.Name {
case "statusCheckRollup":
prFeatures.HasStatusCheckRollup = true
}
}
return
}
func PullRequests(client *Client, repo ghrepo.Interface, currentPRNumber int, currentPRHeadRef, currentUsername string) (*PullRequestsPayload, error) { func PullRequests(client *Client, repo ghrepo.Interface, currentPRNumber int, currentPRHeadRef, currentUsername string) (*PullRequestsPayload, error) {
type edges struct { type edges struct {
TotalCount int TotalCount int
@ -261,18 +307,19 @@ func PullRequests(client *Client, repo ghrepo.Interface, currentPRNumber int, cu
ReviewRequested edges ReviewRequested edges
} }
fragments := ` prFeatures, err := determinePullRequestFeatures(client.http, repo.RepoHost())
fragment pr on PullRequest { if err != nil {
number return nil, err
title }
state
url var reviewsFragment string
headRefName if prFeatures.HasReviewDecision {
headRepositoryOwner { reviewsFragment = "reviewDecision"
login }
}
isCrossRepository var statusesFragment string
isDraft if prFeatures.HasStatusCheckRollup {
statusesFragment = `
commits(last: 1) { commits(last: 1) {
nodes { nodes {
commit { commit {
@ -292,12 +339,28 @@ func PullRequests(client *Client, repo ghrepo.Interface, currentPRNumber int, cu
} }
} }
} }
`
}
fragments := fmt.Sprintf(`
fragment pr on PullRequest {
number
title
state
url
headRefName
headRepositoryOwner {
login
}
isCrossRepository
isDraft
%s
} }
fragment prWithReviews on PullRequest { fragment prWithReviews on PullRequest {
...pr ...pr
reviewDecision %s
} }
` `, statusesFragment, reviewsFragment)
queryPrefix := ` queryPrefix := `
query PullRequestStatus($owner: String!, $repo: String!, $headRefName: String!, $viewerQuery: String!, $reviewerQuery: String!, $per_page: Int = 10) { query PullRequestStatus($owner: String!, $repo: String!, $headRefName: String!, $viewerQuery: String!, $reviewerQuery: String!, $per_page: Int = 10) {
@ -363,7 +426,7 @@ func PullRequests(client *Client, repo ghrepo.Interface, currentPRNumber int, cu
} }
var resp response var resp response
err := client.GraphQL(repo.RepoHost(), query, variables, &resp) err = client.GraphQL(repo.RepoHost(), query, variables, &resp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -404,6 +467,44 @@ func PullRequests(client *Client, repo ghrepo.Interface, currentPRNumber int, cu
return &payload, nil return &payload, nil
} }
func prCommitsFragment(httpClient *http.Client, hostname string) (string, error) {
if prFeatures, err := determinePullRequestFeatures(httpClient, hostname); err != nil {
return "", err
} else if !prFeatures.HasStatusCheckRollup {
return "", nil
}
return `
commits(last: 1) {
totalCount
nodes {
commit {
oid
statusCheckRollup {
contexts(last: 100) {
nodes {
...on StatusContext {
context
state
targetUrl
}
...on CheckRun {
name
status
conclusion
startedAt
completedAt
detailsUrl
}
}
}
}
}
}
}
`, nil
}
func PullRequestByNumber(client *Client, repo ghrepo.Interface, number int) (*PullRequest, error) { func PullRequestByNumber(client *Client, repo ghrepo.Interface, number int) (*PullRequest, error) {
type response struct { type response struct {
Repository struct { Repository struct {
@ -411,6 +512,11 @@ func PullRequestByNumber(client *Client, repo ghrepo.Interface, number int) (*Pu
} }
} }
statusesFragment, err := prCommitsFragment(client.http, repo.RepoHost())
if err != nil {
return nil, err
}
query := ` query := `
query PullRequestByNumber($owner: String!, $repo: String!, $pr_number: Int!) { query PullRequestByNumber($owner: String!, $repo: String!, $pr_number: Int!) {
repository(owner: $owner, name: $repo) { repository(owner: $owner, name: $repo) {
@ -426,33 +532,7 @@ func PullRequestByNumber(client *Client, repo ghrepo.Interface, number int) (*Pu
author { author {
login login
} }
commits(last: 1) { ` + statusesFragment + `
totalCount
nodes {
commit {
oid
statusCheckRollup {
contexts(last: 100) {
nodes {
...on StatusContext {
context
state
targetUrl
}
...on CheckRun {
name
status
conclusion
startedAt
completedAt
detailsUrl
}
}
}
}
}
}
}
baseRefName baseRefName
headRefName headRefName
headRepositoryOwner { headRepositoryOwner {
@ -524,7 +604,7 @@ func PullRequestByNumber(client *Client, repo ghrepo.Interface, number int) (*Pu
} }
var resp response var resp response
err := client.GraphQL(repo.RepoHost(), query, variables, &resp) err = client.GraphQL(repo.RepoHost(), query, variables, &resp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -542,6 +622,11 @@ func PullRequestForBranch(client *Client, repo ghrepo.Interface, baseBranch, hea
} }
} }
statusesFragment, err := prCommitsFragment(client.http, repo.RepoHost())
if err != nil {
return nil, err
}
query := ` query := `
query PullRequestForBranch($owner: String!, $repo: String!, $headRefName: String!) { query PullRequestForBranch($owner: String!, $repo: String!, $headRefName: String!) {
repository(owner: $owner, name: $repo) { repository(owner: $owner, name: $repo) {
@ -556,33 +641,7 @@ func PullRequestForBranch(client *Client, repo ghrepo.Interface, baseBranch, hea
author { author {
login login
} }
commits(last: 1) { ` + statusesFragment + `
totalCount
nodes {
commit {
oid
statusCheckRollup {
contexts(last: 100) {
nodes {
...on StatusContext {
context
state
targetUrl
}
...on CheckRun {
name
status
conclusion
startedAt
completedAt
detailsUrl
}
}
}
}
}
}
}
url url
baseRefName baseRefName
headRefName headRefName
@ -661,7 +720,7 @@ func PullRequestForBranch(client *Client, repo ghrepo.Interface, baseBranch, hea
} }
var resp response var resp response
err := client.GraphQL(repo.RepoHost(), query, variables, &resp) err = client.GraphQL(repo.RepoHost(), query, variables, &resp)
if err != nil { if err != nil {
return nil, err return nil, err
} }