244 lines
5 KiB
Go
244 lines
5 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
type PullRequestsPayload struct {
|
|
ViewerCreated []PullRequest
|
|
ReviewRequested []PullRequest
|
|
CurrentPR *PullRequest
|
|
}
|
|
|
|
type PullRequest struct {
|
|
Number int
|
|
Title string
|
|
URL string
|
|
HeadRefName string
|
|
}
|
|
|
|
type Repo interface {
|
|
RepoName() string
|
|
RepoOwner() string
|
|
}
|
|
|
|
func GitHubRepoId(client *Client, ghRepo Repo) (string, error) {
|
|
owner := ghRepo.RepoOwner()
|
|
repo := ghRepo.RepoName()
|
|
|
|
query := `
|
|
query FindRepoID($owner:String!, $name:String!) {
|
|
repository(owner:$owner, name:$name) {
|
|
id
|
|
}
|
|
}`
|
|
variables := map[string]interface{}{
|
|
"owner": owner,
|
|
"name": repo,
|
|
}
|
|
|
|
result := struct {
|
|
Repository struct {
|
|
Id string
|
|
}
|
|
}{}
|
|
err := client.GraphQL(query, variables, &result)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to determine GH repo ID: %s", err)
|
|
}
|
|
|
|
return result.Repository.Id, nil
|
|
}
|
|
|
|
func PullRequests(client *Client, ghRepo Repo, currentBranch, currentUsername string) (*PullRequestsPayload, error) {
|
|
type edges struct {
|
|
Edges []struct {
|
|
Node PullRequest
|
|
}
|
|
PageInfo struct {
|
|
HasNextPage bool
|
|
EndCursor string
|
|
}
|
|
}
|
|
|
|
type response struct {
|
|
Repository struct {
|
|
PullRequests edges
|
|
}
|
|
ViewerCreated edges
|
|
ReviewRequested edges
|
|
}
|
|
|
|
query := `
|
|
fragment pr on PullRequest {
|
|
number
|
|
title
|
|
url
|
|
headRefName
|
|
}
|
|
|
|
query($owner: String!, $repo: String!, $headRefName: String!, $viewerQuery: String!, $reviewerQuery: String!, $per_page: Int = 10) {
|
|
repository(owner: $owner, name: $repo) {
|
|
pullRequests(headRefName: $headRefName, states: OPEN, first: 1) {
|
|
edges {
|
|
node {
|
|
...pr
|
|
}
|
|
}
|
|
}
|
|
}
|
|
viewerCreated: search(query: $viewerQuery, type: ISSUE, first: $per_page) {
|
|
edges {
|
|
node {
|
|
...pr
|
|
}
|
|
}
|
|
pageInfo {
|
|
hasNextPage
|
|
}
|
|
}
|
|
reviewRequested: search(query: $reviewerQuery, type: ISSUE, first: $per_page) {
|
|
edges {
|
|
node {
|
|
...pr
|
|
}
|
|
}
|
|
pageInfo {
|
|
hasNextPage
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
owner := ghRepo.RepoOwner()
|
|
repo := ghRepo.RepoName()
|
|
|
|
viewerQuery := fmt.Sprintf("repo:%s/%s state:open is:pr author:%s", owner, repo, currentUsername)
|
|
reviewerQuery := fmt.Sprintf("repo:%s/%s state:open review-requested:%s", owner, repo, currentUsername)
|
|
|
|
variables := map[string]interface{}{
|
|
"viewerQuery": viewerQuery,
|
|
"reviewerQuery": reviewerQuery,
|
|
"owner": owner,
|
|
"repo": repo,
|
|
"headRefName": currentBranch,
|
|
}
|
|
|
|
var resp response
|
|
err := client.GraphQL(query, variables, &resp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var viewerCreated []PullRequest
|
|
for _, edge := range resp.ViewerCreated.Edges {
|
|
viewerCreated = append(viewerCreated, edge.Node)
|
|
}
|
|
|
|
var reviewRequested []PullRequest
|
|
for _, edge := range resp.ReviewRequested.Edges {
|
|
reviewRequested = append(reviewRequested, edge.Node)
|
|
}
|
|
|
|
var currentPR *PullRequest
|
|
for _, edge := range resp.Repository.PullRequests.Edges {
|
|
currentPR = &edge.Node
|
|
}
|
|
|
|
payload := PullRequestsPayload{
|
|
viewerCreated,
|
|
reviewRequested,
|
|
currentPR,
|
|
}
|
|
|
|
return &payload, nil
|
|
}
|
|
|
|
func PullRequestsForBranch(client *Client, ghRepo Repo, branch string) ([]PullRequest, error) {
|
|
type response struct {
|
|
Repository struct {
|
|
PullRequests struct {
|
|
Edges []struct {
|
|
Node PullRequest
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
query := `
|
|
query($owner: String!, $repo: String!, $headRefName: String!) {
|
|
repository(owner: $owner, name: $repo) {
|
|
pullRequests(headRefName: $headRefName, states: OPEN, first: 1) {
|
|
edges {
|
|
node {
|
|
number
|
|
title
|
|
url
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}`
|
|
|
|
variables := map[string]interface{}{
|
|
"owner": ghRepo.RepoOwner(),
|
|
"repo": ghRepo.RepoName(),
|
|
"headRefName": branch,
|
|
}
|
|
|
|
var resp response
|
|
err := client.GraphQL(query, variables, &resp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
prs := []PullRequest{}
|
|
for _, edge := range resp.Repository.PullRequests.Edges {
|
|
prs = append(prs, edge.Node)
|
|
}
|
|
|
|
return prs, nil
|
|
}
|
|
|
|
func CreatePullRequest(client *Client, ghRepo Repo, title string, body string, draft bool, base string, head string) (string, error) {
|
|
repoId, err := GitHubRepoId(client, ghRepo)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if repoId == "" {
|
|
return "", fmt.Errorf("could not determine GH repo ID")
|
|
}
|
|
|
|
query := `
|
|
mutation CreatePullRequest($input: CreatePullRequestInput!) {
|
|
createPullRequest(input: $input) {
|
|
pullRequest {
|
|
url
|
|
}
|
|
}
|
|
}`
|
|
|
|
variables := map[string]interface{}{
|
|
"input": map[string]interface{}{
|
|
"repositoryId": repoId,
|
|
"baseRefName": base,
|
|
"headRefName": head,
|
|
"title": title,
|
|
"body": body,
|
|
"draft": draft,
|
|
},
|
|
}
|
|
|
|
result := struct {
|
|
CreatePullRequest struct {
|
|
PullRequest PullRequest
|
|
}
|
|
}{}
|
|
|
|
err = client.GraphQL(query, variables, &result)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return result.CreatePullRequest.PullRequest.URL, nil
|
|
}
|