Compare commits

...

1 Commits

Author SHA1 Message Date
jmiller 56e65268d7 feat: org branch protection user allowlists + actions-bot toggles (#734)
Org-level branch protection rules previously supported team-only
allowlists. This adds per-user allowlists (resolved by username OR
email) and "allow the actions bot" toggles for the push, merge and
force-push allowlists, plus a per-user approvals allowlist -- mirroring
the repo-level ProtectedBranch fields exactly. These carry through
ToProtectedBranch() into the standard enforcement path.

Model: add WhitelistUserIDs/MergeWhitelistUserIDs/
ForcePushAllowlistUserIDs/ApprovalsWhitelistUserIDs ([]int64 JSON) and
WhitelistActionsUser/MergeWhitelistActionsUser/
ForcePushAllowlistActionsUser (bool) to OrgProtectedBranch, and copy
them in ToProtectedBranch().

Migration 362 (v368-style file v363.go): additive columns via x.Sync.

API: new resolveUserIDs helper (username-then-email lookup, dedupe,
422 on unknown); Create/Edit set the new fields gated on the matching
Enable* flags; GET resolves stored user IDs back to usernames and
returns the actions-user bools.

DTOs: add *Usernames []string + *ActionsUser bool to the Create/Edit/
response structs, using the same json names as repo_branch.go.

Swagger: register OrgBranchProtection(/List) responses and the
Create/Edit option bodies; regenerate specs for the org endpoints.

Delete allowlists are intentionally omitted -- org branch protection
has no delete-allowlist concept (no CanDelete/EnableDeleteAllowlist/
DeleteAllowlistTeamIDs), so there is no team allowlist to extend.

Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
2026-07-05 17:17:20 -05:00
10 changed files with 1699 additions and 4 deletions
+18 -2
View File
@@ -28,16 +28,23 @@ type OrgProtectedBranch struct {
CanPush bool `xorm:"NOT NULL DEFAULT false"`
EnableWhitelist bool `xorm:"NOT NULL DEFAULT false"`
WhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
WhitelistUserIDs []int64 `xorm:"JSON TEXT"`
WhitelistActionsUser bool `xorm:"NOT NULL DEFAULT false"`
EnableMergeWhitelist bool `xorm:"NOT NULL DEFAULT false"`
MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
MergeWhitelistActionsUser bool `xorm:"NOT NULL DEFAULT false"`
CanForcePush bool `xorm:"NOT NULL DEFAULT false"`
EnableForcePushAllowlist bool `xorm:"NOT NULL DEFAULT false"`
ForcePushAllowlistTeamIDs []int64 `xorm:"JSON TEXT"`
ForcePushAllowlistUserIDs []int64 `xorm:"JSON TEXT"`
ForcePushAllowlistActionsUser bool `xorm:"NOT NULL DEFAULT false"`
EnableStatusCheck bool `xorm:"NOT NULL DEFAULT false"`
StatusCheckContexts []string `xorm:"JSON TEXT"`
RequiredApprovals int64 `xorm:"NOT NULL DEFAULT 0"`
EnableApprovalsWhitelist bool `xorm:"NOT NULL DEFAULT false"`
ApprovalsWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
ApprovalsWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
BlockOnRejectedReviews bool `xorm:"NOT NULL DEFAULT false"`
BlockOnOfficialReviewRequests bool `xorm:"NOT NULL DEFAULT false"`
BlockOnOutdatedBranch bool `xorm:"NOT NULL DEFAULT false"`
@@ -81,8 +88,10 @@ func (o *OrgProtectedBranch) Match(branchName string) bool {
}
// ToProtectedBranch converts an org-level rule to a ProtectedBranch for use
// in the standard enforcement path. Fields that are user-scoped (WhitelistUserIDs etc.)
// are left empty because org rules only reference teams.
// in the standard enforcement path. Both team-scoped and user-scoped allowlists
// (plus the "allow the actions bot" toggles) are carried over so org rules can
// grant push/merge/force-push/approval access to individual users and the actions
// bot, in addition to teams.
func (o *OrgProtectedBranch) ToProtectedBranch() *ProtectedBranch {
return &ProtectedBranch{
ID: o.ID,
@@ -91,16 +100,23 @@ func (o *OrgProtectedBranch) ToProtectedBranch() *ProtectedBranch {
CanPush: o.CanPush,
EnableWhitelist: o.EnableWhitelist,
WhitelistTeamIDs: o.WhitelistTeamIDs,
WhitelistUserIDs: o.WhitelistUserIDs,
WhitelistActionsUser: o.WhitelistActionsUser,
EnableMergeWhitelist: o.EnableMergeWhitelist,
MergeWhitelistTeamIDs: o.MergeWhitelistTeamIDs,
MergeWhitelistUserIDs: o.MergeWhitelistUserIDs,
MergeWhitelistActionsUser: o.MergeWhitelistActionsUser,
CanForcePush: o.CanForcePush,
EnableForcePushAllowlist: o.EnableForcePushAllowlist,
ForcePushAllowlistTeamIDs: o.ForcePushAllowlistTeamIDs,
ForcePushAllowlistUserIDs: o.ForcePushAllowlistUserIDs,
ForcePushAllowlistActionsUser: o.ForcePushAllowlistActionsUser,
EnableStatusCheck: o.EnableStatusCheck,
StatusCheckContexts: o.StatusCheckContexts,
RequiredApprovals: o.RequiredApprovals,
EnableApprovalsWhitelist: o.EnableApprovalsWhitelist,
ApprovalsWhitelistTeamIDs: o.ApprovalsWhitelistTeamIDs,
ApprovalsWhitelistUserIDs: o.ApprovalsWhitelistUserIDs,
BlockOnRejectedReviews: o.BlockOnRejectedReviews,
BlockOnOfficialReviewRequests: o.BlockOnOfficialReviewRequests,
BlockOnOutdatedBranch: o.BlockOnOutdatedBranch,
+84
View File
@@ -0,0 +1,84 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package git
import (
"testing"
"github.com/stretchr/testify/assert"
)
// TestOrgProtectedBranchToProtectedBranch verifies that the org-level rule carries
// its team allowlists, user allowlists and actions-user toggles across to the
// standard ProtectedBranch used by the enforcement path.
func TestOrgProtectedBranchToProtectedBranch(t *testing.T) {
org := &OrgProtectedBranch{
ID: 7,
RuleName: "main",
Priority: 3,
CanPush: true,
EnableWhitelist: true,
WhitelistTeamIDs: []int64{1, 2},
WhitelistUserIDs: []int64{10, 11},
WhitelistActionsUser: true,
EnableMergeWhitelist: true,
MergeWhitelistTeamIDs: []int64{3},
MergeWhitelistUserIDs: []int64{12},
MergeWhitelistActionsUser: true,
CanForcePush: true,
EnableForcePushAllowlist: true,
ForcePushAllowlistTeamIDs: []int64{4},
ForcePushAllowlistUserIDs: []int64{13, 14},
ForcePushAllowlistActionsUser: true,
RequiredApprovals: 2,
EnableApprovalsWhitelist: true,
ApprovalsWhitelistTeamIDs: []int64{5},
ApprovalsWhitelistUserIDs: []int64{15},
}
pb := org.ToProtectedBranch()
// Push allowlist
assert.Equal(t, []int64{1, 2}, pb.WhitelistTeamIDs)
assert.Equal(t, []int64{10, 11}, pb.WhitelistUserIDs)
assert.True(t, pb.WhitelistActionsUser)
// Merge allowlist
assert.Equal(t, []int64{3}, pb.MergeWhitelistTeamIDs)
assert.Equal(t, []int64{12}, pb.MergeWhitelistUserIDs)
assert.True(t, pb.MergeWhitelistActionsUser)
// Force-push allowlist
assert.Equal(t, []int64{4}, pb.ForcePushAllowlistTeamIDs)
assert.Equal(t, []int64{13, 14}, pb.ForcePushAllowlistUserIDs)
assert.True(t, pb.ForcePushAllowlistActionsUser)
// Approvals allowlist (no actions-user at the approval stage, matching repo-level)
assert.Equal(t, []int64{5}, pb.ApprovalsWhitelistTeamIDs)
assert.Equal(t, []int64{15}, pb.ApprovalsWhitelistUserIDs)
// Sanity: identity fields propagate
assert.Equal(t, int64(7), pb.ID)
assert.Equal(t, "main", pb.RuleName)
assert.Equal(t, int64(3), pb.Priority)
assert.EqualValues(t, 2, pb.RequiredApprovals)
}
// TestOrgProtectedBranchToProtectedBranchEmpty verifies that when the org rule does
// not grant actions-user access, the toggles remain false (opt-in semantics).
func TestOrgProtectedBranchToProtectedBranchEmpty(t *testing.T) {
pb := (&OrgProtectedBranch{RuleName: "release/*"}).ToProtectedBranch()
assert.False(t, pb.WhitelistActionsUser)
assert.False(t, pb.MergeWhitelistActionsUser)
assert.False(t, pb.ForcePushAllowlistActionsUser)
assert.Nil(t, pb.WhitelistUserIDs)
assert.Nil(t, pb.MergeWhitelistUserIDs)
assert.Nil(t, pb.ForcePushAllowlistUserIDs)
assert.Nil(t, pb.ApprovalsWhitelistUserIDs)
}
+1
View File
@@ -439,6 +439,7 @@ func prepareMigrationTasks() []*migration {
newMigration(359, "Add deploy fields to repo manifest", v1_27.AddDeployFieldsToRepoManifest),
newMigration(360, "Add delete allowlist to protected branch", v1_27.AddDeleteAllowlistToProtectedBranch),
newMigration(361, "Add cascade merge rule table", v1_27.AddCascadeMergeRuleTable),
newMigration(362, "Add user allowlists and actions-user toggles to org protected branch", v1_27.AddUserAllowlistsToOrgProtectedBranch),
}
return preparedMigrations
}
+24
View File
@@ -0,0 +1,24 @@
// Copyright 2026 Moko Consulting <hello@mokoconsulting.tech>
// SPDX-License-Identifier: GPL-3.0-or-later
package v1_27
import (
"xorm.io/xorm"
)
// AddUserAllowlistsToOrgProtectedBranch adds per-user allowlists (by user ID) and
// "allow the actions bot" toggles to org-level branch protection rules, alongside
// the existing team-only allowlists. Additive columns only.
func AddUserAllowlistsToOrgProtectedBranch(x *xorm.Engine) error {
type OrgProtectedBranch struct {
WhitelistUserIDs []int64 `xorm:"JSON TEXT"`
WhitelistActionsUser bool `xorm:"NOT NULL DEFAULT false"`
MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
MergeWhitelistActionsUser bool `xorm:"NOT NULL DEFAULT false"`
ForcePushAllowlistUserIDs []int64 `xorm:"JSON TEXT"`
ForcePushAllowlistActionsUser bool `xorm:"NOT NULL DEFAULT false"`
ApprovalsWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
}
return x.Sync(new(OrgProtectedBranch))
}
+21
View File
@@ -14,16 +14,23 @@ type OrgBranchProtection struct {
EnablePush bool `json:"enable_push"`
EnablePushWhitelist bool `json:"enable_push_whitelist"`
PushWhitelistTeams []string `json:"push_whitelist_teams"`
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
PushWhitelistActionsUser bool `json:"push_whitelist_actions_user"`
EnableForcePush bool `json:"enable_force_push"`
EnableForcePushAllowlist bool `json:"enable_force_push_allowlist"`
ForcePushAllowlistTeams []string `json:"force_push_allowlist_teams"`
ForcePushAllowlistUsernames []string `json:"force_push_allowlist_usernames"`
ForcePushAllowlistActionsUser bool `json:"force_push_allowlist_actions_user"`
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
MergeWhitelistActionsUser bool `json:"merge_whitelist_actions_user"`
EnableStatusCheck bool `json:"enable_status_check"`
StatusCheckContexts []string `json:"status_check_contexts"`
RequiredApprovals int64 `json:"required_approvals"`
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"`
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"`
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests"`
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"`
@@ -46,16 +53,23 @@ type CreateOrgBranchProtectionOption struct {
EnablePush bool `json:"enable_push"`
EnablePushWhitelist bool `json:"enable_push_whitelist"`
PushWhitelistTeams []string `json:"push_whitelist_teams"`
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
PushWhitelistActionsUser bool `json:"push_whitelist_actions_user"`
EnableForcePush bool `json:"enable_force_push"`
EnableForcePushAllowlist bool `json:"enable_force_push_allowlist"`
ForcePushAllowlistTeams []string `json:"force_push_allowlist_teams"`
ForcePushAllowlistUsernames []string `json:"force_push_allowlist_usernames"`
ForcePushAllowlistActionsUser bool `json:"force_push_allowlist_actions_user"`
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
MergeWhitelistActionsUser bool `json:"merge_whitelist_actions_user"`
EnableStatusCheck bool `json:"enable_status_check"`
StatusCheckContexts []string `json:"status_check_contexts"`
RequiredApprovals int64 `json:"required_approvals"`
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"`
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"`
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests"`
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"`
@@ -73,16 +87,23 @@ type EditOrgBranchProtectionOption struct {
EnablePush *bool `json:"enable_push"`
EnablePushWhitelist *bool `json:"enable_push_whitelist"`
PushWhitelistTeams []string `json:"push_whitelist_teams"`
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
PushWhitelistActionsUser *bool `json:"push_whitelist_actions_user"`
EnableForcePush *bool `json:"enable_force_push"`
EnableForcePushAllowlist *bool `json:"enable_force_push_allowlist"`
ForcePushAllowlistTeams []string `json:"force_push_allowlist_teams"`
ForcePushAllowlistUsernames []string `json:"force_push_allowlist_usernames"`
ForcePushAllowlistActionsUser *bool `json:"force_push_allowlist_actions_user"`
EnableMergeWhitelist *bool `json:"enable_merge_whitelist"`
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
MergeWhitelistActionsUser *bool `json:"merge_whitelist_actions_user"`
EnableStatusCheck *bool `json:"enable_status_check"`
StatusCheckContexts []string `json:"status_check_contexts"`
RequiredApprovals *int64 `json:"required_approvals"`
EnableApprovalsWhitelist *bool `json:"enable_approvals_whitelist"`
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
BlockOnRejectedReviews *bool `json:"block_on_rejected_reviews"`
BlockOnOfficialReviewRequests *bool `json:"block_on_official_review_requests"`
BlockOnOutdatedBranch *bool `json:"block_on_outdated_branch"`
+125 -2
View File
@@ -8,6 +8,7 @@ import (
git_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/git"
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/organization"
user_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/user"
api "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/structs"
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/web"
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/services/context"
@@ -36,6 +37,18 @@ func toAPIOrgBranchProtection(ctx *context.APIContext, rule *git_model.OrgProtec
return names
}
resolveUserNames := func(ids []int64) []string {
names := make([]string, 0, len(ids))
for _, id := range ids {
u, err := user_model.GetUserByID(ctx, id)
if err != nil {
continue
}
names = append(names, u.Name)
}
return names
}
return &api.OrgBranchProtection{
ID: rule.ID,
OrgID: rule.OrgID,
@@ -44,16 +57,23 @@ func toAPIOrgBranchProtection(ctx *context.APIContext, rule *git_model.OrgProtec
EnablePush: rule.CanPush,
EnablePushWhitelist: rule.EnableWhitelist,
PushWhitelistTeams: resolveTeamNames(rule.WhitelistTeamIDs),
PushWhitelistUsernames: resolveUserNames(rule.WhitelistUserIDs),
PushWhitelistActionsUser: rule.WhitelistActionsUser,
EnableForcePush: rule.CanForcePush,
EnableForcePushAllowlist: rule.EnableForcePushAllowlist,
ForcePushAllowlistTeams: resolveTeamNames(rule.ForcePushAllowlistTeamIDs),
ForcePushAllowlistUsernames: resolveUserNames(rule.ForcePushAllowlistUserIDs),
ForcePushAllowlistActionsUser: rule.ForcePushAllowlistActionsUser,
EnableMergeWhitelist: rule.EnableMergeWhitelist,
MergeWhitelistTeams: resolveTeamNames(rule.MergeWhitelistTeamIDs),
MergeWhitelistUsernames: resolveUserNames(rule.MergeWhitelistUserIDs),
MergeWhitelistActionsUser: rule.MergeWhitelistActionsUser,
EnableStatusCheck: rule.EnableStatusCheck,
StatusCheckContexts: rule.StatusCheckContexts,
RequiredApprovals: rule.RequiredApprovals,
EnableApprovalsWhitelist: rule.EnableApprovalsWhitelist,
ApprovalsWhitelistTeams: resolveTeamNames(rule.ApprovalsWhitelistTeamIDs),
ApprovalsWhitelistUsernames: resolveUserNames(rule.ApprovalsWhitelistUserIDs),
BlockOnRejectedReviews: rule.BlockOnRejectedReviews,
BlockOnOfficialReviewRequests: rule.BlockOnOfficialReviewRequests,
BlockOnOutdatedBranch: rule.BlockOnOutdatedBranch,
@@ -85,6 +105,45 @@ func resolveTeamIDs(ctx *context.APIContext, orgID int64, names []string) ([]int
return ids, true
}
// resolveUserIDs converts a list of usernames or emails to user IDs, returning 422
// on any entry that matches no user. Each entry is first looked up by username and,
// if that user does not exist, by email address. Empty entries are ignored and the
// resulting IDs are deduplicated.
func resolveUserIDs(ctx *context.APIContext, names []string) ([]int64, bool) {
if len(names) == 0 {
return nil, true
}
seen := make(map[int64]struct{}, len(names))
ids := make([]int64, 0, len(names))
for _, name := range names {
if name == "" {
continue
}
u, err := user_model.GetUserByName(ctx, name)
if err != nil {
if !user_model.IsErrUserNotExist(err) {
ctx.APIErrorInternal(err)
return nil, false
}
u, err = user_model.GetUserByEmail(ctx, name)
if err != nil {
if user_model.IsErrUserNotExist(err) {
ctx.APIError(http.StatusUnprocessableEntity, "user does not exist: "+name)
} else {
ctx.APIErrorInternal(err)
}
return nil, false
}
}
if _, ok := seen[u.ID]; ok {
continue
}
seen[u.ID] = struct{}{}
ids = append(ids, u.ID)
}
return ids, true
}
// ListOrgBranchProtections list org-level branch protection rules
func ListOrgBranchProtections(ctx *context.APIContext) {
// swagger:operation GET /orgs/{org}/branch_protections organization orgListBranchProtections
@@ -212,23 +271,50 @@ func CreateOrgBranchProtection(ctx *context.APIContext) {
return
}
pushUsers, ok := resolveUserIDs(ctx, form.PushWhitelistUsernames)
if !ok {
return
}
forcePushUsers, ok := resolveUserIDs(ctx, form.ForcePushAllowlistUsernames)
if !ok {
return
}
mergeUsers, ok := resolveUserIDs(ctx, form.MergeWhitelistUsernames)
if !ok {
return
}
approvalsUsers, ok := resolveUserIDs(ctx, form.ApprovalsWhitelistUsernames)
if !ok {
return
}
enablePushWhitelist := form.EnablePush && form.EnablePushWhitelist
enableForcePushAllowlist := form.EnablePush && form.EnableForcePush && form.EnableForcePushAllowlist
rule := &git_model.OrgProtectedBranch{
OrgID: orgID,
RuleName: form.RuleName,
Priority: form.Priority,
CanPush: form.EnablePush,
EnableWhitelist: form.EnablePush && form.EnablePushWhitelist,
EnableWhitelist: enablePushWhitelist,
WhitelistTeamIDs: pushTeams,
WhitelistUserIDs: pushUsers,
WhitelistActionsUser: enablePushWhitelist && form.PushWhitelistActionsUser,
CanForcePush: form.EnablePush && form.EnableForcePush,
EnableForcePushAllowlist: form.EnablePush && form.EnableForcePush && form.EnableForcePushAllowlist,
EnableForcePushAllowlist: enableForcePushAllowlist,
ForcePushAllowlistTeamIDs: forcePushTeams,
ForcePushAllowlistUserIDs: forcePushUsers,
ForcePushAllowlistActionsUser: enableForcePushAllowlist && form.ForcePushAllowlistActionsUser,
EnableMergeWhitelist: form.EnableMergeWhitelist,
MergeWhitelistTeamIDs: mergeTeams,
MergeWhitelistUserIDs: mergeUsers,
MergeWhitelistActionsUser: form.EnableMergeWhitelist && form.MergeWhitelistActionsUser,
EnableStatusCheck: form.EnableStatusCheck,
StatusCheckContexts: form.StatusCheckContexts,
RequiredApprovals: form.RequiredApprovals,
EnableApprovalsWhitelist: form.EnableApprovalsWhitelist,
ApprovalsWhitelistTeamIDs: approvalsTeams,
ApprovalsWhitelistUserIDs: approvalsUsers,
BlockOnRejectedReviews: form.BlockOnRejectedReviews,
BlockOnOfficialReviewRequests: form.BlockOnOfficialReviewRequests,
BlockOnOutdatedBranch: form.BlockOnOutdatedBranch,
@@ -310,6 +396,16 @@ func EditOrgBranchProtection(ctx *context.APIContext) {
}
rule.WhitelistTeamIDs = ids
}
if form.PushWhitelistUsernames != nil {
ids, ok := resolveUserIDs(ctx, form.PushWhitelistUsernames)
if !ok {
return
}
rule.WhitelistUserIDs = ids
}
if form.PushWhitelistActionsUser != nil {
rule.WhitelistActionsUser = *form.PushWhitelistActionsUser
}
if form.EnableForcePush != nil {
rule.CanForcePush = *form.EnableForcePush
}
@@ -323,6 +419,16 @@ func EditOrgBranchProtection(ctx *context.APIContext) {
}
rule.ForcePushAllowlistTeamIDs = ids
}
if form.ForcePushAllowlistUsernames != nil {
ids, ok := resolveUserIDs(ctx, form.ForcePushAllowlistUsernames)
if !ok {
return
}
rule.ForcePushAllowlistUserIDs = ids
}
if form.ForcePushAllowlistActionsUser != nil {
rule.ForcePushAllowlistActionsUser = *form.ForcePushAllowlistActionsUser
}
if form.EnableMergeWhitelist != nil {
rule.EnableMergeWhitelist = *form.EnableMergeWhitelist
}
@@ -333,6 +439,16 @@ func EditOrgBranchProtection(ctx *context.APIContext) {
}
rule.MergeWhitelistTeamIDs = ids
}
if form.MergeWhitelistUsernames != nil {
ids, ok := resolveUserIDs(ctx, form.MergeWhitelistUsernames)
if !ok {
return
}
rule.MergeWhitelistUserIDs = ids
}
if form.MergeWhitelistActionsUser != nil {
rule.MergeWhitelistActionsUser = *form.MergeWhitelistActionsUser
}
if form.EnableStatusCheck != nil {
rule.EnableStatusCheck = *form.EnableStatusCheck
}
@@ -352,6 +468,13 @@ func EditOrgBranchProtection(ctx *context.APIContext) {
}
rule.ApprovalsWhitelistTeamIDs = ids
}
if form.ApprovalsWhitelistUsernames != nil {
ids, ok := resolveUserIDs(ctx, form.ApprovalsWhitelistUsernames)
if !ok {
return
}
rule.ApprovalsWhitelistUserIDs = ids
}
if form.BlockOnRejectedReviews != nil {
rule.BlockOnRejectedReviews = *form.BlockOnRejectedReviews
}
+6
View File
@@ -156,6 +156,12 @@ type swaggerParameterBodies struct {
// in:body
EditBranchProtectionOption api.EditBranchProtectionOption
// in:body
CreateOrgBranchProtectionOption api.CreateOrgBranchProtectionOption
// in:body
EditOrgBranchProtectionOption api.EditOrgBranchProtectionOption
// in:body
UpdateBranchProtectionPriories api.UpdateBranchProtectionPriories
+14
View File
@@ -41,3 +41,17 @@ type swaggerResponseOrganizationPermissions struct {
// in:body
Body api.OrganizationPermissions `json:"body"`
}
// OrgBranchProtection
// swagger:response OrgBranchProtection
type swaggerResponseOrgBranchProtection struct {
// in:body
Body api.OrgBranchProtection `json:"body"`
}
// OrgBranchProtectionList
// swagger:response OrgBranchProtectionList
type swaggerResponseOrgBranchProtectionList struct {
// in:body
Body []api.OrgBranchProtection `json:"body"`
}
+697
View File
@@ -21518,6 +21518,192 @@
}
}
}
},
"/orgs/{org}/branch_protections": {
"get": {
"produces": [
"application/json"
],
"tags": [
"organization"
],
"summary": "List an organization's branch protection rules",
"operationId": "orgListBranchProtections",
"parameters": [
{
"type": "string",
"description": "name of the organization",
"name": "org",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/OrgBranchProtectionList"
},
"404": {
"$ref": "#/responses/notFound"
}
}
},
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"organization"
],
"summary": "Create an org-level branch protection rule",
"operationId": "orgCreateBranchProtection",
"parameters": [
{
"type": "string",
"description": "name of the organization",
"name": "org",
"in": "path",
"required": true
},
{
"name": "body",
"in": "body",
"schema": {
"$ref": "#/definitions/CreateOrgBranchProtectionOption"
}
}
],
"responses": {
"201": {
"$ref": "#/responses/OrgBranchProtection"
},
"403": {
"$ref": "#/responses/forbidden"
},
"404": {
"$ref": "#/responses/notFound"
},
"422": {
"$ref": "#/responses/validationError"
}
}
}
},
"/orgs/{org}/branch_protections/{name}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"organization"
],
"summary": "Get a specific org-level branch protection rule",
"operationId": "orgGetBranchProtection",
"parameters": [
{
"type": "string",
"description": "name of the organization",
"name": "org",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the branch protection rule",
"name": "name",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/OrgBranchProtection"
},
"404": {
"$ref": "#/responses/notFound"
}
}
},
"delete": {
"tags": [
"organization"
],
"summary": "Delete an org-level branch protection rule",
"operationId": "orgDeleteBranchProtection",
"parameters": [
{
"type": "string",
"description": "name of the organization",
"name": "org",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the branch protection rule",
"name": "name",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"$ref": "#/responses/empty"
},
"404": {
"$ref": "#/responses/notFound"
}
}
},
"patch": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"organization"
],
"summary": "Edit an org-level branch protection rule. Only fields that are set will be changed",
"operationId": "orgEditBranchProtection",
"parameters": [
{
"type": "string",
"description": "name of the organization",
"name": "org",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the branch protection rule",
"name": "name",
"in": "path",
"required": true
},
{
"name": "body",
"in": "body",
"schema": {
"$ref": "#/definitions/EditOrgBranchProtectionOption"
}
}
],
"responses": {
"200": {
"$ref": "#/responses/OrgBranchProtection"
},
"404": {
"$ref": "#/responses/notFound"
},
"422": {
"$ref": "#/responses/validationError"
}
}
}
}
},
"definitions": {
@@ -30266,6 +30452,502 @@
}
},
"x-go-package": "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/structs"
},
"CreateOrgBranchProtectionOption": {
"description": "CreateOrgBranchProtectionOption options for creating an org-level branch protection",
"type": "object",
"properties": {
"approvals_whitelist_teams": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "ApprovalsWhitelistTeams"
},
"approvals_whitelist_username": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "ApprovalsWhitelistUsernames"
},
"block_admin_merge_override": {
"type": "boolean",
"x-go-name": "BlockAdminMergeOverride"
},
"block_on_official_review_requests": {
"type": "boolean",
"x-go-name": "BlockOnOfficialReviewRequests"
},
"block_on_outdated_branch": {
"type": "boolean",
"x-go-name": "BlockOnOutdatedBranch"
},
"block_on_rejected_reviews": {
"type": "boolean",
"x-go-name": "BlockOnRejectedReviews"
},
"dismiss_stale_approvals": {
"type": "boolean",
"x-go-name": "DismissStaleApprovals"
},
"enable_approvals_whitelist": {
"type": "boolean",
"x-go-name": "EnableApprovalsWhitelist"
},
"enable_force_push": {
"type": "boolean",
"x-go-name": "EnableForcePush"
},
"enable_force_push_allowlist": {
"type": "boolean",
"x-go-name": "EnableForcePushAllowlist"
},
"enable_merge_whitelist": {
"type": "boolean",
"x-go-name": "EnableMergeWhitelist"
},
"enable_push": {
"type": "boolean",
"x-go-name": "EnablePush"
},
"enable_push_whitelist": {
"type": "boolean",
"x-go-name": "EnablePushWhitelist"
},
"enable_status_check": {
"type": "boolean",
"x-go-name": "EnableStatusCheck"
},
"force_push_allowlist_actions_user": {
"type": "boolean",
"x-go-name": "ForcePushAllowlistActionsUser"
},
"force_push_allowlist_teams": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "ForcePushAllowlistTeams"
},
"force_push_allowlist_usernames": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "ForcePushAllowlistUsernames"
},
"ignore_stale_approvals": {
"type": "boolean",
"x-go-name": "IgnoreStaleApprovals"
},
"merge_whitelist_actions_user": {
"type": "boolean",
"x-go-name": "MergeWhitelistActionsUser"
},
"merge_whitelist_teams": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "MergeWhitelistTeams"
},
"merge_whitelist_usernames": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "MergeWhitelistUsernames"
},
"priority": {
"type": "integer",
"format": "int64",
"x-go-name": "Priority"
},
"protected_file_patterns": {
"type": "string",
"x-go-name": "ProtectedFilePatterns"
},
"push_whitelist_actions_user": {
"type": "boolean",
"x-go-name": "PushWhitelistActionsUser"
},
"push_whitelist_teams": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "PushWhitelistTeams"
},
"push_whitelist_usernames": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "PushWhitelistUsernames"
},
"require_signed_commits": {
"type": "boolean",
"x-go-name": "RequireSignedCommits"
},
"required_approvals": {
"type": "integer",
"format": "int64",
"x-go-name": "RequiredApprovals"
},
"rule_name": {
"type": "string",
"x-go-name": "RuleName"
},
"status_check_contexts": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "StatusCheckContexts"
},
"unprotected_file_patterns": {
"type": "string",
"x-go-name": "UnprotectedFilePatterns"
}
},
"x-go-package": "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/structs"
},
"EditOrgBranchProtectionOption": {
"description": "EditOrgBranchProtectionOption options for editing an org-level branch protection",
"type": "object",
"properties": {
"approvals_whitelist_teams": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "ApprovalsWhitelistTeams"
},
"approvals_whitelist_username": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "ApprovalsWhitelistUsernames"
},
"block_admin_merge_override": {
"type": "boolean",
"x-go-name": "BlockAdminMergeOverride"
},
"block_on_official_review_requests": {
"type": "boolean",
"x-go-name": "BlockOnOfficialReviewRequests"
},
"block_on_outdated_branch": {
"type": "boolean",
"x-go-name": "BlockOnOutdatedBranch"
},
"block_on_rejected_reviews": {
"type": "boolean",
"x-go-name": "BlockOnRejectedReviews"
},
"dismiss_stale_approvals": {
"type": "boolean",
"x-go-name": "DismissStaleApprovals"
},
"enable_approvals_whitelist": {
"type": "boolean",
"x-go-name": "EnableApprovalsWhitelist"
},
"enable_force_push": {
"type": "boolean",
"x-go-name": "EnableForcePush"
},
"enable_force_push_allowlist": {
"type": "boolean",
"x-go-name": "EnableForcePushAllowlist"
},
"enable_merge_whitelist": {
"type": "boolean",
"x-go-name": "EnableMergeWhitelist"
},
"enable_push": {
"type": "boolean",
"x-go-name": "EnablePush"
},
"enable_push_whitelist": {
"type": "boolean",
"x-go-name": "EnablePushWhitelist"
},
"enable_status_check": {
"type": "boolean",
"x-go-name": "EnableStatusCheck"
},
"force_push_allowlist_actions_user": {
"type": "boolean",
"x-go-name": "ForcePushAllowlistActionsUser"
},
"force_push_allowlist_teams": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "ForcePushAllowlistTeams"
},
"force_push_allowlist_usernames": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "ForcePushAllowlistUsernames"
},
"ignore_stale_approvals": {
"type": "boolean",
"x-go-name": "IgnoreStaleApprovals"
},
"merge_whitelist_actions_user": {
"type": "boolean",
"x-go-name": "MergeWhitelistActionsUser"
},
"merge_whitelist_teams": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "MergeWhitelistTeams"
},
"merge_whitelist_usernames": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "MergeWhitelistUsernames"
},
"priority": {
"type": "integer",
"format": "int64",
"x-go-name": "Priority"
},
"protected_file_patterns": {
"type": "string",
"x-go-name": "ProtectedFilePatterns"
},
"push_whitelist_actions_user": {
"type": "boolean",
"x-go-name": "PushWhitelistActionsUser"
},
"push_whitelist_teams": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "PushWhitelistTeams"
},
"push_whitelist_usernames": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "PushWhitelistUsernames"
},
"require_signed_commits": {
"type": "boolean",
"x-go-name": "RequireSignedCommits"
},
"required_approvals": {
"type": "integer",
"format": "int64",
"x-go-name": "RequiredApprovals"
},
"status_check_contexts": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "StatusCheckContexts"
},
"unprotected_file_patterns": {
"type": "string",
"x-go-name": "UnprotectedFilePatterns"
}
},
"x-go-package": "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/structs"
},
"OrgBranchProtection": {
"description": "OrgBranchProtection represents an org-level branch protection ruleset",
"type": "object",
"properties": {
"approvals_whitelist_teams": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "ApprovalsWhitelistTeams"
},
"approvals_whitelist_username": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "ApprovalsWhitelistUsernames"
},
"block_admin_merge_override": {
"type": "boolean",
"x-go-name": "BlockAdminMergeOverride"
},
"block_on_official_review_requests": {
"type": "boolean",
"x-go-name": "BlockOnOfficialReviewRequests"
},
"block_on_outdated_branch": {
"type": "boolean",
"x-go-name": "BlockOnOutdatedBranch"
},
"block_on_rejected_reviews": {
"type": "boolean",
"x-go-name": "BlockOnRejectedReviews"
},
"created_at": {
"type": "string",
"format": "date-time",
"x-go-name": "Created"
},
"dismiss_stale_approvals": {
"type": "boolean",
"x-go-name": "DismissStaleApprovals"
},
"enable_approvals_whitelist": {
"type": "boolean",
"x-go-name": "EnableApprovalsWhitelist"
},
"enable_force_push": {
"type": "boolean",
"x-go-name": "EnableForcePush"
},
"enable_force_push_allowlist": {
"type": "boolean",
"x-go-name": "EnableForcePushAllowlist"
},
"enable_merge_whitelist": {
"type": "boolean",
"x-go-name": "EnableMergeWhitelist"
},
"enable_push": {
"type": "boolean",
"x-go-name": "EnablePush"
},
"enable_push_whitelist": {
"type": "boolean",
"x-go-name": "EnablePushWhitelist"
},
"enable_status_check": {
"type": "boolean",
"x-go-name": "EnableStatusCheck"
},
"force_push_allowlist_actions_user": {
"type": "boolean",
"x-go-name": "ForcePushAllowlistActionsUser"
},
"force_push_allowlist_teams": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "ForcePushAllowlistTeams"
},
"force_push_allowlist_usernames": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "ForcePushAllowlistUsernames"
},
"id": {
"type": "integer",
"format": "int64",
"x-go-name": "ID"
},
"ignore_stale_approvals": {
"type": "boolean",
"x-go-name": "IgnoreStaleApprovals"
},
"merge_whitelist_actions_user": {
"type": "boolean",
"x-go-name": "MergeWhitelistActionsUser"
},
"merge_whitelist_teams": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "MergeWhitelistTeams"
},
"merge_whitelist_usernames": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "MergeWhitelistUsernames"
},
"org_id": {
"type": "integer",
"format": "int64",
"x-go-name": "OrgID"
},
"priority": {
"type": "integer",
"format": "int64",
"x-go-name": "Priority"
},
"protected_file_patterns": {
"type": "string",
"x-go-name": "ProtectedFilePatterns"
},
"push_whitelist_actions_user": {
"type": "boolean",
"x-go-name": "PushWhitelistActionsUser"
},
"push_whitelist_teams": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "PushWhitelistTeams"
},
"push_whitelist_usernames": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "PushWhitelistUsernames"
},
"require_signed_commits": {
"type": "boolean",
"x-go-name": "RequireSignedCommits"
},
"required_approvals": {
"type": "integer",
"format": "int64",
"x-go-name": "RequiredApprovals"
},
"rule_name": {
"type": "string",
"x-go-name": "RuleName"
},
"status_check_contexts": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "StatusCheckContexts"
},
"unprotected_file_patterns": {
"type": "string",
"x-go-name": "UnprotectedFilePatterns"
},
"updated_at": {
"type": "string",
"format": "date-time",
"x-go-name": "Updated"
}
},
"x-go-package": "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/structs"
}
},
"responses": {
@@ -31404,6 +32086,21 @@
"type": "string"
}
}
},
"OrgBranchProtection": {
"description": "OrgBranchProtection",
"schema": {
"$ref": "#/definitions/OrgBranchProtection"
}
},
"OrgBranchProtectionList": {
"description": "OrgBranchProtectionList",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/OrgBranchProtection"
}
}
}
},
"securityDefinitions": {
+709
View File
@@ -911,6 +911,29 @@
},
"description": "OAuth2ApplicationList represents a list of OAuth2 applications."
},
"OrgBranchProtection": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OrgBranchProtection"
}
}
},
"description": "OrgBranchProtection"
},
"OrgBranchProtectionList": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/OrgBranchProtection"
},
"type": "array"
}
}
},
"description": "OrgBranchProtectionList"
},
"Organization": {
"content": {
"application/json": {
@@ -4264,6 +4287,166 @@
"type": "object",
"x-go-package": "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/structs"
},
"CreateOrgBranchProtectionOption": {
"description": "CreateOrgBranchProtectionOption options for creating an org-level branch protection",
"properties": {
"approvals_whitelist_teams": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "ApprovalsWhitelistTeams"
},
"approvals_whitelist_username": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "ApprovalsWhitelistUsernames"
},
"block_admin_merge_override": {
"type": "boolean",
"x-go-name": "BlockAdminMergeOverride"
},
"block_on_official_review_requests": {
"type": "boolean",
"x-go-name": "BlockOnOfficialReviewRequests"
},
"block_on_outdated_branch": {
"type": "boolean",
"x-go-name": "BlockOnOutdatedBranch"
},
"block_on_rejected_reviews": {
"type": "boolean",
"x-go-name": "BlockOnRejectedReviews"
},
"dismiss_stale_approvals": {
"type": "boolean",
"x-go-name": "DismissStaleApprovals"
},
"enable_approvals_whitelist": {
"type": "boolean",
"x-go-name": "EnableApprovalsWhitelist"
},
"enable_force_push": {
"type": "boolean",
"x-go-name": "EnableForcePush"
},
"enable_force_push_allowlist": {
"type": "boolean",
"x-go-name": "EnableForcePushAllowlist"
},
"enable_merge_whitelist": {
"type": "boolean",
"x-go-name": "EnableMergeWhitelist"
},
"enable_push": {
"type": "boolean",
"x-go-name": "EnablePush"
},
"enable_push_whitelist": {
"type": "boolean",
"x-go-name": "EnablePushWhitelist"
},
"enable_status_check": {
"type": "boolean",
"x-go-name": "EnableStatusCheck"
},
"force_push_allowlist_actions_user": {
"type": "boolean",
"x-go-name": "ForcePushAllowlistActionsUser"
},
"force_push_allowlist_teams": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "ForcePushAllowlistTeams"
},
"force_push_allowlist_usernames": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "ForcePushAllowlistUsernames"
},
"ignore_stale_approvals": {
"type": "boolean",
"x-go-name": "IgnoreStaleApprovals"
},
"merge_whitelist_actions_user": {
"type": "boolean",
"x-go-name": "MergeWhitelistActionsUser"
},
"merge_whitelist_teams": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "MergeWhitelistTeams"
},
"merge_whitelist_usernames": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "MergeWhitelistUsernames"
},
"priority": {
"format": "int64",
"type": "integer",
"x-go-name": "Priority"
},
"protected_file_patterns": {
"type": "string",
"x-go-name": "ProtectedFilePatterns"
},
"push_whitelist_actions_user": {
"type": "boolean",
"x-go-name": "PushWhitelistActionsUser"
},
"push_whitelist_teams": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "PushWhitelistTeams"
},
"push_whitelist_usernames": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "PushWhitelistUsernames"
},
"require_signed_commits": {
"type": "boolean",
"x-go-name": "RequireSignedCommits"
},
"required_approvals": {
"format": "int64",
"type": "integer",
"x-go-name": "RequiredApprovals"
},
"rule_name": {
"type": "string",
"x-go-name": "RuleName"
},
"status_check_contexts": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "StatusCheckContexts"
},
"unprotected_file_patterns": {
"type": "string",
"x-go-name": "UnprotectedFilePatterns"
}
},
"type": "object",
"x-go-package": "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/structs"
},
"CreateOrgOption": {
"description": "CreateOrgOption options for creating an organization",
"properties": {
@@ -5431,6 +5614,162 @@
"type": "object",
"x-go-package": "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/structs"
},
"EditOrgBranchProtectionOption": {
"description": "EditOrgBranchProtectionOption options for editing an org-level branch protection",
"properties": {
"approvals_whitelist_teams": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "ApprovalsWhitelistTeams"
},
"approvals_whitelist_username": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "ApprovalsWhitelistUsernames"
},
"block_admin_merge_override": {
"type": "boolean",
"x-go-name": "BlockAdminMergeOverride"
},
"block_on_official_review_requests": {
"type": "boolean",
"x-go-name": "BlockOnOfficialReviewRequests"
},
"block_on_outdated_branch": {
"type": "boolean",
"x-go-name": "BlockOnOutdatedBranch"
},
"block_on_rejected_reviews": {
"type": "boolean",
"x-go-name": "BlockOnRejectedReviews"
},
"dismiss_stale_approvals": {
"type": "boolean",
"x-go-name": "DismissStaleApprovals"
},
"enable_approvals_whitelist": {
"type": "boolean",
"x-go-name": "EnableApprovalsWhitelist"
},
"enable_force_push": {
"type": "boolean",
"x-go-name": "EnableForcePush"
},
"enable_force_push_allowlist": {
"type": "boolean",
"x-go-name": "EnableForcePushAllowlist"
},
"enable_merge_whitelist": {
"type": "boolean",
"x-go-name": "EnableMergeWhitelist"
},
"enable_push": {
"type": "boolean",
"x-go-name": "EnablePush"
},
"enable_push_whitelist": {
"type": "boolean",
"x-go-name": "EnablePushWhitelist"
},
"enable_status_check": {
"type": "boolean",
"x-go-name": "EnableStatusCheck"
},
"force_push_allowlist_actions_user": {
"type": "boolean",
"x-go-name": "ForcePushAllowlistActionsUser"
},
"force_push_allowlist_teams": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "ForcePushAllowlistTeams"
},
"force_push_allowlist_usernames": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "ForcePushAllowlistUsernames"
},
"ignore_stale_approvals": {
"type": "boolean",
"x-go-name": "IgnoreStaleApprovals"
},
"merge_whitelist_actions_user": {
"type": "boolean",
"x-go-name": "MergeWhitelistActionsUser"
},
"merge_whitelist_teams": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "MergeWhitelistTeams"
},
"merge_whitelist_usernames": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "MergeWhitelistUsernames"
},
"priority": {
"format": "int64",
"type": "integer",
"x-go-name": "Priority"
},
"protected_file_patterns": {
"type": "string",
"x-go-name": "ProtectedFilePatterns"
},
"push_whitelist_actions_user": {
"type": "boolean",
"x-go-name": "PushWhitelistActionsUser"
},
"push_whitelist_teams": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "PushWhitelistTeams"
},
"push_whitelist_usernames": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "PushWhitelistUsernames"
},
"require_signed_commits": {
"type": "boolean",
"x-go-name": "RequireSignedCommits"
},
"required_approvals": {
"format": "int64",
"type": "integer",
"x-go-name": "RequiredApprovals"
},
"status_check_contexts": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "StatusCheckContexts"
},
"unprotected_file_patterns": {
"type": "string",
"x-go-name": "UnprotectedFilePatterns"
}
},
"type": "object",
"x-go-package": "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/structs"
},
"EditOrgOption": {
"description": "EditOrgOption options for editing an organization",
"properties": {
@@ -7900,6 +8239,186 @@
],
"type": "string"
},
"OrgBranchProtection": {
"description": "OrgBranchProtection represents an org-level branch protection ruleset",
"properties": {
"approvals_whitelist_teams": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "ApprovalsWhitelistTeams"
},
"approvals_whitelist_username": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "ApprovalsWhitelistUsernames"
},
"block_admin_merge_override": {
"type": "boolean",
"x-go-name": "BlockAdminMergeOverride"
},
"block_on_official_review_requests": {
"type": "boolean",
"x-go-name": "BlockOnOfficialReviewRequests"
},
"block_on_outdated_branch": {
"type": "boolean",
"x-go-name": "BlockOnOutdatedBranch"
},
"block_on_rejected_reviews": {
"type": "boolean",
"x-go-name": "BlockOnRejectedReviews"
},
"created_at": {
"format": "date-time",
"type": "string",
"x-go-name": "Created"
},
"dismiss_stale_approvals": {
"type": "boolean",
"x-go-name": "DismissStaleApprovals"
},
"enable_approvals_whitelist": {
"type": "boolean",
"x-go-name": "EnableApprovalsWhitelist"
},
"enable_force_push": {
"type": "boolean",
"x-go-name": "EnableForcePush"
},
"enable_force_push_allowlist": {
"type": "boolean",
"x-go-name": "EnableForcePushAllowlist"
},
"enable_merge_whitelist": {
"type": "boolean",
"x-go-name": "EnableMergeWhitelist"
},
"enable_push": {
"type": "boolean",
"x-go-name": "EnablePush"
},
"enable_push_whitelist": {
"type": "boolean",
"x-go-name": "EnablePushWhitelist"
},
"enable_status_check": {
"type": "boolean",
"x-go-name": "EnableStatusCheck"
},
"force_push_allowlist_actions_user": {
"type": "boolean",
"x-go-name": "ForcePushAllowlistActionsUser"
},
"force_push_allowlist_teams": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "ForcePushAllowlistTeams"
},
"force_push_allowlist_usernames": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "ForcePushAllowlistUsernames"
},
"id": {
"format": "int64",
"type": "integer",
"x-go-name": "ID"
},
"ignore_stale_approvals": {
"type": "boolean",
"x-go-name": "IgnoreStaleApprovals"
},
"merge_whitelist_actions_user": {
"type": "boolean",
"x-go-name": "MergeWhitelistActionsUser"
},
"merge_whitelist_teams": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "MergeWhitelistTeams"
},
"merge_whitelist_usernames": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "MergeWhitelistUsernames"
},
"org_id": {
"format": "int64",
"type": "integer",
"x-go-name": "OrgID"
},
"priority": {
"format": "int64",
"type": "integer",
"x-go-name": "Priority"
},
"protected_file_patterns": {
"type": "string",
"x-go-name": "ProtectedFilePatterns"
},
"push_whitelist_actions_user": {
"type": "boolean",
"x-go-name": "PushWhitelistActionsUser"
},
"push_whitelist_teams": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "PushWhitelistTeams"
},
"push_whitelist_usernames": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "PushWhitelistUsernames"
},
"require_signed_commits": {
"type": "boolean",
"x-go-name": "RequireSignedCommits"
},
"required_approvals": {
"format": "int64",
"type": "integer",
"x-go-name": "RequiredApprovals"
},
"rule_name": {
"type": "string",
"x-go-name": "RuleName"
},
"status_check_contexts": {
"items": {
"type": "string"
},
"type": "array",
"x-go-name": "StatusCheckContexts"
},
"unprotected_file_patterns": {
"type": "string",
"x-go-name": "UnprotectedFilePatterns"
},
"updated_at": {
"format": "date-time",
"type": "string",
"x-go-name": "Updated"
}
},
"type": "object",
"x-go-package": "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/structs"
},
"Organization": {
"description": "Organization represents an organization",
"properties": {
@@ -13484,6 +14003,196 @@
]
}
},
"/orgs/{org}/branch_protections": {
"get": {
"operationId": "orgListBranchProtections",
"parameters": [
{
"description": "name of the organization",
"in": "path",
"name": "org",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"$ref": "#/components/responses/OrgBranchProtectionList"
},
"404": {
"$ref": "#/components/responses/notFound"
}
},
"summary": "List an organization's branch protection rules",
"tags": [
"organization"
]
},
"post": {
"operationId": "orgCreateBranchProtection",
"parameters": [
{
"description": "name of the organization",
"in": "path",
"name": "org",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateOrgBranchProtectionOption"
}
}
},
"x-originalParamName": "body"
},
"responses": {
"201": {
"$ref": "#/components/responses/OrgBranchProtection"
},
"403": {
"$ref": "#/components/responses/forbidden"
},
"404": {
"$ref": "#/components/responses/notFound"
},
"422": {
"$ref": "#/components/responses/validationError"
}
},
"summary": "Create an org-level branch protection rule",
"tags": [
"organization"
]
}
},
"/orgs/{org}/branch_protections/{name}": {
"delete": {
"operationId": "orgDeleteBranchProtection",
"parameters": [
{
"description": "name of the organization",
"in": "path",
"name": "org",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "name of the branch protection rule",
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"$ref": "#/components/responses/empty"
},
"404": {
"$ref": "#/components/responses/notFound"
}
},
"summary": "Delete an org-level branch protection rule",
"tags": [
"organization"
]
},
"get": {
"operationId": "orgGetBranchProtection",
"parameters": [
{
"description": "name of the organization",
"in": "path",
"name": "org",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "name of the branch protection rule",
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"$ref": "#/components/responses/OrgBranchProtection"
},
"404": {
"$ref": "#/components/responses/notFound"
}
},
"summary": "Get a specific org-level branch protection rule",
"tags": [
"organization"
]
},
"patch": {
"operationId": "orgEditBranchProtection",
"parameters": [
{
"description": "name of the organization",
"in": "path",
"name": "org",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "name of the branch protection rule",
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EditOrgBranchProtectionOption"
}
}
},
"x-originalParamName": "body"
},
"responses": {
"200": {
"$ref": "#/components/responses/OrgBranchProtection"
},
"404": {
"$ref": "#/components/responses/notFound"
},
"422": {
"$ref": "#/components/responses/validationError"
}
},
"summary": "Edit an org-level branch protection rule. Only fields that are set will be changed",
"tags": [
"organization"
]
}
},
"/orgs/{org}/hooks": {
"get": {
"operationId": "orgListHooks",