diff --git a/models/git/protected_branch.go b/models/git/protected_branch.go index b96da67b35..1edb05205e 100644 --- a/models/git/protected_branch.go +++ b/models/git/protected_branch.go @@ -48,6 +48,9 @@ type ProtectedBranch struct { ForcePushAllowlistUserIDs []int64 `xorm:"JSON TEXT"` ForcePushAllowlistTeamIDs []int64 `xorm:"JSON TEXT"` ForcePushAllowlistDeployKeys bool `xorm:"NOT NULL DEFAULT false"` + WhitelistActionsUser bool `xorm:"NOT NULL DEFAULT false"` + MergeWhitelistActionsUser bool `xorm:"NOT NULL DEFAULT false"` + ForcePushAllowlistActionsUser bool `xorm:"NOT NULL DEFAULT false"` EnableStatusCheck bool `xorm:"NOT NULL DEFAULT false"` StatusCheckContexts []string `xorm:"JSON TEXT"` EnableApprovalsWhitelist bool `xorm:"NOT NULL DEFAULT false"` @@ -124,6 +127,11 @@ func (protectBranch *ProtectedBranch) CanUserPush(ctx context.Context, user *use return false } + // Allow the actions bot user if explicitly whitelisted. + if user.IsActions() && protectBranch.WhitelistActionsUser { + return true + } + if !protectBranch.EnableWhitelist { if err := protectBranch.LoadRepo(ctx); err != nil { log.Error("LoadRepo: %v", err) @@ -161,6 +169,11 @@ func (protectBranch *ProtectedBranch) CanUserForcePush(ctx context.Context, user return false } + // Allow the actions bot user if explicitly whitelisted. + if user.IsActions() && protectBranch.ForcePushAllowlistActionsUser { + return protectBranch.CanUserPush(ctx, user) + } + if !protectBranch.EnableForcePushAllowlist { return protectBranch.CanUserPush(ctx, user) } @@ -183,6 +196,11 @@ func (protectBranch *ProtectedBranch) CanUserForcePush(ctx context.Context, user // IsUserMergeWhitelisted checks if some user is whitelisted to merge to this branch func IsUserMergeWhitelisted(ctx context.Context, protectBranch *ProtectedBranch, userID int64, permissionInRepo access_model.Permission) bool { + // Allow the actions bot user if explicitly whitelisted. + if userID == user_model.ActionsUserID && protectBranch.MergeWhitelistActionsUser { + return true + } + if !protectBranch.EnableMergeWhitelist { // Then we need to fall back on whether the user has write permission return permissionInRepo.CanWrite(unit.TypeCode) diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index e362332ca5..bb5774a26f 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -411,6 +411,7 @@ func prepareMigrationTasks() []*migration { newMigration(331, "Add ActionRunAttempt model and related action fields", v1_27.AddActionRunAttemptModel), newMigration(332, "Add org-level branch protection rulesets", v1_27.AddOrgProtectedBranchTable), newMigration(333, "Add require_2fa to user table for org enforcement", v1_27.AddRequire2FAToUser), + newMigration(334, "Add actions user whitelist to protected branches", v1_27.AddActionsUserWhitelistToProtectedBranch), } return preparedMigrations } diff --git a/models/migrations/v1_27/v334.go b/models/migrations/v1_27/v334.go new file mode 100644 index 0000000000..aeb8ed8efa --- /dev/null +++ b/models/migrations/v1_27/v334.go @@ -0,0 +1,17 @@ +// Copyright 2026 The MokoGitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_27 + +import "xorm.io/xorm" + +// AddActionsUserWhitelistToProtectedBranch adds toggle fields that allow +// the built-in actions bot user to bypass branch protection rules. +func AddActionsUserWhitelistToProtectedBranch(x *xorm.Engine) error { + type ProtectedBranch struct { + WhitelistActionsUser bool `xorm:"NOT NULL DEFAULT false"` + MergeWhitelistActionsUser bool `xorm:"NOT NULL DEFAULT false"` + ForcePushAllowlistActionsUser bool `xorm:"NOT NULL DEFAULT false"` + } + return x.Sync(new(ProtectedBranch)) +} diff --git a/models/user/avatar.go b/models/user/avatar.go index 291d1467bb..c691357509 100644 --- a/models/user/avatar.go +++ b/models/user/avatar.go @@ -54,9 +54,9 @@ func GenerateRandomAvatar(ctx context.Context, u *User) error { // AvatarLinkWithSize returns a link to the user's avatar with size. size <= 0 means default size func (u *User) AvatarLinkWithSize(ctx context.Context, size int) string { - // ghost user was deleted, Gitea actions is a bot user, 0 means the user should be a virtual user + // ghost user was deleted, actions bot is a system user, 0 means the user should be a virtual user // which comes from git configure information - if u.IsGhost() || u.IsGiteaActions() || u.ID <= 0 { + if u.IsGhost() || u.IsActions() || u.ID <= 0 { return avatars.DefaultAvatarLink() } diff --git a/models/user/user.go b/models/user/user.go index f7dcc407e8..435b7af250 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -510,9 +510,9 @@ func (u *User) GitName() string { } // IsMailable checks if a user is eligible to receive emails. -// System users like Ghost and Gitea Actions are excluded. +// System users like Ghost and the actions bot are excluded. func (u *User) IsMailable() bool { - return u.IsActive && !u.IsGiteaActions() && !u.IsGhost() + return u.IsActive && !u.IsActions() && !u.IsGhost() } // IsUserExist checks if given username exist, @@ -627,8 +627,10 @@ var ( "swagger.v1.json", "openapi3.v1.json", - "ghost", // reserved name for deleted users (id: -1) - "gitea-actions", // gitea builtin user (id: -2) + "ghost", // reserved name for deleted users (id: -1) + "mokogitea-actions", // actions bot user (id: -2) + "gitea-actions", // legacy actions bot name + "github-actions", // legacy actions bot name } // These names are reserved for user accounts: user's keys, user's rss feed, user's avatar, etc. diff --git a/models/user/user_system.go b/models/user/user_system.go index 5671e45487..09703acdab 100644 --- a/models/user/user_system.go +++ b/models/user/user_system.go @@ -34,8 +34,12 @@ func (u *User) IsGhost() bool { const ( ActionsUserID int64 = -2 - ActionsUserName = "gitea-actions" - ActionsUserEmail = "teabot@gitea.io" + ActionsUserName = "mokogitea-actions" + ActionsUserEmail = "mokogitea-actions[bot]@mokoconsulting.tech" + + // Legacy names recognized as aliases for the actions bot user. + ActionsUserNameLegacyGitea = "gitea-actions" + ActionsUserNameLegacyGitHub = "github-actions" ) // NewActionsUser creates and returns a fake user for running the actions. @@ -45,7 +49,7 @@ func NewActionsUser() *User { Name: ActionsUserName, LowerName: ActionsUserName, IsActive: true, - FullName: "Gitea Actions", + FullName: "MokoGitea Actions", Email: ActionsUserEmail, KeepEmailPrivate: true, LoginName: ActionsUserName, @@ -75,15 +79,30 @@ func GetActionsUserTaskID(u *User) (int64, bool) { return 0, false } -func (u *User) IsGiteaActions() bool { +// IsActions checks whether this user is the built-in actions bot. +func (u *User) IsActions() bool { return u != nil && u.ID == ActionsUserID } +// IsGiteaActions is a deprecated alias for IsActions. +func (u *User) IsGiteaActions() bool { + return u.IsActions() +} + +// isActionsName returns true if the given name (case-insensitive, with +// optional "[bot]" suffix stripped) matches any known actions bot name. +func isActionsName(name string) bool { + clean := strings.TrimSuffix(name, "[bot]") + return strings.EqualFold(clean, ActionsUserName) || + strings.EqualFold(clean, ActionsUserNameLegacyGitea) || + strings.EqualFold(clean, ActionsUserNameLegacyGitHub) +} + func GetSystemUserByName(name string) *User { if strings.EqualFold(name, GhostUserName) { return NewGhostUser() } - if strings.EqualFold(name, ActionsUserName) { + if isActionsName(name) { return NewActionsUser() } return nil diff --git a/models/user/user_system_test.go b/models/user/user_system_test.go index 3ae9c6e366..ae3eec81fd 100644 --- a/models/user/user_system_test.go +++ b/models/user/user_system_test.go @@ -25,13 +25,39 @@ func TestSystemUser(t *testing.T) { uid, u, err = GetPossibleUserByID(t.Context(), -2) require.NoError(t, err) assert.Equal(t, int64(-2), uid) - assert.Equal(t, "gitea-actions", u.Name) - assert.Equal(t, "gitea-actions", u.LowerName) - assert.True(t, u.IsGiteaActions()) + assert.Equal(t, "mokogitea-actions", u.Name) + assert.Equal(t, "mokogitea-actions", u.LowerName) + assert.True(t, u.IsActions()) + assert.True(t, u.IsGiteaActions()) // deprecated alias + // canonical name lookup + u = GetSystemUserByName("mokogitea-actions") + require.NotNil(t, u) + assert.Equal(t, "MokoGitea Actions", u.FullName) + + // legacy name lookups u = GetSystemUserByName("Gitea-actionS") require.NotNil(t, u) - assert.Equal(t, "Gitea Actions", u.FullName) + assert.Equal(t, "MokoGitea Actions", u.FullName) + + u = GetSystemUserByName("github-actions") + require.NotNil(t, u) + assert.Equal(t, "MokoGitea Actions", u.FullName) + + // [bot] suffix lookups + u = GetSystemUserByName("mokogitea-actions[bot]") + require.NotNil(t, u) + assert.Equal(t, "MokoGitea Actions", u.FullName) + + u = GetSystemUserByName("gitea-actions[bot]") + require.NotNil(t, u) + + u = GetSystemUserByName("github-actions[bot]") + require.NotNil(t, u) + + // unknown name returns nil + u = GetSystemUserByName("unknown-bot") + assert.Nil(t, u) uid, u, err = GetPossibleUserByID(t.Context(), 999999) require.NoError(t, err) diff --git a/modules/structs/repo_branch.go b/modules/structs/repo_branch.go index dee9490998..77b82a11a4 100644 --- a/modules/structs/repo_branch.go +++ b/modules/structs/repo_branch.go @@ -42,14 +42,17 @@ type BranchProtection struct { PushWhitelistUsernames []string `json:"push_whitelist_usernames"` PushWhitelistTeams []string `json:"push_whitelist_teams"` PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"` + PushWhitelistActionsUser bool `json:"push_whitelist_actions_user"` EnableForcePush bool `json:"enable_force_push"` EnableForcePushAllowlist bool `json:"enable_force_push_allowlist"` ForcePushAllowlistUsernames []string `json:"force_push_allowlist_usernames"` ForcePushAllowlistTeams []string `json:"force_push_allowlist_teams"` ForcePushAllowlistDeployKeys bool `json:"force_push_allowlist_deploy_keys"` + ForcePushAllowlistActionsUser bool `json:"force_push_allowlist_actions_user"` EnableMergeWhitelist bool `json:"enable_merge_whitelist"` MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` MergeWhitelistTeams []string `json:"merge_whitelist_teams"` + MergeWhitelistActionsUser bool `json:"merge_whitelist_actions_user"` EnableStatusCheck bool `json:"enable_status_check"` StatusCheckContexts []string `json:"status_check_contexts"` RequiredApprovals int64 `json:"required_approvals"` @@ -84,14 +87,17 @@ type CreateBranchProtectionOption struct { PushWhitelistUsernames []string `json:"push_whitelist_usernames"` PushWhitelistTeams []string `json:"push_whitelist_teams"` PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"` + PushWhitelistActionsUser bool `json:"push_whitelist_actions_user"` EnableForcePush bool `json:"enable_force_push"` EnableForcePushAllowlist bool `json:"enable_force_push_allowlist"` ForcePushAllowlistUsernames []string `json:"force_push_allowlist_usernames"` ForcePushAllowlistTeams []string `json:"force_push_allowlist_teams"` ForcePushAllowlistDeployKeys bool `json:"force_push_allowlist_deploy_keys"` + ForcePushAllowlistActionsUser bool `json:"force_push_allowlist_actions_user"` EnableMergeWhitelist bool `json:"enable_merge_whitelist"` MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` MergeWhitelistTeams []string `json:"merge_whitelist_teams"` + MergeWhitelistActionsUser bool `json:"merge_whitelist_actions_user"` EnableStatusCheck bool `json:"enable_status_check"` StatusCheckContexts []string `json:"status_check_contexts"` RequiredApprovals int64 `json:"required_approvals"` @@ -117,14 +123,17 @@ type EditBranchProtectionOption struct { PushWhitelistUsernames []string `json:"push_whitelist_usernames"` PushWhitelistTeams []string `json:"push_whitelist_teams"` PushWhitelistDeployKeys *bool `json:"push_whitelist_deploy_keys"` + PushWhitelistActionsUser *bool `json:"push_whitelist_actions_user"` EnableForcePush *bool `json:"enable_force_push"` EnableForcePushAllowlist *bool `json:"enable_force_push_allowlist"` ForcePushAllowlistUsernames []string `json:"force_push_allowlist_usernames"` ForcePushAllowlistTeams []string `json:"force_push_allowlist_teams"` ForcePushAllowlistDeployKeys *bool `json:"force_push_allowlist_deploy_keys"` + ForcePushAllowlistActionsUser *bool `json:"force_push_allowlist_actions_user"` EnableMergeWhitelist *bool `json:"enable_merge_whitelist"` MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` MergeWhitelistTeams []string `json:"merge_whitelist_teams"` + MergeWhitelistActionsUser *bool `json:"merge_whitelist_actions_user"` EnableStatusCheck *bool `json:"enable_status_check"` StatusCheckContexts []string `json:"status_check_contexts"` RequiredApprovals *int64 `json:"required_approvals"` diff --git a/options/locale/locale_en-US.json b/options/locale/locale_en-US.json index 5c780182f0..cf91027ca8 100644 --- a/options/locale/locale_en-US.json +++ b/options/locale/locale_en-US.json @@ -2404,15 +2404,18 @@ "repo.settings.protect_whitelist_committers": "Allowlist Restricted Push", "repo.settings.protect_whitelist_committers_desc": "Only allowlisted users or teams will be allowed to push to this branch (but not force push).", "repo.settings.protect_whitelist_deploy_keys": "Allowlist deploy keys with write access to push.", + "repo.settings.protect_whitelist_actions_user": "Allowlist actions bot user to push.", "repo.settings.protect_whitelist_users": "Allowlisted users for pushing:", "repo.settings.protect_whitelist_teams": "Allowlisted teams for pushing:", "repo.settings.protect_force_push_allowlist_users": "Allowlisted users for force pushing:", "repo.settings.protect_force_push_allowlist_teams": "Allowlisted teams for force pushing:", "repo.settings.protect_force_push_allowlist_deploy_keys": "Allowlist deploy keys with push access to force push.", + "repo.settings.protect_force_push_allowlist_actions_user": "Allowlist actions bot user to force push.", "repo.settings.protect_merge_whitelist_committers": "Enable Merge Allowlist", "repo.settings.protect_merge_whitelist_committers_desc": "Allow only allowlisted users or teams to merge pull requests into this branch.", "repo.settings.protect_merge_whitelist_users": "Allowlisted users for merging:", "repo.settings.protect_merge_whitelist_teams": "Allowlisted teams for merging:", + "repo.settings.protect_merge_whitelist_actions_user": "Allowlist actions bot user to merge.", "repo.settings.protect_check_status_contexts": "Enable Status Check", "repo.settings.protect_status_check_patterns": "Status check patterns:", "repo.settings.protect_status_check_patterns_desc": "Enter patterns to specify which status checks must pass before branches can be merged into a branch that matches this rule. Each line specifies a pattern. Patterns cannot be empty.", diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 4bbc5fc411..5aa5f5813a 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -758,10 +758,13 @@ func CreateBranchProtection(ctx *context.APIContext) { CanPush: form.EnablePush, EnableWhitelist: form.EnablePush && form.EnablePushWhitelist, WhitelistDeployKeys: form.EnablePush && form.EnablePushWhitelist && form.PushWhitelistDeployKeys, + WhitelistActionsUser: form.EnablePush && form.EnablePushWhitelist && form.PushWhitelistActionsUser, CanForcePush: form.EnablePush && form.EnableForcePush, EnableForcePushAllowlist: form.EnablePush && form.EnableForcePush && form.EnableForcePushAllowlist, ForcePushAllowlistDeployKeys: form.EnablePush && form.EnableForcePush && form.EnableForcePushAllowlist && form.ForcePushAllowlistDeployKeys, + ForcePushAllowlistActionsUser: form.EnablePush && form.EnableForcePush && form.EnableForcePushAllowlist && form.ForcePushAllowlistActionsUser, EnableMergeWhitelist: form.EnableMergeWhitelist, + MergeWhitelistActionsUser: form.EnableMergeWhitelist && form.MergeWhitelistActionsUser, EnableStatusCheck: form.EnableStatusCheck, StatusCheckContexts: form.StatusCheckContexts, EnableApprovalsWhitelist: form.EnableApprovalsWhitelist, @@ -861,17 +864,22 @@ func EditBranchProtection(ctx *context.APIContext) { protectBranch.CanPush = false protectBranch.EnableWhitelist = false protectBranch.WhitelistDeployKeys = false + protectBranch.WhitelistActionsUser = false } else { protectBranch.CanPush = true if form.EnablePushWhitelist != nil { if !*form.EnablePushWhitelist { protectBranch.EnableWhitelist = false protectBranch.WhitelistDeployKeys = false + protectBranch.WhitelistActionsUser = false } else { protectBranch.EnableWhitelist = true if form.PushWhitelistDeployKeys != nil { protectBranch.WhitelistDeployKeys = *form.PushWhitelistDeployKeys } + if form.PushWhitelistActionsUser != nil { + protectBranch.WhitelistActionsUser = *form.PushWhitelistActionsUser + } } } } @@ -882,17 +890,22 @@ func EditBranchProtection(ctx *context.APIContext) { protectBranch.CanForcePush = false protectBranch.EnableForcePushAllowlist = false protectBranch.ForcePushAllowlistDeployKeys = false + protectBranch.ForcePushAllowlistActionsUser = false } else { protectBranch.CanForcePush = true if form.EnableForcePushAllowlist != nil { if !*form.EnableForcePushAllowlist { protectBranch.EnableForcePushAllowlist = false protectBranch.ForcePushAllowlistDeployKeys = false + protectBranch.ForcePushAllowlistActionsUser = false } else { protectBranch.EnableForcePushAllowlist = true if form.ForcePushAllowlistDeployKeys != nil { protectBranch.ForcePushAllowlistDeployKeys = *form.ForcePushAllowlistDeployKeys } + if form.ForcePushAllowlistActionsUser != nil { + protectBranch.ForcePushAllowlistActionsUser = *form.ForcePushAllowlistActionsUser + } } } } @@ -904,6 +917,12 @@ func EditBranchProtection(ctx *context.APIContext) { if form.EnableMergeWhitelist != nil { protectBranch.EnableMergeWhitelist = *form.EnableMergeWhitelist + if !*form.EnableMergeWhitelist { + protectBranch.MergeWhitelistActionsUser = false + } + } + if form.MergeWhitelistActionsUser != nil && protectBranch.EnableMergeWhitelist { + protectBranch.MergeWhitelistActionsUser = *form.MergeWhitelistActionsUser } if form.EnableStatusCheck != nil { diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go index c73ecc0814..2e2c3f3b01 100644 --- a/routers/web/repo/githttp.go +++ b/routers/web/repo/githttp.go @@ -162,7 +162,7 @@ func httpBase(ctx *context.Context, optGitService ...string) *serviceHandler { return nil } - if ctx.IsBasicAuth && ctx.Data["IsApiToken"] != true && !ctx.Doer.IsGiteaActions() { + if ctx.IsBasicAuth && ctx.Data["IsApiToken"] != true && !ctx.Doer.IsActions() { _, err = auth_model.GetTwoFactorByUID(ctx, ctx.Doer.ID) if err == nil { // TODO: This response should be changed to "invalid credentials" for security reasons once the expectation behind it (creating an app token to authenticate) is properly documented diff --git a/routers/web/repo/setting/protected_branch.go b/routers/web/repo/setting/protected_branch.go index d983a08c19..14f37a9bad 100644 --- a/routers/web/repo/setting/protected_branch.go +++ b/routers/web/repo/setting/protected_branch.go @@ -168,10 +168,12 @@ func SettingsProtectedBranchPost(ctx *context.Context) { protectBranch.CanPush = true protectBranch.EnableWhitelist = false protectBranch.WhitelistDeployKeys = false + protectBranch.WhitelistActionsUser = false case "whitelist": protectBranch.CanPush = true protectBranch.EnableWhitelist = true protectBranch.WhitelistDeployKeys = f.WhitelistDeployKeys + protectBranch.WhitelistActionsUser = f.WhitelistActionsUser if strings.TrimSpace(f.WhitelistUsers) != "" { whitelistUsers, _ = base.StringsToInt64s(strings.Split(f.WhitelistUsers, ",")) } @@ -182,6 +184,7 @@ func SettingsProtectedBranchPost(ctx *context.Context) { protectBranch.CanPush = false protectBranch.EnableWhitelist = false protectBranch.WhitelistDeployKeys = false + protectBranch.WhitelistActionsUser = false } switch f.EnableForcePush { @@ -189,10 +192,12 @@ func SettingsProtectedBranchPost(ctx *context.Context) { protectBranch.CanForcePush = true protectBranch.EnableForcePushAllowlist = false protectBranch.ForcePushAllowlistDeployKeys = false + protectBranch.ForcePushAllowlistActionsUser = false case "whitelist": protectBranch.CanForcePush = true protectBranch.EnableForcePushAllowlist = true protectBranch.ForcePushAllowlistDeployKeys = f.ForcePushAllowlistDeployKeys + protectBranch.ForcePushAllowlistActionsUser = f.ForcePushAllowlistActionsUser if strings.TrimSpace(f.ForcePushAllowlistUsers) != "" { forcePushAllowlistUsers, _ = base.StringsToInt64s(strings.Split(f.ForcePushAllowlistUsers, ",")) } @@ -203,9 +208,11 @@ func SettingsProtectedBranchPost(ctx *context.Context) { protectBranch.CanForcePush = false protectBranch.EnableForcePushAllowlist = false protectBranch.ForcePushAllowlistDeployKeys = false + protectBranch.ForcePushAllowlistActionsUser = false } protectBranch.EnableMergeWhitelist = f.EnableMergeWhitelist + protectBranch.MergeWhitelistActionsUser = f.EnableMergeWhitelist && f.MergeWhitelistActionsUser if f.EnableMergeWhitelist { if strings.TrimSpace(f.MergeWhitelistUsers) != "" { mergeWhitelistUsers, _ = base.StringsToInt64s(strings.Split(f.MergeWhitelistUsers, ",")) diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index f528ca36d0..1a055ced6e 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -118,7 +118,7 @@ func (input *notifyInput) Notify(ctx context.Context) { func notify(ctx context.Context, input *notifyInput) error { shouldDetectSchedules := input.Event == webhook_module.HookEventPush && input.Ref.BranchName() == input.Repo.DefaultBranch - if input.Doer.IsGiteaActions() { + if input.Doer.IsActions() { // avoiding triggering cyclically, for example: // a comment of an issue will trigger the runner to add a new comment as reply, // and the new comment will trigger the runner again. diff --git a/services/convert/convert.go b/services/convert/convert.go index d543c1a731..2bc181de9a 100644 --- a/services/convert/convert.go +++ b/services/convert/convert.go @@ -173,14 +173,17 @@ func ToBranchProtection(ctx context.Context, bp *git_model.ProtectedBranch, repo PushWhitelistUsernames: pushWhitelistUsernames, PushWhitelistTeams: pushWhitelistTeams, PushWhitelistDeployKeys: bp.WhitelistDeployKeys, + PushWhitelistActionsUser: bp.WhitelistActionsUser, EnableForcePush: bp.CanForcePush, EnableForcePushAllowlist: bp.EnableForcePushAllowlist, ForcePushAllowlistUsernames: forcePushAllowlistUsernames, ForcePushAllowlistTeams: forcePushAllowlistTeams, ForcePushAllowlistDeployKeys: bp.ForcePushAllowlistDeployKeys, + ForcePushAllowlistActionsUser: bp.ForcePushAllowlistActionsUser, EnableMergeWhitelist: bp.EnableMergeWhitelist, MergeWhitelistUsernames: mergeWhitelistUsernames, MergeWhitelistTeams: mergeWhitelistTeams, + MergeWhitelistActionsUser: bp.MergeWhitelistActionsUser, EnableStatusCheck: bp.EnableStatusCheck, StatusCheckContexts: bp.StatusCheckContexts, RequiredApprovals: bp.RequiredApprovals, diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 5899af498b..20aff24682 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -172,13 +172,16 @@ type ProtectBranchForm struct { WhitelistUsers string WhitelistTeams string WhitelistDeployKeys bool + WhitelistActionsUser bool EnableForcePush string ForcePushAllowlistUsers string ForcePushAllowlistTeams string ForcePushAllowlistDeployKeys bool + ForcePushAllowlistActionsUser bool EnableMergeWhitelist bool MergeWhitelistUsers string MergeWhitelistTeams string + MergeWhitelistActionsUser bool EnableStatusCheck bool StatusCheckContexts string RequiredApprovals int64 diff --git a/templates/repo/settings/protected_branch.tmpl b/templates/repo/settings/protected_branch.tmpl index fc26c3b517..01803890c3 100644 --- a/templates/repo/settings/protected_branch.tmpl +++ b/templates/repo/settings/protected_branch.tmpl @@ -88,6 +88,12 @@ +