Supports wildcard protected branch (#20825)

This PR introduce glob match for protected branch name. The separator is
`/` and you can use `*` matching non-separator chars and use `**` across
separator.

It also supports input an exist or non-exist branch name as matching
condition and branch name condition has high priority than glob rule.

Should fix #2529 and #15705

screenshots

<img width="1160" alt="image"
src="https://user-images.githubusercontent.com/81045/205651179-ebb5492a-4ade-4bb4-a13c-965e8c927063.png">

Co-authored-by: zeripath <art27@cantab.net>
This commit is contained in:
Lunny Xiao 2023-01-16 16:00:22 +08:00 committed by GitHub
parent cc1f8cbe96
commit 2782c14396
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 1222 additions and 819 deletions

View file

@ -440,11 +440,12 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
setMergeTarget(ctx, pull)
if err := pull.LoadProtectedBranch(ctx); err != nil {
pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, repo.ID, pull.BaseBranch)
if err != nil {
ctx.ServerError("LoadProtectedBranch", err)
return nil
}
ctx.Data["EnableStatusCheck"] = pull.ProtectedBranch != nil && pull.ProtectedBranch.EnableStatusCheck
ctx.Data["EnableStatusCheck"] = pb != nil && pb.EnableStatusCheck
var baseGitRepo *git.Repository
if pull.BaseRepoID == ctx.Repo.Repository.ID && ctx.Repo.GitRepo != nil {
@ -570,16 +571,16 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(commitStatuses)
}
if pull.ProtectedBranch != nil && pull.ProtectedBranch.EnableStatusCheck {
if pb != nil && pb.EnableStatusCheck {
ctx.Data["is_context_required"] = func(context string) bool {
for _, c := range pull.ProtectedBranch.StatusCheckContexts {
for _, c := range pb.StatusCheckContexts {
if c == context {
return true
}
}
return false
}
ctx.Data["RequiredStatusCheckState"] = pull_service.MergeRequiredContextsCommitStatus(commitStatuses, pull.ProtectedBranch.StatusCheckContexts)
ctx.Data["RequiredStatusCheckState"] = pull_service.MergeRequiredContextsCommitStatus(commitStatuses, pb.StatusCheckContexts)
}
ctx.Data["HeadBranchMovedOn"] = headBranchSha != sha
@ -752,16 +753,17 @@ func ViewPullFiles(ctx *context.Context) {
return
}
if err = pull.LoadProtectedBranch(ctx); err != nil {
pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pull.BaseRepoID, pull.BaseBranch)
if err != nil {
ctx.ServerError("LoadProtectedBranch", err)
return
}
if pull.ProtectedBranch != nil {
glob := pull.ProtectedBranch.GetProtectedFilePatterns()
if pb != nil {
glob := pb.GetProtectedFilePatterns()
if len(glob) != 0 {
for _, file := range diff.Files {
file.IsProtected = pull.ProtectedBranch.IsProtectedFile(glob, file.Name)
file.IsProtected = pb.IsProtectedFile(glob, file.Name)
}
}
}
@ -1400,7 +1402,7 @@ func deleteBranch(ctx *context.Context, pr *issues_model.PullRequest, gitRepo *g
ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", fullBranchName))
case errors.Is(err, repo_service.ErrBranchIsDefault):
ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", fullBranchName))
case errors.Is(err, repo_service.ErrBranchIsProtected):
case errors.Is(err, git_model.ErrBranchIsProtected):
ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", fullBranchName))
default:
log.Error("DeleteBranch: %v", err)