forked from forgejo/forgejo
Allow repo admin to merge PR regardless of review status (#9611)
* Allow repo admin to merge even if review is not ok.
This commit is contained in:
parent
4d06d10dba
commit
32fb813133
13 changed files with 236 additions and 124 deletions
|
@ -30,6 +30,7 @@ import (
|
|||
)
|
||||
|
||||
// Merge merges pull request to base repository.
|
||||
// Caller should check PR is ready to be merged (review and status checks)
|
||||
// FIXME: add repoWorkingPull make sure two merges does not happen at same time.
|
||||
func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repository, mergeStyle models.MergeStyle, message string) (err error) {
|
||||
binVersion, err := git.BinVersion()
|
||||
|
@ -53,11 +54,6 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
|||
}
|
||||
prConfig := prUnit.PullRequestsConfig()
|
||||
|
||||
if err := pr.CheckUserAllowedToMerge(doer); err != nil {
|
||||
log.Error("CheckUserAllowedToMerge(%v): %v", doer, err)
|
||||
return fmt.Errorf("CheckUserAllowedToMerge: %v", err)
|
||||
}
|
||||
|
||||
// Check if merge style is correct and allowed
|
||||
if !prConfig.IsMergeStyleAllowed(mergeStyle) {
|
||||
return models.ErrInvalidMergeStyle{ID: pr.BaseRepo.ID, Style: mergeStyle}
|
||||
|
@ -473,3 +469,64 @@ func getDiffTree(repoPath, baseBranch, headBranch string) (string, error) {
|
|||
|
||||
return out.String(), nil
|
||||
}
|
||||
|
||||
// IsUserAllowedToMerge check if user is allowed to merge PR with given permissions and branch protections
|
||||
func IsUserAllowedToMerge(pr *models.PullRequest, p models.Permission, user *models.User) (bool, error) {
|
||||
if p.IsAdmin() {
|
||||
return true, nil
|
||||
}
|
||||
if !p.CanWrite(models.UnitTypeCode) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
err := pr.LoadProtectedBranch()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if pr.ProtectedBranch == nil || pr.ProtectedBranch.IsUserMergeWhitelisted(user.ID) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// CheckPRReadyToMerge checks whether the PR is ready to be merged (reviews and status checks)
|
||||
func CheckPRReadyToMerge(pr *models.PullRequest) (err error) {
|
||||
if pr.BaseRepo == nil {
|
||||
if err = pr.GetBaseRepo(); err != nil {
|
||||
return fmt.Errorf("GetBaseRepo: %v", err)
|
||||
}
|
||||
}
|
||||
if pr.ProtectedBranch == nil {
|
||||
if err = pr.LoadProtectedBranch(); err != nil {
|
||||
return fmt.Errorf("LoadProtectedBranch: %v", err)
|
||||
}
|
||||
if pr.ProtectedBranch == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
isPass, err := IsPullCommitStatusPass(pr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isPass {
|
||||
return models.ErrNotAllowedToMerge{
|
||||
Reason: "Not all required status checks successful",
|
||||
}
|
||||
}
|
||||
|
||||
if enoughApprovals := pr.ProtectedBranch.HasEnoughApprovals(pr); !enoughApprovals {
|
||||
return models.ErrNotAllowedToMerge{
|
||||
Reason: "Does not have enough approvals",
|
||||
}
|
||||
}
|
||||
if rejected := pr.ProtectedBranch.MergeBlockedByRejectedReview(pr); rejected {
|
||||
return models.ErrNotAllowedToMerge{
|
||||
Reason: "There are requested changes",
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue