1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-22 18:28:37 +00:00

Add force_merge to merge request and fix checking mergable (#23010)

Fix #23000.
This commit is contained in:
Jason Song
2023-02-21 22:42:07 +08:00
committed by GitHub
parent 1fcf96ad01
commit c8c2a31818
6 changed files with 59 additions and 20 deletions

View File

@@ -230,7 +230,7 @@ func handlePull(pullID int64, sha string) {
return
}
if err := pull_service.CheckPullMergable(ctx, doer, &perm, pr, false, false); err != nil {
if err := pull_service.CheckPullMergable(ctx, doer, &perm, pr, pull_service.MergeCheckTypeGeneral, false); err != nil {
if errors.Is(pull_service.ErrUserNotAllowedToMerge, err) {
log.Info("%-v was scheduled to automerge by an unauthorized user", pr)
return

View File

@@ -604,7 +604,7 @@ type MergePullRequestForm struct {
MergeMessageField string
MergeCommitID string // only used for manually-merged
HeadCommitID string `json:"head_commit_id,omitempty"`
ForceMerge *bool `json:"force_merge,omitempty"`
ForceMerge bool `json:"force_merge,omitempty"`
MergeWhenChecksSucceed bool `json:"merge_when_checks_succeed,omitempty"`
DeleteBranchAfterMerge bool `json:"delete_branch_after_merge,omitempty"`
}

View File

@@ -59,8 +59,16 @@ func AddToTaskQueue(pr *issues_model.PullRequest) {
}
}
type MergeCheckType int
const (
MergeCheckTypeGeneral MergeCheckType = iota // general merge checks for "merge", "rebase", "squash", etc
MergeCheckTypeManually // Manually Merged button (mark a PR as merged manually)
MergeCheckTypeAuto // Auto Merge (Scheduled Merge) After Checks Succeed
)
// CheckPullMergable check if the pull mergable based on all conditions (branch protection, merge options, ...)
func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *issues_model.PullRequest, manuallMerge, force bool) error {
func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *issues_model.PullRequest, mergeCheckType MergeCheckType, adminSkipProtectionCheck bool) error {
return db.WithTx(stdCtx, func(ctx context.Context) error {
if pr.HasMerged {
return ErrHasMerged
@@ -80,8 +88,8 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce
return ErrUserNotAllowedToMerge
}
if manuallMerge {
// don't check rules to "auto merge", doer is going to mark this pull as merged manually
if mergeCheckType == MergeCheckTypeManually {
// if doer is doing "manually merge" (mark as merged manually), do not check anything
return nil
}
@@ -103,14 +111,25 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce
return err
}
if !force {
return err
// Now the branch protection check failed, check whether the failure could be skipped (skip by setting err = nil)
// * when doing Auto Merge (Scheduled Merge After Checks Succeed), skip the branch protection check
if mergeCheckType == MergeCheckTypeAuto {
err = nil
}
if isRepoAdmin, err2 := access_model.IsUserRepoAdmin(ctx, pr.BaseRepo, doer); err2 != nil {
log.Error("Unable to check if %-v is a repo admin in %-v: %v", doer, pr.BaseRepo, err2)
return err2
} else if !isRepoAdmin {
// * if the doer is admin, they could skip the branch protection check
if adminSkipProtectionCheck {
if isRepoAdmin, errCheckAdmin := access_model.IsUserRepoAdmin(ctx, pr.BaseRepo, doer); errCheckAdmin != nil {
log.Error("Unable to check if %-v is a repo admin in %-v: %v", doer, pr.BaseRepo, errCheckAdmin)
return errCheckAdmin
} else if isRepoAdmin {
err = nil // repo admin can skip the check, so clear the error
}
}
// If there is still a branch protection check error, return it
if err != nil {
return err
}
}