- Removed GitHub Dependencies: Excised the unused newGithubClient and its associated dependencies (google/go-github and oauth2) from main.go and go.mod.
- Project Infrastructure Updates:
- Updated Dockerfile to use golang:1.25 for consistency with go.mod.
- Modified action.yaml to run from the local Dockerfile, ensuring that the Forgejo-specific logic is utilized.
- Validation: Verified all changes through a successful build and by running the full test suite, all of which passed.
109 lines
3.3 KiB
Go
109 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"codeberg.org/mvdkleijn/forgejo-sdk/forgejo/v3"
|
|
)
|
|
|
|
func retrieveApprovers(client *forgejo.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 len(expandedUsers) > 0 {
|
|
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 *forgejo.Client, org string, userOrTeam string, workflowInitiator string, shouldExcludeWorkflowInitiator bool) []string {
|
|
fmt.Printf("Attempting to expand user %s/%s as a group (may not succeed)\n", org, userOrTeam)
|
|
|
|
// Try to find a team with this name in the org
|
|
teams, _, err := client.SearchOrgTeams(org, &forgejo.SearchTeamsOptions{Query: userOrTeam})
|
|
if err != nil {
|
|
fmt.Printf("Error searching teams: %v\n", err)
|
|
return nil
|
|
}
|
|
|
|
var team *forgejo.Team
|
|
for _, t := range teams {
|
|
if strings.EqualFold(t.Name, userOrTeam) {
|
|
team = t
|
|
break
|
|
}
|
|
}
|
|
|
|
if team == nil {
|
|
return nil
|
|
}
|
|
|
|
users, _, err := client.ListTeamMembers(team.ID, forgejo.ListTeamMembersOptions{})
|
|
if err != nil {
|
|
fmt.Printf("Error listing team members: %v\n", err)
|
|
return nil
|
|
}
|
|
|
|
userNames := make([]string, 0, len(users))
|
|
for _, user := range users {
|
|
userName := user.UserName
|
|
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
|
|
}
|