From 78f41e4fc43cd903c95d501e40c3496689698cc4 Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Mon, 19 Feb 2024 21:48:17 +0100 Subject: [PATCH] Disallow merge when required checked are missing (#29143) (#29268) backport #29143 Co-authored-by: wxiaoguang --- routers/web/repo/pull.go | 30 ++++++++++++++++++++++++++++++ services/pull/commit_status.go | 4 ++++ templates/repo/pulls/status.tmpl | 15 +++++++++++++-- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 81fb1fb51e..7b86c86188 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -635,6 +635,24 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C } if pb != nil && pb.EnableStatusCheck { + + var missingRequiredChecks []string + for _, requiredContext := range pb.StatusCheckContexts { + contextFound := false + matchesRequiredContext := createRequiredContextMatcher(requiredContext) + for _, presentStatus := range commitStatuses { + if matchesRequiredContext(presentStatus.Context) { + contextFound = true + break + } + } + + if !contextFound { + missingRequiredChecks = append(missingRequiredChecks, requiredContext) + } + } + ctx.Data["MissingRequiredChecks"] = missingRequiredChecks + ctx.Data["is_context_required"] = func(context string) bool { for _, c := range pb.StatusCheckContexts { if c == context { @@ -703,6 +721,18 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C return compareInfo } +func createRequiredContextMatcher(requiredContext string) func(string) bool { + if gp, err := glob.Compile(requiredContext); err == nil { + return func(contextToCheck string) bool { + return gp.Match(contextToCheck) + } + } + + return func(contextToCheck string) bool { + return requiredContext == contextToCheck + } +} + type pullCommitList struct { Commits []pull_service.CommitInfo `json:"commits"` LastReviewCommitSha string `json:"last_review_commit_sha"` diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go index 39d60380ff..965cfa0df1 100644 --- a/services/pull/commit_status.go +++ b/services/pull/commit_status.go @@ -50,6 +50,10 @@ func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus, } } + if matchedCount != len(requiredContexts) { + return structs.CommitStatusPending + } + if matchedCount == 0 { status := git_model.CalcCommitStatus(commitStatuses) if status != nil { diff --git a/templates/repo/pulls/status.tmpl b/templates/repo/pulls/status.tmpl index 476b89a425..513ec98073 100644 --- a/templates/repo/pulls/status.tmpl +++ b/templates/repo/pulls/status.tmpl @@ -1,7 +1,7 @@ {{if $.LatestCommitStatus}} {{if not $.Issue.PullRequest.HasMerged}}
- {{if eq .LatestCommitStatus.State "pending"}} + {{if or (eq .LatestCommitStatus.State "pending") (.MissingRequiredChecks)}} {{ctx.Locale.Tr "repo.pulls.status_checking"}} {{else if eq .LatestCommitStatus.State "success"}} {{ctx.Locale.Tr "repo.pulls.status_checks_success"}} @@ -14,7 +14,7 @@ {{else}} {{ctx.Locale.Tr "repo.pulls.status_checking"}} {{end}} -
+ {{end}} {{range $.LatestCommitStatuses}} @@ -31,4 +31,15 @@ {{end}} + {{range .MissingRequiredChecks}} +
+ {{svg "octicon-dot-fill" 18 "commit-status icon text yellow"}} +
+ {{.}} +
+
{{ctx.Locale.Tr "repo.pulls.status_checks_requested"}}
+
+
+
+ {{end}} {{end}}