Skip to content

Commit 4318dbb

Browse files
committed
feat: add support for assignees
1 parent 070d1a6 commit 4318dbb

File tree

9 files changed

+46
-0
lines changed

9 files changed

+46
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ echo "gruntwork-io/terragrunt gruntwork-io/terratest" | git-xargs \
442442
| `--no-skip-ci` | By default, git-xargs will prepend \"[skip ci]\" to its commit messages to prevent large git-xargs jobs from creating expensive CI jobs excessively. If you pass the `--no-skip-ci` flag, then git-xargs will not prepend \"[skip ci]\". Default: false, meaning that \"[skip ci]\" will be prepended to commit messages. | Bool | No |
443443
| `--reviewers` | An optional slice of GitHub usernames, separated by commas, to request reviews from after a pull request is successfully opened. Default: empty slice, meaning that no reviewers will be requested. | String | No |
444444
| `--team-reviewers` | An optional slice of GitHub team names, separated by commas, to request reviews from after a pull request is successfully opened. Default: empty slice, meaning that no team reviewers will be requested. IMPORTANT: Please read and understand [the GitHub restrictions](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/requesting-a-pull-request-review) on this functionality before using it! Only certain GitHub organizations / payment plans support this functionality. | String | No |
445+
| `--assignees` | An optional slice of GitHub usernames, separated by commas, to assign to the pull request after it is successfully opened. Default: empty slice, meaning that no assignees will be assigned. | String | No |
445446
| `--keep-cloned-repositories` | By default, git-xargs will delete the repositories it clones to your temporary file directory once it has completed processing that repo, to save space on your machine. If you wish to retain the local repositories, pass this flag. | Bool | No |
446447
## Best practices, tips and tricks
447448

auth/auth.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ type githubPullRequestService interface {
1818
RequestReviewers(ctx context.Context, owner, repo string, number int, reviewers github.ReviewersRequest) (*github.PullRequest, *github.Response, error)
1919
}
2020

21+
// The go-github package satisfies this Issues service's interface in production
22+
type githubIssuesService interface {
23+
AddAssignees(ctx context.Context, owner, repo string, number int, assignees []string) (*github.Issue, *github.Response, error)
24+
}
25+
2126
// The go-github package satisfies this Repositories service's interface in production
2227
type githubRepositoriesService interface {
2328
Get(ctx context.Context, owner, repo string) (*github.Repository, *github.Response, error)
@@ -31,12 +36,14 @@ type githubRepositoriesService interface {
3136
// without actually making API calls to GitHub when running tests
3237
type GithubClient struct {
3338
PullRequests githubPullRequestService
39+
Issues githubIssuesService
3440
Repositories githubRepositoriesService
3541
}
3642

3743
func NewClient(client *github.Client) GithubClient {
3844
return GithubClient{
3945
PullRequests: client.PullRequests,
46+
Issues: client.Issues,
4047
Repositories: client.Repositories,
4148
}
4249
}

cmd/git-xargs.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ func parseGitXargsConfig(c *cli.Context) (*config.GitXargsConfig, error) {
3434
config.PullRequestDescription = c.String("pull-request-description")
3535
config.Reviewers = c.StringSlice("reviewers")
3636
config.TeamReviewers = c.StringSlice("team-reviewers")
37+
config.Assignees = c.StringSlice("assignees")
3738
config.ReposFile = c.String("repos")
3839
config.GithubOrg = c.String("github-org")
3940
config.RepoSlice = c.StringSlice("repo")

common/common.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const (
1717
PullRequestDescriptionFlagName = "pull-request-description"
1818
PullRequestReviewersFlagName = "reviewers"
1919
PullRequestTeamReviewersFlagName = "team-reviewers"
20+
PullRequestAssigneesFlagName = "assignees"
2021
SecondsToWaitBetweenPrsFlagName = "seconds-between-prs"
2122
DefaultCommitMessage = "git-xargs programmatic commit"
2223
DefaultPullRequestTitle = "git-xargs programmatic pull request"
@@ -91,6 +92,10 @@ var (
9192
Name: PullRequestTeamReviewersFlagName,
9293
Usage: "A list of GitHub team names to request reviews from",
9394
}
95+
GenericPullRequestAssigneesFlag = cli.StringSliceFlag{
96+
Name: PullRequestAssigneesFlagName,
97+
Usage: "A list of GitHub usernames to request as the assignees",
98+
}
9499
GenericSecondsToWaitFlag = cli.IntFlag{
95100
Name: SecondsToWaitBetweenPrsFlagName,
96101
Usage: "The number of seconds to sleep between pull requests in order to respect GitHub API rate limits. Increase this number if you are being rate limited regularly. Defaults to 12 seconds.",

config/config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type GitXargsConfig struct {
2626
PullRequestDescription string
2727
Reviewers []string
2828
TeamReviewers []string
29+
Assignees []string
2930
ReposFile string
3031
GithubOrg string
3132
RepoSlice []string
@@ -58,6 +59,7 @@ func NewGitXargsConfig() *GitXargsConfig {
5859
PullRequestDescription: common.DefaultPullRequestDescription,
5960
Reviewers: []string{},
6061
TeamReviewers: []string{},
62+
Assignees: []string{},
6163
ReposFile: "",
6264
GithubOrg: "",
6365
RepoSlice: []string{},
@@ -91,3 +93,7 @@ func NewGitXargsTestConfig() *GitXargsConfig {
9193
func (c *GitXargsConfig) HasReviewers() bool {
9294
return len(c.Reviewers) > 0 || len(c.TeamReviewers) > 0
9395
}
96+
97+
func (c *GitXargsConfig) HasAssignees() bool {
98+
return len(c.Assignees) > 0
99+
}

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ func setupApp() *cli.App {
7373
common.GenericPullRequestDescriptionFlag,
7474
common.GenericPullRequestReviewersFlag,
7575
common.GenericPullRequestTeamReviewersFlag,
76+
common.GenericPullRequestAssigneesFlag,
7677
common.GenericSecondsToWaitFlag,
7778
common.GenericMaxPullRequestRetriesFlag,
7879
common.GenericSecondsToWaitWhenRateLimitedFlag,

mocks/mocks.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ func (m mockGithubPullRequestService) RequestReviewers(ctx context.Context, owne
7777
return m.PullRequest, m.Response, nil
7878
}
7979

80+
// This mocks the Issue service in go-github that is used in production to call the associated GitHub endpoint
81+
type mockgithubIssuesService struct {
82+
Issue *github.Issue
83+
Response *github.Response
84+
}
85+
86+
func (m mockgithubIssuesService) AddAssignees(ctx context.Context, owner, repo string, number int, assignees []string) (*github.Issue, *github.Response, error) {
87+
return m.Issue, m.Response, nil
88+
}
89+
8090
// This mocks the Repositories service in go-github that is used in production to call the associated GitHub endpoint
8191
type mockGithubRepositoriesService struct {
8292
Repository *github.Repository
@@ -126,6 +136,10 @@ func ConfigureMockGithubClient() auth.GithubClient {
126136
},
127137
Response: &github.Response{},
128138
}
139+
client.Issues = mockgithubIssuesService{
140+
Issue: &github.Issue{},
141+
Response: &github.Response{},
142+
}
129143

130144
return client
131145
}

repository/repo-operations.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,14 @@ func openPullRequest(config *config.GitXargsConfig, pr types.OpenPrRequest) erro
594594

595595
}
596596

597+
if config.HasAssignees() {
598+
assignees := config.Assignees
599+
_, _, assigneeErr := config.GithubClient.Issues.AddAssignees(context.Background(), *pr.Repo.GetOwner().Login, pr.Repo.GetName(), githubPR.GetNumber(), assignees)
600+
if assigneeErr != nil {
601+
config.Stats.TrackSingle(stats.AddAssigneesErr, pr.Repo)
602+
}
603+
}
604+
597605
if config.Draft {
598606
config.Stats.TrackDraftPullRequest(pr.Repo.GetName(), githubPR.GetHTMLURL())
599607
} else {

stats/stats.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ const (
7878
PRFailedAfterMaximumRetriesErr types.Event = "pr-failed-after-maximum-retries"
7979
// RequestReviewersErr denotes a repo whose follow up request to add reviewers to the opened pull request failed
8080
RequestReviewersErr types.Event = "request-reviewers-error"
81+
// AddAssigneesErr denotes a repo whose follow up request to add assignees to the opened pull request failed
82+
AddAssigneesErr types.Event = "add-assignees-error"
8183
)
8284

8385
var allEvents = []types.AnnotatedEvent{
@@ -112,6 +114,7 @@ var allEvents = []types.AnnotatedEvent{
112114
{Event: PRFailedDueToRateLimitsErr, Description: "Repos whose initial Pull Request failed to be created due to GitHub rate limits"},
113115
{Event: PRFailedAfterMaximumRetriesErr, Description: "Repos whose Pull Request failed to be created after the maximum number of retries"},
114116
{Event: RequestReviewersErr, Description: "Repos whose request to add reviewers to the opened pull request failed"},
117+
{Event: AddAssigneesErr, Description: "Repos whose request to add assignees to the opened pull request failed"},
115118
}
116119

117120
// RunStats will be a stats-tracker class that keeps score of which repos were touched, which were considered for update, which had branches made, PRs made, which were missing workflows or contexts, or had out of date workflows syntax values, etc

0 commit comments

Comments
 (0)