Skip to content

Commit c7f7bfc

Browse files
author
Nate Smith
authored
Merge pull request cli#787 from cli/issue-pr-create-metadata
Add flags to add additional metadata to `issue/pr create`
2 parents 5ba3baa + c682d90 commit c7f7bfc

File tree

8 files changed

+1146
-37
lines changed

8 files changed

+1146
-37
lines changed

api/queries_org.go

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package api
22

3-
import "fmt"
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/shurcooL/githubv4"
8+
)
49

510
// using API v3 here because the equivalent in GraphQL needs `read:org` scope
611
func resolveOrganization(client *Client, orgName string) (string, error) {
@@ -22,3 +27,84 @@ func resolveOrganizationTeam(client *Client, orgName, teamSlug string) (string,
2227
err := client.REST("GET", fmt.Sprintf("orgs/%s/teams/%s", orgName, teamSlug), nil, &response)
2328
return response.Organization.NodeID, response.NodeID, err
2429
}
30+
31+
// OrganizationProjects fetches all open projects for an organization
32+
func OrganizationProjects(client *Client, owner string) ([]RepoProject, error) {
33+
var query struct {
34+
Organization struct {
35+
Projects struct {
36+
Nodes []RepoProject
37+
PageInfo struct {
38+
HasNextPage bool
39+
EndCursor string
40+
}
41+
} `graphql:"projects(states: [OPEN], first: 100, orderBy: {field: NAME, direction: ASC}, after: $endCursor)"`
42+
} `graphql:"organization(login: $owner)"`
43+
}
44+
45+
variables := map[string]interface{}{
46+
"owner": githubv4.String(owner),
47+
"endCursor": (*githubv4.String)(nil),
48+
}
49+
50+
v4 := githubv4.NewClient(client.http)
51+
52+
var projects []RepoProject
53+
for {
54+
err := v4.Query(context.Background(), &query, variables)
55+
if err != nil {
56+
return nil, err
57+
}
58+
59+
projects = append(projects, query.Organization.Projects.Nodes...)
60+
if !query.Organization.Projects.PageInfo.HasNextPage {
61+
break
62+
}
63+
variables["endCursor"] = githubv4.String(query.Organization.Projects.PageInfo.EndCursor)
64+
}
65+
66+
return projects, nil
67+
}
68+
69+
type OrgTeam struct {
70+
ID string
71+
Slug string
72+
}
73+
74+
// OrganizationTeams fetches all the teams in an organization
75+
func OrganizationTeams(client *Client, owner string) ([]OrgTeam, error) {
76+
var query struct {
77+
Organization struct {
78+
Teams struct {
79+
Nodes []OrgTeam
80+
PageInfo struct {
81+
HasNextPage bool
82+
EndCursor string
83+
}
84+
} `graphql:"teams(first: 100, orderBy: {field: NAME, direction: ASC}, after: $endCursor)"`
85+
} `graphql:"organization(login: $owner)"`
86+
}
87+
88+
variables := map[string]interface{}{
89+
"owner": githubv4.String(owner),
90+
"endCursor": (*githubv4.String)(nil),
91+
}
92+
93+
v4 := githubv4.NewClient(client.http)
94+
95+
var teams []OrgTeam
96+
for {
97+
err := v4.Query(context.Background(), &query, variables)
98+
if err != nil {
99+
return nil, err
100+
}
101+
102+
teams = append(teams, query.Organization.Teams.Nodes...)
103+
if !query.Organization.Teams.PageInfo.HasNextPage {
104+
break
105+
}
106+
variables["endCursor"] = githubv4.String(query.Organization.Teams.PageInfo.EndCursor)
107+
}
108+
109+
return teams, nil
110+
}

api/queries_pr.go

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ func CreatePullRequest(client *Client, repo *Repository, params map[string]inter
586586
mutation CreatePullRequest($input: CreatePullRequestInput!) {
587587
createPullRequest(input: $input) {
588588
pullRequest {
589+
id
589590
url
590591
}
591592
}
@@ -595,7 +596,10 @@ func CreatePullRequest(client *Client, repo *Repository, params map[string]inter
595596
"repositoryId": repo.ID,
596597
}
597598
for key, val := range params {
598-
inputParams[key] = val
599+
switch key {
600+
case "title", "body", "draft", "baseRefName", "headRefName":
601+
inputParams[key] = val
602+
}
599603
}
600604
variables := map[string]interface{}{
601605
"input": inputParams,
@@ -611,8 +615,70 @@ func CreatePullRequest(client *Client, repo *Repository, params map[string]inter
611615
if err != nil {
612616
return nil, err
613617
}
618+
pr := &result.CreatePullRequest.PullRequest
619+
620+
// metadata parameters aren't currently available in `createPullRequest`,
621+
// but they are in `updatePullRequest`
622+
updateParams := make(map[string]interface{})
623+
for key, val := range params {
624+
switch key {
625+
case "assigneeIds", "labelIds", "projectIds", "milestoneId":
626+
if !isBlank(val) {
627+
updateParams[key] = val
628+
}
629+
}
630+
}
631+
if len(updateParams) > 0 {
632+
updateQuery := `
633+
mutation UpdatePullRequest($input: UpdatePullRequestInput!) {
634+
updatePullRequest(input: $input) { clientMutationId }
635+
}`
636+
updateParams["pullRequestId"] = pr.ID
637+
variables := map[string]interface{}{
638+
"input": updateParams,
639+
}
640+
err := client.GraphQL(updateQuery, variables, &result)
641+
if err != nil {
642+
return nil, err
643+
}
644+
}
614645

615-
return &result.CreatePullRequest.PullRequest, nil
646+
// reviewers are requested in yet another additional mutation
647+
reviewParams := make(map[string]interface{})
648+
if ids, ok := params["userReviewerIds"]; ok && !isBlank(ids) {
649+
reviewParams["userIds"] = ids
650+
}
651+
if ids, ok := params["teamReviewerIds"]; ok && !isBlank(ids) {
652+
reviewParams["teamIds"] = ids
653+
}
654+
655+
if len(reviewParams) > 0 {
656+
reviewQuery := `
657+
mutation RequestReviews($input: RequestReviewsInput!) {
658+
requestReviews(input: $input) { clientMutationId }
659+
}`
660+
reviewParams["pullRequestId"] = pr.ID
661+
variables := map[string]interface{}{
662+
"input": reviewParams,
663+
}
664+
err := client.GraphQL(reviewQuery, variables, &result)
665+
if err != nil {
666+
return nil, err
667+
}
668+
}
669+
670+
return pr, nil
671+
}
672+
673+
func isBlank(v interface{}) bool {
674+
switch vv := v.(type) {
675+
case string:
676+
return vv == ""
677+
case []string:
678+
return len(vv) == 0
679+
default:
680+
return true
681+
}
616682
}
617683

618684
func AddReview(client *Client, pr *PullRequest, input *PullRequestReviewInput) error {

0 commit comments

Comments
 (0)