diff options
author | Tim <tim@datenknoten.me> | 2024-10-23 06:39:43 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-23 12:39:43 +0800 |
commit | de2ad2e1b177ed1c3412761c54b28579f8ecbb00 (patch) | |
tree | a8124fa2c61116adfe96e41b89335202c2955b55 /services | |
parent | 620f19610ef747412a9e4265c6b20fa560663f17 (diff) | |
download | gitea-de2ad2e1b177ed1c3412761c54b28579f8ecbb00.tar.gz gitea-de2ad2e1b177ed1c3412761c54b28579f8ecbb00.zip |
Make admins adhere to branch protection rules (#32248)
This introduces a new flag `BlockAdminMergeOverride` on the branch
protection rules that prevents admins/repo owners from bypassing branch
protection rules and merging without approvals or failing status checks.
Fixes #17131
---------
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Diffstat (limited to 'services')
-rw-r--r-- | services/convert/convert.go | 1 | ||||
-rw-r--r-- | services/forms/repo_form.go | 1 | ||||
-rw-r--r-- | services/pull/check.go | 25 |
3 files changed, 19 insertions, 8 deletions
diff --git a/services/convert/convert.go b/services/convert/convert.go index 041d553e98..8dc311dae9 100644 --- a/services/convert/convert.go +++ b/services/convert/convert.go @@ -185,6 +185,7 @@ func ToBranchProtection(ctx context.Context, bp *git_model.ProtectedBranch, repo RequireSignedCommits: bp.RequireSignedCommits, ProtectedFilePatterns: bp.ProtectedFilePatterns, UnprotectedFilePatterns: bp.UnprotectedFilePatterns, + BlockAdminMergeOverride: bp.BlockAdminMergeOverride, Created: bp.CreatedUnix.AsTime(), Updated: bp.UpdatedUnix.AsTime(), } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 988e479a48..ddd07a64cb 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -219,6 +219,7 @@ type ProtectBranchForm struct { RequireSignedCommits bool ProtectedFilePatterns string UnprotectedFilePatterns string + BlockAdminMergeOverride bool } // Validate validates the fields diff --git a/services/pull/check.go b/services/pull/check.go index ce212f7d83..736be4611b 100644 --- a/services/pull/check.go +++ b/services/pull/check.go @@ -68,7 +68,7 @@ const ( ) // CheckPullMergeable check if the pull mergeable based on all conditions (branch protection, merge options, ...) -func CheckPullMergeable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *issues_model.PullRequest, mergeCheckType MergeCheckType, adminSkipProtectionCheck bool) error { +func CheckPullMergeable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *issues_model.PullRequest, mergeCheckType MergeCheckType, adminForceMerge bool) error { return db.WithTx(stdCtx, func(ctx context.Context) error { if pr.HasMerged { return ErrHasMerged @@ -118,13 +118,22 @@ func CheckPullMergeable(stdCtx context.Context, doer *user_model.User, perm *acc err = nil } - // * 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 admin tries to "Force Merge", they could sometimes skip the branch protection check + if adminForceMerge { + isRepoAdmin, errForceMerge := access_model.IsUserRepoAdmin(ctx, pr.BaseRepo, doer) + if errForceMerge != nil { + return fmt.Errorf("IsUserRepoAdmin failed, repo: %v, doer: %v, err: %w", pr.BaseRepoID, doer.ID, errForceMerge) + } + + protectedBranchRule, errForceMerge := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch) + if errForceMerge != nil { + return fmt.Errorf("GetFirstMatchProtectedBranchRule failed, repo: %v, base branch: %v, err: %w", pr.BaseRepoID, pr.BaseBranch, errForceMerge) + } + + // if doer is admin and the "Force Merge" is not blocked, then clear the branch protection check error + blockAdminForceMerge := protectedBranchRule != nil && protectedBranchRule.BlockAdminMergeOverride + if isRepoAdmin && !blockAdminForceMerge { + err = nil } } |