diff --git a/README.md b/README.md index 5b1c7eb..f331488 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Code Ownership & Review Assignment Tool - GitHub CODEOWNERS but better [![Go Report Card](https://goreportcard.com/badge/github.com/multimediallc/codeowners-plus)](https://goreportcard.com/report/github.com/multimediallc/codeowners-plus?kill_cache=1) [![Tests](https://github.com/multimediallc/codeowners-plus/actions/workflows/go.yml/badge.svg)](https://github.com/multimediallc/codeowners-plus/actions/workflows/go.yml) -![Coverage](https://img.shields.io/badge/Coverage-81.8%25-brightgreen) +![Coverage](https://img.shields.io/badge/Coverage-81.6%25-brightgreen) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md) @@ -229,6 +229,9 @@ high_priority_labels = ["high-priority", "urgent"] # of files and owners in its review comment detailed_reviewers = true +# `disable_smart_dismissal` (default false) means the codeowners will not dismiss stale reviews +disable_smart_dismissal = true + # `enforcement` allows you to specify how the Codeowners Plus check should be enforced [enforcement] # see "Enforcement Options" below for more details diff --git a/codeowners.toml b/codeowners.toml index 7b82eb8..c495377 100644 --- a/codeowners.toml +++ b/codeowners.toml @@ -10,6 +10,8 @@ ignore = ["test_project"] high_priority_labels = ["P0"] # `detailed_reviewers` (default false) means the codeowners will include a collapsible list of files and owners in its review comment detailed_reviewers = false +# `disable_smart_dismissal` (default false) means the codeowners will not dismiss stale reviews +disable_smart_dismissal = false # `enforcement` allows you to specify how the codeowners check should be enforced [enforcement] diff --git a/internal/app/app.go b/internal/app/app.go index c488338..a4b4b4a 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -261,7 +261,7 @@ func (a *App) processApprovalsAndReviewers() (bool, string, []string, error) { if len(unapprovedOwners) > 0 && !maxReviewsMet { // Return failed status if any codeowner team has not approved the PR unapprovedCommentString := unapprovedOwners.ToCommentString(false) - if a.Conf.Enforcement.Approval && tokenOwnerApproval != nil { + if a.Conf.Enforcement.Approval && tokenOwnerApproval != nil && !a.Conf.DisableSmartDismissal { _ = a.client.DismissStaleReviews([]*gh.CurrentApproval{tokenOwnerApproval}) } message = fmt.Sprintf( @@ -402,7 +402,22 @@ func (a *App) processTokenOwnerApproval() (*gh.CurrentApproval, error) { func (a *App) processApprovals(ghApprovals []*gh.CurrentApproval) (int, error) { fileReviewers := f.MapMap(a.codeowners.FileRequired(), func(reviewers codeowners.ReviewerGroups) []string { return reviewers.Flatten() }) - approvers, approvalsToDismiss := a.client.CheckApprovals(fileReviewers, ghApprovals, a.gitDiff) + + var approvers []string + var approvalsToDismiss []*gh.CurrentApproval + + if a.Conf.DisableSmartDismissal { + // Smart dismissal is disabled - treat all approvals as valid + a.printDebug("Smart dismissal disabled - keeping all approvals\n") + for _, approval := range ghApprovals { + approvers = append(approvers, approval.Reviewers...) + } + approvalsToDismiss = []*gh.CurrentApproval{} + } else { + // Normal smart dismissal logic + approvers, approvalsToDismiss = a.client.CheckApprovals(fileReviewers, ghApprovals, a.gitDiff) + } + a.codeowners.ApplyApprovals(approvers) if len(approvalsToDismiss) > 0 { diff --git a/internal/config/config.go b/internal/config/config.go index 80190cc..2ae41bd 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -17,6 +17,7 @@ type Config struct { HighPriorityLabels []string `toml:"high_priority_labels"` AdminBypass *AdminBypass `toml:"admin_bypass"` DetailedReviewers bool `toml:"detailed_reviewers"` + DisableSmartDismissal bool `toml:"disable_smart_dismissal"` } type Enforcement struct {