-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add
--reviewers
to av pr create
- Loading branch information
Showing
6 changed files
with
201 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package actions | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"strings" | ||
|
||
"emperror.dev/errors" | ||
"github.com/aviator-co/av/internal/gh" | ||
"github.com/aviator-co/av/internal/utils/colors" | ||
"github.com/shurcooL/githubv4" | ||
) | ||
|
||
// AddPullRequestReviewers adds the given reviewers to the given pull request. | ||
// It accepts a list of reviewers, which can be either GitHub user logins or | ||
// team names in the format `@organization/team`. | ||
func AddPullRequestReviewers( | ||
ctx context.Context, | ||
client *gh.Client, | ||
prID githubv4.ID, | ||
reviewers []string, | ||
) error { | ||
_, _ = fmt.Fprint(os.Stderr, | ||
" - adding ", colors.UserInput(len(reviewers)), " reviewers to pull request\n", | ||
) | ||
|
||
// We need to map the given reviewers to GitHub node IDs. | ||
var reviewerIDs []githubv4.ID | ||
var teamIDs []githubv4.ID | ||
for _, reviewer := range reviewers { | ||
if ok, org, team := isTeamName(reviewer); ok { | ||
team, err := client.OrganizationTeam(ctx, org, team) | ||
if err != nil { | ||
return err | ||
} | ||
teamIDs = append(teamIDs, team.ID) | ||
} else { | ||
user, err := client.User(ctx, reviewer) | ||
if err != nil { | ||
return err | ||
} | ||
reviewerIDs = append(reviewerIDs, user.ID) | ||
} | ||
} | ||
|
||
if _, err := client.RequestReviews(ctx, githubv4.RequestReviewsInput{ | ||
PullRequestID: prID, | ||
UserIDs: &reviewerIDs, | ||
TeamIDs: &teamIDs, | ||
Union: gh.Ptr[githubv4.Boolean](true), | ||
}); err != nil { | ||
return errors.WrapIf(err, "requesting reviews") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func isTeamName(s string) (bool, string, string) { | ||
before, after, found := strings.Cut(s, "/") | ||
if !found || before == "" || after == "" { | ||
return false, "", "" | ||
} | ||
|
||
// It's common to specify team names as `@aviator-co/engineering`. We want | ||
// just the organization name (`aviator-co`) and team slug (`engineering`) | ||
// here, so strip the leading `@` if it exists. | ||
// This shouldn't cause any ambiguity since GitHub user login's can't | ||
// contain a slash character. | ||
if strings.HasPrefix(before, "@") { | ||
before = before[1:] | ||
} | ||
return true, before, after | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package gh | ||
|
||
import ( | ||
"context" | ||
|
||
"emperror.dev/errors" | ||
"github.com/shurcooL/githubv4" | ||
) | ||
|
||
type Team struct { | ||
ID githubv4.ID `graphql:"id"` | ||
Login string `graphql:"login"` | ||
} | ||
|
||
// OrganizationTeam returns information about the given team in the given organization. | ||
func (c *Client) OrganizationTeam( | ||
ctx context.Context, | ||
organizationLogin string, | ||
teamSlug string, | ||
) (*Team, error) { | ||
var query struct { | ||
Organization struct { | ||
ID githubv4.ID `graphql:"id"` | ||
Team Team `graphql:"team(slug: $teamSlug)"` | ||
} `graphql:"organization(login: $organizationLogin)"` | ||
} | ||
if err := c.query(ctx, &query, map[string]any{ | ||
"organizationLogin": githubv4.String(organizationLogin), | ||
"teamSlug": githubv4.String(teamSlug), | ||
}); err != nil { | ||
return nil, err | ||
} | ||
if query.Organization.ID == "" { | ||
return nil, errors.Errorf("GitHub organization %q not found", organizationLogin) | ||
} | ||
if query.Organization.Team.ID == "" { | ||
return nil, errors.Errorf( | ||
"GitHub team %q not found within organization %q", | ||
teamSlug, | ||
organizationLogin, | ||
) | ||
} | ||
return &query.Organization.Team, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package gh | ||
|
||
import ( | ||
"context" | ||
|
||
"emperror.dev/errors" | ||
"github.com/shurcooL/githubv4" | ||
) | ||
|
||
type User struct { | ||
ID githubv4.ID `graphql:"id"` | ||
Login string `graphql:"login"` | ||
} | ||
|
||
// User returns information about the given user. | ||
func (c *Client) User(ctx context.Context, login string) (*User, error) { | ||
var query struct { | ||
User User | ||
} | ||
if err := c.query(ctx, &query, nil); err != nil { | ||
return nil, err | ||
} | ||
if query.User.ID == "" { | ||
return nil, errors.Errorf("GitHub user %q not found", login) | ||
} | ||
return &query.User, nil | ||
} |