-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Correctly fetch Github PR status #160
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,91 @@ | ||||
package lib | ||||
|
||||
import ( | ||||
"context" | ||||
"fmt" | ||||
"strings" | ||||
"time" | ||||
|
||||
"github.com/google/go-github/v35/github" | ||||
"github.com/hasura/go-graphql-client" | ||||
) | ||||
|
||||
type GithubStatusContext struct { | ||||
Context string | ||||
TargetURL *string | ||||
} | ||||
|
||||
type GithubPRStatus struct { | ||||
// "error", "expected", "failure", "pending", or "success" | ||||
State string | ||||
|
||||
// Results from the Status Checks. Does not include results from the Checks API (incl. Github Actions) | ||||
Statuses []GithubStatusContext | ||||
} | ||||
|
||||
func GetGithubPRStatus(ctx context.Context, client *github.Client, repoLimiter *time.Ticker, repo Repo, prNumber int) (GithubPRStatus, error) { | ||||
p := NewProviderFromConfig(repo.ProviderConfig) | ||||
graphqlClient, err := p.GithubGraphqlClient(ctx, client) | ||||
if err != nil { | ||||
return GithubPRStatus{}, err | ||||
} | ||||
|
||||
// Fetch the rolled up status checks from github | ||||
// This includes both the Statuses API and Checks API | ||||
var query struct { | ||||
Repository struct { | ||||
PullRequest struct { | ||||
Commits struct { | ||||
Nodes []struct { | ||||
Commit struct { | ||||
StatusCheckRollup struct { | ||||
State string | ||||
Contexts struct { | ||||
Nodes []struct { | ||||
Typename string `graphql:"__typename"` | ||||
StatusContext struct { | ||||
Context string | ||||
TargetURL string | ||||
} `graphql:"... on StatusContext"` | ||||
} | ||||
} `graphql:"contexts(first: 10)"` | ||||
} | ||||
} | ||||
} | ||||
} `graphql:"commits(last: 1)"` | ||||
} `graphql:"pullRequest(number: $number)"` | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @benwaffle Is there a reason your query is going off of the Pull Request number? The PR's latest head SHA is already available from here: Line 26 in 724c03c
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no particular reason, using the PR number worked |
||||
} `graphql:"repository(owner: $owner, name: $name)"` | ||||
} | ||||
|
||||
<-repoLimiter.C | ||||
err = graphqlClient.Query(ctx, &query, map[string]interface{}{ | ||||
"owner": graphql.String(repo.Owner), | ||||
"name": graphql.String(repo.Name), | ||||
"number": graphql.Int(prNumber), | ||||
}) | ||||
if err != nil { | ||||
return GithubPRStatus{}, err | ||||
} | ||||
|
||||
commits := query.Repository.PullRequest.Commits.Nodes | ||||
if len(commits) != 1 { | ||||
return GithubPRStatus{}, fmt.Errorf("unexpected number of commits in PR") | ||||
} | ||||
|
||||
lastCommit := commits[0].Commit.StatusCheckRollup | ||||
var statuses []GithubStatusContext | ||||
|
||||
for _, status := range lastCommit.Contexts.Nodes { | ||||
if status.Typename == "StatusContext" { | ||||
statuses = append(statuses, GithubStatusContext{ | ||||
Context: status.StatusContext.Context, | ||||
TargetURL: &status.StatusContext.TargetURL, | ||||
}) | ||||
} | ||||
} | ||||
|
||||
return GithubPRStatus{ | ||||
State: strings.ToLower(lastCommit.State), | ||||
Statuses: statuses, | ||||
}, nil | ||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rgarcia @benwaffle I may be misunderstanding, but is the only reason why all the statuses are fetched in this function is to find the circle ci context?
microplane/push/push.go
Lines 146 to 160 in 724c03c
If so, it may be better to just query for that context specifically using the GraphQL API: https://docs.github.com/en/graphql/reference/objects#status
I've seen repositories with hundreds of statuses before, there's no guarantee that the first 10 here will capture the CircleCI context for every commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, just to get the circle ci build. Not sure where that's used, but I suppose there would be value in displaying other CI URLs (travis, jenkins, gh actions, etc...)