Skip to content

Commit

Permalink
Attempt to add a review before merging
Browse files Browse the repository at this point in the history
  • Loading branch information
jvansanten committed Nov 21, 2024
1 parent e95cc0f commit 6aa22b7
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 32 deletions.
23 changes: 13 additions & 10 deletions pkg/cli/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,18 +137,21 @@ func NewCommand() (c *cobra.Command) {
}

selectedIds := promptAndFormat(pullRequestsArray, table)
for i, id := range selectedIds {
for i, pr := range selectedIds {

if approveOnly {
gitclient.ApprovePullRequest(ghClient, ctx, id, skip)
gitclient.ApprovePullRequest(ghClient, ctx, pr, skip)
} else if closePr {
gitclient.ClosePullRequest(ghClient, ctx, id, skip)
gitclient.ClosePullRequest(ghClient, ctx, pr, skip)
} else {
// delay between merges to allow other active PRs to get synced
if i > 0 {
time.Sleep(time.Duration(delay) * time.Second)
}
gitclient.MergePullRequest(ghClient, ctx, id, &mergeMethod, skip)
if pr.NeedsReview {
gitclient.ApprovePullRequest(ghClient, ctx, pr, skip)
}
gitclient.MergePullRequest(ghClient, ctx, pr, &mergeMethod, skip)

}
}
Expand All @@ -158,7 +161,7 @@ func NewCommand() (c *cobra.Command) {
return
}

func promptAndFormat(pullRequests []*gitclient.PullRequest, table *tablewriter.Table) []githubv4.ID {
func promptAndFormat(pullRequests []*gitclient.PullRequest, table *tablewriter.Table) (selectedPullRequests []*gitclient.PullRequest) {
prIds := []string{}

for _, pr := range pullRequests {
Expand All @@ -175,16 +178,16 @@ func promptAndFormat(pullRequests []*gitclient.PullRequest, table *tablewriter.T

prompt, selectedIds := selectPrIds(prIds)
survey.AskOne(prompt, &selectedIds)
indices := []githubv4.ID{}
for _, id := range selectedIds {
for i, prId := range prIds {
selectedPullRequests = make([]*gitclient.PullRequest, len(selectedIds))
for idIndex, id := range selectedIds {
for prIndex, prId := range prIds {
if id == prId {
indices = append(indices, pullRequests[i].ID)
selectedPullRequests[idIndex] = pullRequests[prIndex]
break
}
}
}
return indices
return
}

func initTable() (table *tablewriter.Table) {
Expand Down
60 changes: 38 additions & 22 deletions pkg/gitclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type PullRequest struct {
CreatedAt time.Time
ID githubv4.ID
StatusRollup string
NeedsReview bool
}

func Client(githubToken string, ctx context.Context, isEnterprise bool) (client *github.Client) {
Expand Down Expand Up @@ -88,6 +89,18 @@ type pullRequests struct {
CreatedAt githubv4.DateTime
ID githubv4.ID
Commits commits `graphql:"commits(last:1)"`
// NB: this only works for classic branch protection rules. Repository
// rulesets don't appear to be visible in the API
BaseRef struct {
BranchProtectionRule struct {
RequiredApprovingReviewCount githubv4.Int
}
}
Reviews struct {
Nodes []struct {
AuthorCanPushToRepository githubv4.Boolean
}
} `graphql:"reviews(first: 100, states: [APPROVED])"`
}
}

Expand Down Expand Up @@ -183,6 +196,12 @@ func GetPullRequests(client *githubv4.Client, ctx context.Context, owner string,
pullRequests := []*PullRequest{}
for _, repo := range repos {
for _, pr := range repo.PullRequests.Nodes {
reviews := 0
for _, review := range pr.Reviews.Nodes {
if review.AuthorCanPushToRepository {
reviews++
}
}
pullRequest := &PullRequest{
RepositoryOwner: string(repo.Owner.Login),
RepositoryName: string(repo.Name),
Expand All @@ -192,6 +211,7 @@ func GetPullRequests(client *githubv4.Client, ctx context.Context, owner string,
CreatedAt: pr.CreatedAt.Time,
ID: pr.ID,
StatusRollup: string(pr.Commits.Nodes[0].Commit.StatusCheckRollup.State),
NeedsReview: reviews < int(pr.BaseRef.BranchProtectionRule.RequiredApprovingReviewCount),
}

pullRequests = append(pullRequests, pullRequest)
Expand All @@ -201,56 +221,51 @@ func GetPullRequests(client *githubv4.Client, ctx context.Context, owner string,
return pullRequests, nil
}

func ApprovePullRequest(ghClient *githubv4.Client, ctx context.Context, prId githubv4.ID, skip bool) {
func ApprovePullRequest(ghClient *githubv4.Client, ctx context.Context, pr *PullRequest, skip bool) {

commitMessage := ctx.Value("message").(githubv4.String)
commitMessage := githubv4.String(DefaultApproveMsg())
event := githubv4.PullRequestReviewEventApprove

input := githubv4.AddPullRequestReviewInput{
PullRequestID: prId,
PullRequestID: pr.ID,
Body: &commitMessage,
Event: &event,
}

var m struct {
AddPullRequestReview struct {
PullRequest struct {
Number githubv4.Int
Repository struct {
NameWithOwner githubv4.String
}
}
PullRequestReview struct {
State githubv4.String
State githubv4.PullRequestReviewState
}
} `graphql:"addPullRequestReview(input: $input)"`
}

err := ghClient.Mutate(ctx, &m, input, nil)
if err != nil && !skip {
log.Printf("Could not approve pull request %v, did you try to approve your on pull request? - %v\n", prId, err)
log.Printf("Could not approve pull request %s/%s#%d - %v\n", pr.RepositoryOwner, pr.RepositoryName, pr.Number, err)
}

review := m.AddPullRequestReview.PullRequestReview

if err != nil && skip {
fmt.Printf("Could not approve pull request, skipping.")
} else {
fmt.Printf("PR %v: %v\n", prId, review.State)
fmt.Printf("%s/%s#%d: %v\n", pr.RepositoryOwner, pr.RepositoryName, pr.Number, review.State)
}
}

func MergePullRequest(ghClient *githubv4.Client, ctx context.Context, prId githubv4.ID, mergeMethod *githubv4.PullRequestMergeMethod, skip bool) {
func MergePullRequest(ghClient *githubv4.Client, ctx context.Context, pr *PullRequest, mergeMethod *githubv4.PullRequestMergeMethod, skip bool) {

input := githubv4.MergePullRequestInput{
PullRequestID: prId,
PullRequestID: pr.ID,
MergeMethod: mergeMethod,
}

var m struct {
MergePullRequest struct {
PullRequest struct {
Merged bool
State githubv4.PullRequestState
Number githubv4.Int
Repository struct {
NameWithOwner githubv4.String
Expand All @@ -261,24 +276,25 @@ func MergePullRequest(ghClient *githubv4.Client, ctx context.Context, prId githu

err := ghClient.Mutate(ctx, &m, input, nil)
if err != nil {
log.Printf("Could not merge PR %s, skipping: %v\n", prId, err)
log.Printf("Could not merge %s/%s#%d - %v\n", pr.RepositoryOwner, pr.RepositoryName, pr.Number, err)
}

pr := m.MergePullRequest.PullRequest
prOut := m.MergePullRequest.PullRequest
fmt.Printf("%s/%s#%d merged: %v\n", pr.RepositoryOwner, pr.RepositoryName, pr.Number, prOut.State)

fmt.Printf("PR %s#%d merged: %v\n", pr.Repository.NameWithOwner, pr.Number, pr.Merged)
}

func ClosePullRequest(ghClient *githubv4.Client, ctx context.Context, prId githubv4.ID, skip bool) {
func ClosePullRequest(ghClient *githubv4.Client, ctx context.Context, pr *PullRequest, skip bool) {

input := githubv4.ClosePullRequestInput{
PullRequestID: prId,
PullRequestID: pr.ID,
}

var m struct {
ClosePullRequest struct {
PullRequest struct {
Closed bool
State githubv4.PullRequestState
Number githubv4.Int
Repository struct {
NameWithOwner githubv4.String
Expand All @@ -289,12 +305,12 @@ func ClosePullRequest(ghClient *githubv4.Client, ctx context.Context, prId githu

err := ghClient.Mutate(ctx, &m, input, nil)
if err != nil {
log.Printf("Could not close PR %s, skipping: %v\n", prId, err)
log.Printf("Could not close %s/%s#%d - %v\n", pr.RepositoryOwner, pr.RepositoryName, pr.Number, err)
}

pr := m.ClosePullRequest.PullRequest
prOut := m.ClosePullRequest.PullRequest

fmt.Printf("PR %s#%d closed: %v\n", pr.Repository.NameWithOwner, pr.Number, pr.Closed)
fmt.Printf("%s/%s#%d merged: %v\n", pr.RepositoryOwner, pr.RepositoryName, pr.Number, prOut.State)

}

Expand Down

0 comments on commit 6aa22b7

Please sign in to comment.