Skip to content

Conversation

@C-Hipple
Copy link
Collaborator

@C-Hipple C-Hipple commented Oct 31, 2025

Related PR(s)

Related Issue(s)

#40

Summary / Background

This PR adds checking for when all of teh teams have approved a PR, but there are not enough approvals to satisfy minReviews. In that case, mm-codeowners will re-request from all required teams.

Most commonly, we'll have 2 reviews required and only 1 owning team. That team will then be re-requested for a 2nd review.

If you require 3 reviews, and 2 teams are required, and they've both approved, then both teams will be re-requested.

Important to note that none of this re-requesting logic triggers if there are any outstanding teams still to review, since it checks that there's no outstanding review requests.

@pooyaw
Copy link

pooyaw commented Oct 31, 2025

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Licenses 0 0 0 0 0 issues
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@C-Hipple
Copy link
Collaborator Author

/gemini review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a useful feature to re-request reviews from a satisfied team when min_reviews is not met. This is particularly helpful for workflows requiring multiple reviews from a single team. The implementation is generally solid, with new logic in app.go and corresponding changes in the codeowners package and tests. I've provided a couple of suggestions to enhance efficiency and reduce code duplication for better long-term maintainability.

Comment on lines 237 to 240
// Filter out anyone already requested
ownersToReRequest := f.Filtered(allRequiredOwnerNames, func(owner string) bool {
return !slices.Contains(currentlyRequestedOwners, owner)
})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation for filtering ownersToReRequest uses slices.Contains inside a loop (f.Filtered), which results in a time complexity of O(N*M). For larger lists of owners, this could be inefficient. A more performant and idiomatic Go approach is to use a map (acting as a set) for currentlyRequestedOwners to achieve O(1) lookups during filtering.

				// Filter out anyone already requested
				currentlyRequestedSet := make(map[string]struct{}, len(currentlyRequestedOwners))
				for _, owner := range currentlyRequestedOwners {
					currentlyRequestedSet[owner] = struct{}{}
				}
				ownersToReRequest := f.Filtered(allRequiredOwnerNames, func(owner string) bool {
					_, exists := currentlyRequestedSet[owner]
					return !exists
				})

Comment on lines 98 to 104
func (om *ownersMap) AllRequiredIncludingSatisfied() ReviewerGroups {
reviewers := make([]*ReviewerGroup, 0)
for _, fileOwner := range om.fileToOwner {
reviewers = append(reviewers, fileOwner.requiredReviewers...)
}
return f.RemoveDuplicates(reviewers)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This new function AllRequiredIncludingSatisfied is very similar to the existing AllRequired function. To improve maintainability and reduce code duplication, you could consider refactoring them to use a common private helper function.

For example, you could introduce a helper:

func (om *ownersMap) allReviewers(getReviewers func(fileOwners) ReviewerGroups) ReviewerGroups {
	reviewers := make([]*ReviewerGroup, 0)
	for _, fileOwner := range om.fileToOwner {
		reviewers = append(reviewers, getReviewers(fileOwner)...)
	}
	return f.RemoveDuplicates(reviewers)
}

And then AllRequired and AllRequiredIncludingSatisfied would become one-liners:

func (om *ownersMap) AllRequired() ReviewerGroups {
	return om.allReviewers(func(fo fileOwners) ReviewerGroups { return fo.RequiredReviewers() })
}

func (om *ownersMap) AllRequiredIncludingSatisfied() ReviewerGroups {
	return om.allReviewers(func(fo fileOwners) ReviewerGroups { return fo.requiredReviewers })
}

if validApprovalCount < *a.Conf.MinReviews && len(unapprovedOwners) == 0 {
// All required teams have approved, but we need more reviews
// Re-request review from the satisfied team(s)
allRequiredOwnerNames := a.codeowners.AllRequiredIncludingSatisfied().Flatten()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is totally unnecessary - allRequiredOwnersNames already exists and is never mutated

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh, this is was very confusing to me since method used to get allRequiredOwnersNames filters out approved, but didn't realize that it was calculated before the approvals were processed


// Check if we need to re-request from a satisfied team when min_reviews is not met
// This handles the case where only 1 team is required but multiple reviews are needed
if a.Conf.MinReviews != nil && *a.Conf.MinReviews > 0 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this into the existing MinReviews handling block

@C-Hipple C-Hipple marked this pull request as ready for review November 3, 2025 14:58
@github-actions
Copy link

github-actions bot commented Nov 3, 2025

Codeowners approval required for this PR:

@C-Hipple C-Hipple requested a review from BakerNet November 3, 2025 15:45
@BakerNet BakerNet merged commit a32319d into main Nov 3, 2025
11 of 12 checks passed
@BakerNet BakerNet deleted the feature/re-request-only-team branch November 3, 2025 18:00
@BakerNet BakerNet linked an issue Nov 3, 2025 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Re-request review to satisfy minimum codeowners count

4 participants