diff --git a/cmd/root.go b/cmd/root.go index e12a607..ea739e9 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -60,6 +60,9 @@ func initConfig() { // If a config file is found, read it in. if err := viper.ReadInConfig(); err == nil { - fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) + _, err := fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) + if err != nil { + return + } } } diff --git a/internal/github/pullRequests.go b/internal/github/pullRequests.go new file mode 100644 index 0000000..4befce8 --- /dev/null +++ b/internal/github/pullRequests.go @@ -0,0 +1,41 @@ +package github + +import ( + "context" + "fmt" + + "github.com/google/go-github/v60/github" +) + +// FindCommunityPRs obtains non-teammember PRs +func FindCommunityPRs(owner string, repo string, teamMembers map[string]bool, githubClient *github.Client) ([]*github.PullRequest, error) { + var finalPRs []*github.PullRequest + opts := &github.PullRequestListOptions{ + State: "open", + Sort: "created", + Direction: "desc", + ListOptions: github.ListOptions{ + Page: 0, + PerPage: 100, + }, + } + for { + opts.ListOptions.Page++ + pullRequests, resp, err := githubClient.PullRequests.List(context.TODO(), owner, repo, opts) + if err != nil { + return finalPRs, fmt.Errorf("error listing pull requests: %w", err) + } + + for _, pullRequest := range pullRequests { + user := *pullRequest.User.Login + if !teamMembers[user] { + finalPRs = append(finalPRs, pullRequest) + } + } + + if resp.NextPage == 0 { + break + } + } + return finalPRs, nil +} diff --git a/internal/github/teamMemberList.go b/internal/github/teamMemberList.go new file mode 100644 index 0000000..43c9e0f --- /dev/null +++ b/internal/github/teamMemberList.go @@ -0,0 +1,44 @@ +package github + +import ( + "context" + "fmt" + "strings" + + "github.com/google/go-github/v60/github" +) + +// GetTeamMemList obtains a list of teammembers +func GetTeamMemberList(githubClient *github.Client, internalTeam string) (map[string]bool, error) { + teamMembers := make(map[string]bool) + + teamParts := strings.Split(internalTeam, "/") + if len(teamParts) != 2 { + return nil, fmt.Errorf("invalid team name - must contain org and team : %s", internalTeam) + } + + teamOpts := &github.TeamListTeamMembersOptions{ + Role: "all", + ListOptions: github.ListOptions{ + Page: 0, + PerPage: 100, + }, + } + + for { + teamOpts.ListOptions.Page++ + members, resp, err := githubClient.Teams.ListTeamMembersBySlug(context.TODO(), teamParts[0], teamParts[1], teamOpts) + if err != nil { + return nil, fmt.Errorf("error getting team %s: %w", internalTeam, err) + } + + for _, member := range members { + teamMembers[*member.Login] = true + } + + if resp.NextPage == 0 { + break + } + } + return teamMembers, nil +} diff --git a/internal/label/pullrequests.go b/internal/label/pullrequests.go index af7c207..73b1bd5 100644 --- a/internal/label/pullrequests.go +++ b/internal/label/pullrequests.go @@ -9,114 +9,74 @@ import ( "github.com/google/go-github/v60/github" "github.com/chia-network/github-bot/internal/config" + github2 "github.com/chia-network/github-bot/internal/github" ) // PullRequests applies internal or community labels to pull requests // Internal is determined by checking if the PR author is a member of the specified internalTeam func PullRequests(githubClient *github.Client, internalTeam string, cfg config.LabelConfig) error { - teamMembers := map[string]bool{} - - teamParts := strings.Split(internalTeam, "/") - if len(teamParts) != 2 { - return fmt.Errorf("invalid team name - must contain org and team : %s", internalTeam) - } - - teamOpts := &github.TeamListTeamMembersOptions{ - Role: "all", - ListOptions: github.ListOptions{ - Page: 0, - PerPage: 100, - }, - } - - for { - teamOpts.ListOptions.Page++ - members, resp, err := githubClient.Teams.ListTeamMembersBySlug(context.TODO(), teamParts[0], teamParts[1], teamOpts) - if err != nil { - return fmt.Errorf("error getting team %s: %w", internalTeam, err) - } - - for _, member := range members { - teamMembers[*member.Login] = true - } - - if resp.NextPage == 0 { - break - } - } - + teamMembers, _ := github2.GetTeamMemberList(githubClient, internalTeam) for _, fullRepo := range cfg.LabelCheckRepos { log.Println("checking repos") parts := strings.Split(fullRepo.Name, "/") if len(parts) != 2 { return fmt.Errorf("invalid repository name - must contain owner and repository: %s", fullRepo.Name) } - opts := &github.PullRequestListOptions{ - State: "open", - Sort: "created", - Direction: "desc", - ListOptions: github.ListOptions{ - Page: 0, - PerPage: 100, - }, + owner := parts[0] + repo := parts[1] + pullRequests, err := github2.FindCommunityPRs(owner, repo, teamMembers, githubClient) + if err != nil { + return err } - for { - lowestNumber := 0 - opts.ListOptions.Page++ - owner := parts[0] - repo := parts[1] - pullRequests, resp, err := githubClient.PullRequests.List(context.TODO(), owner, repo, opts) - if err != nil { - return fmt.Errorf("error listing pull requests: %w", err) + + lowestNumber := 0 + + for _, pullRequest := range pullRequests { + lowestNumber = *pullRequest.Number + if *pullRequest.Number < fullRepo.MinimumNumber { + // Break, not continue, since our order ensures PR numbers are getting smaller + break + } + if *pullRequest.Draft { + continue + } + user := *pullRequest.User.Login + if cfg.LabelSkipMap[user] { + continue + } + var label string + if teamMembers[user] { + label = cfg.LabelInternal + } else { + label = cfg.LabelExternal } - for _, pullRequest := range pullRequests { - lowestNumber = *pullRequest.Number - if *pullRequest.Number < fullRepo.MinimumNumber { - // Break, not continue, since our order ensures PR numbers are getting smaller - break - } - if *pullRequest.Draft { - continue - } - user := *pullRequest.User.Login - if cfg.LabelSkipMap[user] { - continue - } - var label string - if teamMembers[user] { - label = cfg.LabelInternal - } else { - label = cfg.LabelExternal + if label != "" { + log.Printf("Pull Request %d by %s will be labeled %s\n", *pullRequest.Number, user, label) + hasLabel := false + for _, existingLabel := range pullRequest.Labels { + if *existingLabel.Name == label { + log.Println(" Already labeled, skipping...") + hasLabel = true + break + } } - if label != "" { - log.Printf("Pull Request %d by %s will be labeled %s\n", *pullRequest.Number, user, label) - hasLabel := false - for _, existingLabel := range pullRequest.Labels { - if *existingLabel.Name == label { - log.Println(" Already labeled, skipping...") - hasLabel = true - break - } + if !hasLabel { + allLabels := []string{label} + for _, labelP := range pullRequest.Labels { + allLabels = append(allLabels, *labelP.Name) } - - if !hasLabel { - allLabels := []string{label} - for _, labelP := range pullRequest.Labels { - allLabels = append(allLabels, *labelP.Name) - } - _, _, err := githubClient.Issues.AddLabelsToIssue(context.TODO(), owner, repo, *pullRequest.Number, allLabels) - if err != nil { - return fmt.Errorf("error adding labels to pull request %d: %w", *pullRequest.Number, err) - } + _, _, err := githubClient.Issues.AddLabelsToIssue(context.TODO(), owner, repo, *pullRequest.Number, allLabels) + if err != nil { + return fmt.Errorf("error adding labels to pull request %d: %w", *pullRequest.Number, err) } } } + } - if resp.NextPage == 0 || lowestNumber <= fullRepo.MinimumNumber { - break - } + if lowestNumber <= fullRepo.MinimumNumber { + continue } }