summaryrefslogtreecommitdiffstats
path: root/modules/pull
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2019-09-18 13:39:45 +0800
committerLauris BH <lauris@nix.lv>2019-09-18 08:39:45 +0300
commit04ca7f004710de2b408f558f6f148894aa61ba57 (patch)
tree57fea3b9853127897676faaf9e70abace2565878 /modules/pull
parent29454733b4eeea33e6c94c50b32855066c203988 (diff)
downloadgitea-04ca7f004710de2b408f558f6f148894aa61ba57.tar.gz
gitea-04ca7f004710de2b408f558f6f148894aa61ba57.zip
Refuse merge until all required status checks success (#7481)
* refuse merge until ci successfully * deny merge request when required status checkes not succeed on merge Post and API * add database migration for added columns on protected_branch * fix migration * fix protected branch check bug * fix protected branch settings * remove duplicated code on check pull request's required commit statuses pass * remove unused codes * fix migration * add newline for template file * fix go mod * rename function name and some other fixes * fix template * fix bug pull view * remove go1.12 wrong dependencies * add administrator bypass when protected branch status check enabled * fix bug * improve the codes
Diffstat (limited to 'modules/pull')
-rw-r--r--modules/pull/commit_status.go70
1 files changed, 70 insertions, 0 deletions
diff --git a/modules/pull/commit_status.go b/modules/pull/commit_status.go
new file mode 100644
index 0000000000..bdadc329d6
--- /dev/null
+++ b/modules/pull/commit_status.go
@@ -0,0 +1,70 @@
+// Copyright 2019 The Gitea Authors.
+// All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package pull
+
+import (
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/git"
+
+ "github.com/pkg/errors"
+)
+
+// IsCommitStatusContextSuccess returns true if all required status check contexts succeed.
+func IsCommitStatusContextSuccess(commitStatuses []*models.CommitStatus, requiredContexts []string) bool {
+ for _, ctx := range requiredContexts {
+ var found bool
+ for _, commitStatus := range commitStatuses {
+ if commitStatus.Context == ctx {
+ if commitStatus.State != models.CommitStatusSuccess {
+ return false
+ }
+
+ found = true
+ break
+ }
+ }
+ if !found {
+ return false
+ }
+ }
+ return true
+}
+
+// IsPullCommitStatusPass returns if all required status checks PASS
+func IsPullCommitStatusPass(pr *models.PullRequest) (bool, error) {
+ if err := pr.LoadProtectedBranch(); err != nil {
+ return false, errors.Wrap(err, "GetLatestCommitStatus")
+ }
+ if pr.ProtectedBranch == nil || !pr.ProtectedBranch.EnableStatusCheck {
+ return true, nil
+ }
+
+ // check if all required status checks are successful
+ headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
+ if err != nil {
+ return false, errors.Wrap(err, "OpenRepository")
+ }
+
+ if !headGitRepo.IsBranchExist(pr.HeadBranch) {
+ return false, errors.New("Head branch does not exist, can not merge")
+ }
+
+ sha, err := headGitRepo.GetBranchCommitID(pr.HeadBranch)
+ if err != nil {
+ return false, errors.Wrap(err, "GetBranchCommitID")
+ }
+
+ if err := pr.LoadBaseRepo(); err != nil {
+ return false, errors.Wrap(err, "LoadBaseRepo")
+ }
+
+ commitStatuses, err := models.GetLatestCommitStatus(pr.BaseRepo, sha, 0)
+ if err != nil {
+ return false, errors.Wrap(err, "GetLatestCommitStatus")
+ }
+
+ return IsCommitStatusContextSuccess(commitStatuses, pr.ProtectedBranch.StatusCheckContexts), nil
+}