feat(actions): rebrand actions bot user and add branch protection whitelist
Branch Policy Check / Verify merge target (pull_request) Successful in 1s
PR RC Release / Build RC Release (pull_request) Successful in 2s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request) Successful in 1m13s

Rebrand the built-in actions bot user from upstream Gitea naming to
MokoGitea branding:
- Name: gitea-actions → mokogitea-actions
- FullName: Gitea Actions → MokoGitea Actions
- Email: teabot@gitea.io → mokogitea-actions[bot]@mokoconsulting.tech

Add backward-compatible name recognition so all three bot name variants
(mokogitea-actions, gitea-actions, github-actions) with optional [bot]
suffix resolve to the same system user.

Add WhitelistActionsUser, MergeWhitelistActionsUser, and
ForcePushAllowlistActionsUser toggles to branch protection rules,
allowing CI/CD workflows to push to protected branches when explicitly
enabled. Previously the actions bot (virtual user ID -2) could never be
added to whitelist because updateUserWhitelist() only validates real
database users.

Closes #233

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan Miller
2026-05-30 10:37:43 -05:00
parent 7959864835
commit d4824dc05b
19 changed files with 168 additions and 23 deletions
+18
View File
@@ -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)
+1
View File
@@ -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
}
+17
View File
@@ -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))
}
+2 -2
View File
@@ -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()
}
+6 -4
View File
@@ -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.
+24 -5
View File
@@ -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
+30 -4
View File
@@ -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)
+9
View File
@@ -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"`
+3
View File
@@ -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.",
+19
View File
@@ -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 {
+1 -1
View File
@@ -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
@@ -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, ","))
+1 -1
View File
@@ -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.
+3
View File
@@ -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,
+3
View File
@@ -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
@@ -88,6 +88,12 @@
<label>{{ctx.Locale.Tr "repo.settings.protect_whitelist_deploy_keys"}}</label>
</div>
</div>
<div class="checkbox-sub-item field">
<div class="ui checkbox">
<input type="checkbox" name="whitelist_actions_user" {{if .Rule.WhitelistActionsUser}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.protect_whitelist_actions_user"}}</label>
</div>
</div>
</div>
</div>
<div class="field">
@@ -158,6 +164,12 @@
<label>{{ctx.Locale.Tr "repo.settings.protect_force_push_allowlist_deploy_keys"}}</label>
</div>
</div>
<div class="checkbox-sub-item field">
<div class="ui checkbox">
<input type="checkbox" name="force_push_allowlist_actions_user" {{if .Rule.ForcePushAllowlistActionsUser}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.protect_force_push_allowlist_actions_user"}}</label>
</div>
</div>
</div>
</div>
<h5 class="ui dividing header">{{ctx.Locale.Tr "repo.settings.event_pull_request_approvals"}}</h5>
@@ -303,6 +315,12 @@
</div>
</div>
{{end}}
<div class="checkbox-sub-item field">
<div class="ui checkbox">
<input type="checkbox" name="merge_whitelist_actions_user" {{if .Rule.MergeWhitelistActionsUser}}checked{{end}}>
<label>{{ctx.Locale.Tr "repo.settings.protect_merge_whitelist_actions_user"}}</label>
</div>
</div>
</div>
</div>
<div class="field">
+4 -4
View File
@@ -149,7 +149,7 @@ func TestActionsJobTokenPermissiveAccess(t *testing.T) {
require.NoError(t, actions_model.UpdateRun(t.Context(), task.Job.Run, "is_fork_pull_request"))
testURL := *u
testURL.User = url.UserPassword("gitea-actions", task.Token)
testURL.User = url.UserPassword("mokogitea-actions", task.Token)
t.Run("ReadGitContent", func(t *testing.T) {
testURL.Path = "/user5/repo4.git/HEAD"
@@ -443,7 +443,7 @@ jobs:
// but it should not have write access
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s/%s.git/info/lfs/objects/batch", user2.Name, repo2.Name), lfs.BatchRequest{Operation: "upload"}).
SetHeader("Accept", lfs.MediaType).
AddBasicAuth("gitea-actions", task1Token)
AddBasicAuth("mokogitea-actions", task1Token)
MakeRequest(t, req, http.StatusUnauthorized)
// set repo1&repo2 max permission to "write" so that the actions token can access code
@@ -465,11 +465,11 @@ jobs:
// now task1 has write access to repo1, but still only read access to repo2 (different repo)
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s/%s.git/info/lfs/objects/batch", user2.Name, repo1.Name), lfs.BatchRequest{Operation: "upload"}).
SetHeader("Accept", lfs.MediaType).
AddBasicAuth("gitea-actions", task1Token)
AddBasicAuth("mokogitea-actions", task1Token)
MakeRequest(t, req, http.StatusOK)
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s/%s.git/info/lfs/objects/batch", user2.Name, repo2.Name), lfs.BatchRequest{Operation: "upload"}).
SetHeader("Accept", lfs.MediaType).
AddBasicAuth("gitea-actions", task1Token)
AddBasicAuth("mokogitea-actions", task1Token)
MakeRequest(t, req, http.StatusUnauthorized)
})
}
+1 -1
View File
@@ -57,7 +57,7 @@ jobs:
// prepare for clone
dstPath := t.TempDir()
u.Path = fmt.Sprintf("%s/%s.git", "user2", "reusable_workflow")
u.User = url.UserPassword("gitea-actions", taskToken)
u.User = url.UserPassword("mokogitea-actions", taskToken)
// the git clone will fail
doGitCloneFail(u)(t)
@@ -21,7 +21,7 @@ func testActionUserSignIn(t *testing.T) {
resp := MakeRequest(t, req, http.StatusOK)
u := DecodeJSON(t, resp, &api.User{})
assert.Equal(t, "gitea-actions", u.UserName)
assert.Equal(t, "mokogitea-actions", u.UserName)
}
func testActionUserAccessPublicRepo(t *testing.T) {