forked from trstringer/manual-approval
-
Notifications
You must be signed in to change notification settings - Fork 0
/
approvers.go
96 lines (80 loc) · 3.22 KB
/
approvers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package main
import (
"context"
"fmt"
"os"
"strconv"
"strings"
"github.com/google/go-github/v43/github"
)
func retrieveApprovers(client *github.Client, repoOwner string) ([]string, error) {
workflowInitiator := os.Getenv(envVarWorkflowInitiator)
shouldExcludeWorkflowInitiatorRaw := os.Getenv(envVarExcludeWorkflowInitiatorAsApprover)
shouldExcludeWorkflowInitiator, parseBoolErr := strconv.ParseBool(shouldExcludeWorkflowInitiatorRaw)
if parseBoolErr != nil {
return nil, fmt.Errorf("error parsing exclude-workflow-initiator-as-approver flag: %w", parseBoolErr)
}
approvers := []string{}
requiredApproversRaw := os.Getenv(envVarApprovers)
requiredApprovers := strings.Split(requiredApproversRaw, ",")
for i := range requiredApprovers {
requiredApprovers[i] = strings.TrimSpace(requiredApprovers[i])
}
for _, approverUser := range requiredApprovers {
expandedUsers := expandGroupFromUser(client, repoOwner, approverUser, workflowInitiator, shouldExcludeWorkflowInitiator)
if expandedUsers != nil {
approvers = append(approvers, expandedUsers...)
} else if strings.EqualFold(workflowInitiator, approverUser) && shouldExcludeWorkflowInitiator {
fmt.Printf("Not adding user '%s' as an approver as they are the workflow initiator\n", approverUser)
} else {
approvers = append(approvers, approverUser)
}
}
approvers = deduplicateUsers(approvers)
minimumApprovalsRaw := os.Getenv(envVarMinimumApprovals)
minimumApprovals := len(approvers)
var err error
if minimumApprovalsRaw != "" {
minimumApprovals, err = strconv.Atoi(minimumApprovalsRaw)
if err != nil {
return nil, fmt.Errorf("error parsing minimum number of approvals: %w", err)
}
}
if minimumApprovals > len(approvers) {
return nil, fmt.Errorf("error: minimum required approvals (%d) is greater than the total number of approvers (%d)", minimumApprovals, len(approvers))
}
return approvers, nil
}
func expandGroupFromUser(client *github.Client, org, userOrTeam string, workflowInitiator string, shouldExcludeWorkflowInitiator bool) []string {
fmt.Printf("Attempting to expand user %s/%s as a group (may not succeed)\n", org, userOrTeam)
// GitHub replaces periods in the team name with hyphens. If a period is
// passed to the request it would result in a 404. So we need to replace
// and occurrences with a hyphen.
formattedUserOrTeam := strings.ReplaceAll(userOrTeam, ".", "-")
users, _, err := client.Teams.ListTeamMembersBySlug(context.Background(), org, formattedUserOrTeam, &github.TeamListTeamMembersOptions{})
if err != nil {
fmt.Printf("%v\n", err)
return nil
}
userNames := make([]string, 0, len(users))
for _, user := range users {
userName := user.GetLogin()
if strings.EqualFold(userName, workflowInitiator) && shouldExcludeWorkflowInitiator {
fmt.Printf("Not adding user '%s' from group '%s' as an approver as they are the workflow initiator\n", userName, userOrTeam)
} else {
userNames = append(userNames, userName)
}
}
return userNames
}
func deduplicateUsers(users []string) []string {
uniqValuesByKey := make(map[string]bool)
uniqUsers := []string{}
for _, user := range users {
if _, ok := uniqValuesByKey[user]; !ok {
uniqValuesByKey[user] = true
uniqUsers = append(uniqUsers, user)
}
}
return uniqUsers
}