From 6ca0a8d7c8f121e5dcacaae7ad43493e3ae93522 Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Mon, 19 Feb 2024 10:57:08 +0100 Subject: [PATCH] Disallow merge when required checked are missing (#29143) fixes #21892 This PR disallows merging a PR when not all commit status contexts configured in the branch protection are met. Previously, the PR was happy to merge when one commit status was successful and the other contexts weren't reported. Any feedback is welcome, first time Go :-) I'm also not sure if the changes in the template break something else Given the following branch protection: ![branch_protection](https://github.com/go-gitea/gitea/assets/2401875/f871b4e4-138b-435a-b496-f9ad432e3dec) This was shown before the change: ![before](https://github.com/go-gitea/gitea/assets/2401875/60424ff0-ee09-4fa0-856e-64e6e3fb0612) With the change, it is now shown as this: ![after](https://github.com/go-gitea/gitea/assets/2401875/4e464142-efb1-4889-8166-eb3be26c8f3d) --------- 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 81fb1fb51ef9d..7b86c86188bec 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 39d60380ff202..965cfa0df1b2e 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 476b89a42511f..513ec98073443 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}}