mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-22 12:43:39 +09:00
feat: Add bypass allowlist for branch protection (#36514)
- Introduce a “Bypass Protection Allowlist” on branch rules (users/teams) alongside admins, with BlockAdminMergeOverride still respected. - Surface the allowlist in API (create/edit options, structs) and settings UI; merge box now shows the red button + message for bypass-capable users. - Apply bypass logic to merge checks and pre-receive so allowlisted users can override unmet approvals/status checks/ protected files when force-merging. - Add migration for new columns, locale strings, and unit tests (bypass helper; queue test tweak). <img width="1069" height="218" alt="image" src="https://github.com/user-attachments/assets/0b61bc2a-a27f-47f3-a923-613688008e65" /> Fixes #36476 --------- Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: Giteabot <teabot@gitea.io> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: Codex GPT-5.3 <codex@openai.com> Co-authored-by: GPT-5.2 <noreply@openai.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
This commit is contained in:
co-authored by
silverwind
Giteabot
wxiaoguang
Codex GPT-5.3
GPT-5.2
Cursor
Claude
parent
54ff68b0a9
commit
eb93981d45
@@ -83,6 +83,7 @@ func SettingsProtectedBranch(c *context.Context) {
|
||||
c.Data["whitelist_users"] = strings.Join(base.Int64sToStrings(rule.WhitelistUserIDs), ",")
|
||||
c.Data["force_push_allowlist_users"] = strings.Join(base.Int64sToStrings(rule.ForcePushAllowlistUserIDs), ",")
|
||||
c.Data["merge_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.MergeWhitelistUserIDs), ",")
|
||||
c.Data["bypass_allowlist_users"] = strings.Join(base.Int64sToStrings(rule.BypassAllowlistUserIDs), ",")
|
||||
c.Data["approvals_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.ApprovalsWhitelistUserIDs), ",")
|
||||
c.Data["status_check_contexts"] = strings.Join(rule.StatusCheckContexts, "\n")
|
||||
contexts, _ := git_model.FindRepoRecentCommitStatusContexts(c, c.Repo.Repository.ID, 7*24*time.Hour) // Find last week status check contexts
|
||||
@@ -98,6 +99,7 @@ func SettingsProtectedBranch(c *context.Context) {
|
||||
c.Data["whitelist_teams"] = strings.Join(base.Int64sToStrings(rule.WhitelistTeamIDs), ",")
|
||||
c.Data["force_push_allowlist_teams"] = strings.Join(base.Int64sToStrings(rule.ForcePushAllowlistTeamIDs), ",")
|
||||
c.Data["merge_whitelist_teams"] = strings.Join(base.Int64sToStrings(rule.MergeWhitelistTeamIDs), ",")
|
||||
c.Data["bypass_allowlist_teams"] = strings.Join(base.Int64sToStrings(rule.BypassAllowlistTeamIDs), ",")
|
||||
c.Data["approvals_whitelist_teams"] = strings.Join(base.Int64sToStrings(rule.ApprovalsWhitelistTeamIDs), ",")
|
||||
}
|
||||
|
||||
@@ -155,7 +157,7 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
var whitelistUsers, whitelistTeams, forcePushAllowlistUsers, forcePushAllowlistTeams, mergeWhitelistUsers, mergeWhitelistTeams, approvalsWhitelistUsers, approvalsWhitelistTeams []int64
|
||||
var whitelistUsers, whitelistTeams, forcePushAllowlistUsers, forcePushAllowlistTeams, mergeWhitelistUsers, mergeWhitelistTeams, approvalsWhitelistUsers, approvalsWhitelistTeams, bypassAllowlistUsers, bypassAllowlistTeams []int64
|
||||
protectBranch.RuleName = f.RuleName
|
||||
if f.RequiredApprovals < 0 {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.protected_branch_required_approvals_min"))
|
||||
@@ -215,6 +217,16 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
protectBranch.EnableBypassAllowlist = f.EnableBypassAllowlist
|
||||
if f.EnableBypassAllowlist {
|
||||
if strings.TrimSpace(f.BypassAllowlistUsers) != "" {
|
||||
bypassAllowlistUsers, _ = base.StringsToInt64s(strings.Split(f.BypassAllowlistUsers, ","))
|
||||
}
|
||||
if strings.TrimSpace(f.BypassAllowlistTeams) != "" {
|
||||
bypassAllowlistTeams, _ = base.StringsToInt64s(strings.Split(f.BypassAllowlistTeams, ","))
|
||||
}
|
||||
}
|
||||
|
||||
protectBranch.EnableStatusCheck = f.EnableStatusCheck
|
||||
if f.EnableStatusCheck {
|
||||
patterns := strings.Split(strings.ReplaceAll(f.StatusCheckContexts, "\r", "\n"), "\n")
|
||||
@@ -271,6 +283,8 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
|
||||
MergeTeamIDs: mergeWhitelistTeams,
|
||||
ApprovalsUserIDs: approvalsWhitelistUsers,
|
||||
ApprovalsTeamIDs: approvalsWhitelistTeams,
|
||||
BypassUserIDs: bypassAllowlistUsers,
|
||||
BypassTeamIDs: bypassAllowlistTeams,
|
||||
}); err != nil {
|
||||
ctx.ServerError("CreateOrUpdateProtectedBranch", err)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user