mirror of https://github.com/go-gitea/gitea
Merge dd2b74d6a7
into 48d4580dd5
This commit is contained in:
commit
fe9b826d8c
|
@ -38,10 +38,15 @@ type ProtectedBranch struct {
|
|||
isPlainName bool `xorm:"-"`
|
||||
CanPush bool `xorm:"NOT NULL DEFAULT false"`
|
||||
EnableWhitelist bool
|
||||
WhitelistUserIDs []int64 `xorm:"JSON TEXT"`
|
||||
WhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
|
||||
WhitelistUserIDs []int64 `xorm:"JSON TEXT"`
|
||||
WhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
|
||||
WhitelistDeployKeys bool `xorm:"NOT NULL DEFAULT false"`
|
||||
CanForcePush bool `xorm:"NOT NULL DEFAULT false"`
|
||||
EnableForcePushWhitelist bool
|
||||
ForcePushWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
|
||||
ForcePushWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
|
||||
ForcePushWhitelistDeployKeys bool `xorm:"NOT NULL DEFAULT false"`
|
||||
EnableMergeWhitelist bool `xorm:"NOT NULL DEFAULT false"`
|
||||
WhitelistDeployKeys bool `xorm:"NOT NULL DEFAULT false"`
|
||||
MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
|
||||
MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
|
||||
EnableStatusCheck bool `xorm:"NOT NULL DEFAULT false"`
|
||||
|
@ -143,6 +148,33 @@ func (protectBranch *ProtectedBranch) CanUserPush(ctx context.Context, user *use
|
|||
return in
|
||||
}
|
||||
|
||||
// CanUserForcePush returns if some user could force push to this protected branch
|
||||
// Since force-push extends normal push, we also check if user has regular push access
|
||||
func (protectBranch *ProtectedBranch) CanUserForcePush(ctx context.Context, user *user_model.User) bool {
|
||||
if !protectBranch.CanForcePush {
|
||||
return false
|
||||
}
|
||||
|
||||
if !protectBranch.EnableForcePushWhitelist {
|
||||
return protectBranch.CanUserPush(ctx, user)
|
||||
}
|
||||
|
||||
if slices.Contains(protectBranch.ForcePushWhitelistUserIDs, user.ID) {
|
||||
return protectBranch.CanUserPush(ctx, user)
|
||||
}
|
||||
|
||||
if len(protectBranch.ForcePushWhitelistTeamIDs) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
in, err := organization.IsUserInTeams(ctx, user.ID, protectBranch.ForcePushWhitelistTeamIDs)
|
||||
if err != nil {
|
||||
log.Error("IsUserInTeams: %v", err)
|
||||
return false
|
||||
}
|
||||
return in && protectBranch.CanUserPush(ctx, 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 {
|
||||
if !protectBranch.EnableMergeWhitelist {
|
||||
|
@ -301,6 +333,9 @@ type WhitelistOptions struct {
|
|||
UserIDs []int64
|
||||
TeamIDs []int64
|
||||
|
||||
ForcePushUserIDs []int64
|
||||
ForcePushTeamIDs []int64
|
||||
|
||||
MergeUserIDs []int64
|
||||
MergeTeamIDs []int64
|
||||
|
||||
|
@ -328,6 +363,12 @@ func UpdateProtectBranch(ctx context.Context, repo *repo_model.Repository, prote
|
|||
}
|
||||
protectBranch.WhitelistUserIDs = whitelist
|
||||
|
||||
whitelist, err = updateUserWhitelist(ctx, repo, protectBranch.ForcePushWhitelistUserIDs, opts.ForcePushUserIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
protectBranch.ForcePushWhitelistUserIDs = whitelist
|
||||
|
||||
whitelist, err = updateUserWhitelist(ctx, repo, protectBranch.MergeWhitelistUserIDs, opts.MergeUserIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -347,6 +388,12 @@ func UpdateProtectBranch(ctx context.Context, repo *repo_model.Repository, prote
|
|||
}
|
||||
protectBranch.WhitelistTeamIDs = whitelist
|
||||
|
||||
whitelist, err = updateTeamWhitelist(ctx, repo, protectBranch.ForcePushWhitelistTeamIDs, opts.ForcePushTeamIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
protectBranch.ForcePushWhitelistTeamIDs = whitelist
|
||||
|
||||
whitelist, err = updateTeamWhitelist(ctx, repo, protectBranch.MergeWhitelistTeamIDs, opts.MergeTeamIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -468,43 +515,58 @@ func DeleteProtectedBranch(ctx context.Context, repo *repo_model.Repository, id
|
|||
return nil
|
||||
}
|
||||
|
||||
// RemoveUserIDFromProtectedBranch remove all user ids from protected branch options
|
||||
// removeIDsFromProtectedBranch is a helper function to remove IDs from protected branch options
|
||||
func removeIDsFromProtectedBranch(ctx context.Context, p *ProtectedBranch, userID, teamID int64, columnNames []string) error {
|
||||
lenUserIDs, lenForcePushIDs, lenApprovalIDs, lenMergeIDs := len(p.WhitelistUserIDs), len(p.ForcePushWhitelistUserIDs), len(p.ApprovalsWhitelistUserIDs), len(p.MergeWhitelistUserIDs)
|
||||
lenTeamIDs, lenForcePushTeamIDs, lenApprovalTeamIDs, lenMergeTeamIDs := len(p.WhitelistTeamIDs), len(p.ForcePushWhitelistTeamIDs), len(p.ApprovalsWhitelistTeamIDs), len(p.MergeWhitelistTeamIDs)
|
||||
|
||||
if userID > 0 {
|
||||
p.WhitelistUserIDs = util.SliceRemoveAll(p.WhitelistUserIDs, userID)
|
||||
p.ForcePushWhitelistUserIDs = util.SliceRemoveAll(p.ForcePushWhitelistUserIDs, userID)
|
||||
p.ApprovalsWhitelistUserIDs = util.SliceRemoveAll(p.ApprovalsWhitelistUserIDs, userID)
|
||||
p.MergeWhitelistUserIDs = util.SliceRemoveAll(p.MergeWhitelistUserIDs, userID)
|
||||
}
|
||||
|
||||
if teamID > 0 {
|
||||
p.WhitelistTeamIDs = util.SliceRemoveAll(p.WhitelistTeamIDs, teamID)
|
||||
p.ForcePushWhitelistTeamIDs = util.SliceRemoveAll(p.ForcePushWhitelistTeamIDs, teamID)
|
||||
p.ApprovalsWhitelistTeamIDs = util.SliceRemoveAll(p.ApprovalsWhitelistTeamIDs, teamID)
|
||||
p.MergeWhitelistTeamIDs = util.SliceRemoveAll(p.MergeWhitelistTeamIDs, teamID)
|
||||
}
|
||||
|
||||
if (lenUserIDs != len(p.WhitelistUserIDs) ||
|
||||
lenForcePushIDs != len(p.ForcePushWhitelistUserIDs) ||
|
||||
lenApprovalIDs != len(p.ApprovalsWhitelistUserIDs) ||
|
||||
lenMergeIDs != len(p.MergeWhitelistUserIDs)) ||
|
||||
(lenTeamIDs != len(p.WhitelistTeamIDs) ||
|
||||
lenForcePushTeamIDs != len(p.ForcePushWhitelistTeamIDs) ||
|
||||
lenApprovalTeamIDs != len(p.ApprovalsWhitelistTeamIDs) ||
|
||||
lenMergeTeamIDs != len(p.MergeWhitelistTeamIDs)) {
|
||||
if _, err := db.GetEngine(ctx).ID(p.ID).Cols(columnNames...).Update(p); err != nil {
|
||||
return fmt.Errorf("updateProtectedBranches: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveUserIDFromProtectedBranch removes all user ids from protected branch options
|
||||
func RemoveUserIDFromProtectedBranch(ctx context.Context, p *ProtectedBranch, userID int64) error {
|
||||
lenIDs, lenApprovalIDs, lenMergeIDs := len(p.WhitelistUserIDs), len(p.ApprovalsWhitelistUserIDs), len(p.MergeWhitelistUserIDs)
|
||||
p.WhitelistUserIDs = util.SliceRemoveAll(p.WhitelistUserIDs, userID)
|
||||
p.ApprovalsWhitelistUserIDs = util.SliceRemoveAll(p.ApprovalsWhitelistUserIDs, userID)
|
||||
p.MergeWhitelistUserIDs = util.SliceRemoveAll(p.MergeWhitelistUserIDs, userID)
|
||||
|
||||
if lenIDs != len(p.WhitelistUserIDs) || lenApprovalIDs != len(p.ApprovalsWhitelistUserIDs) ||
|
||||
lenMergeIDs != len(p.MergeWhitelistUserIDs) {
|
||||
if _, err := db.GetEngine(ctx).ID(p.ID).Cols(
|
||||
"whitelist_user_i_ds",
|
||||
"merge_whitelist_user_i_ds",
|
||||
"approvals_whitelist_user_i_ds",
|
||||
).Update(p); err != nil {
|
||||
return fmt.Errorf("updateProtectedBranches: %v", err)
|
||||
}
|
||||
columnNames := []string{
|
||||
"whitelist_user_i_ds",
|
||||
"force_push_whitelist_user_i_ds",
|
||||
"merge_whitelist_user_i_ds",
|
||||
"approvals_whitelist_user_i_ds",
|
||||
}
|
||||
return nil
|
||||
return removeIDsFromProtectedBranch(ctx, p, userID, 0, columnNames)
|
||||
}
|
||||
|
||||
// RemoveTeamIDFromProtectedBranch remove all team ids from protected branch options
|
||||
// RemoveTeamIDFromProtectedBranch removes all team ids from protected branch options
|
||||
func RemoveTeamIDFromProtectedBranch(ctx context.Context, p *ProtectedBranch, teamID int64) error {
|
||||
lenIDs, lenApprovalIDs, lenMergeIDs := len(p.WhitelistTeamIDs), len(p.ApprovalsWhitelistTeamIDs), len(p.MergeWhitelistTeamIDs)
|
||||
p.WhitelistTeamIDs = util.SliceRemoveAll(p.WhitelistTeamIDs, teamID)
|
||||
p.ApprovalsWhitelistTeamIDs = util.SliceRemoveAll(p.ApprovalsWhitelistTeamIDs, teamID)
|
||||
p.MergeWhitelistTeamIDs = util.SliceRemoveAll(p.MergeWhitelistTeamIDs, teamID)
|
||||
|
||||
if lenIDs != len(p.WhitelistTeamIDs) ||
|
||||
lenApprovalIDs != len(p.ApprovalsWhitelistTeamIDs) ||
|
||||
lenMergeIDs != len(p.MergeWhitelistTeamIDs) {
|
||||
if _, err := db.GetEngine(ctx).ID(p.ID).Cols(
|
||||
"whitelist_team_i_ds",
|
||||
"merge_whitelist_team_i_ds",
|
||||
"approvals_whitelist_team_i_ds",
|
||||
).Update(p); err != nil {
|
||||
return fmt.Errorf("updateProtectedBranches: %v", err)
|
||||
}
|
||||
columnNames := []string{
|
||||
"whitelist_team_i_ds",
|
||||
"force_push_whitelist_team_i_ds",
|
||||
"merge_whitelist_team_i_ds",
|
||||
"approvals_whitelist_team_i_ds",
|
||||
}
|
||||
return nil
|
||||
return removeIDsFromProtectedBranch(ctx, p, 0, teamID, columnNames)
|
||||
}
|
||||
|
|
|
@ -30,6 +30,11 @@ type BranchProtection struct {
|
|||
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
|
||||
PushWhitelistTeams []string `json:"push_whitelist_teams"`
|
||||
PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"`
|
||||
EnableForcePush bool `json:"enable_force_push"`
|
||||
EnableForcePushWhitelist bool `json:"enable_force_push_whitelist"`
|
||||
ForcePushWhitelistUsernames []string `json:"force_push_whitelist_usernames"`
|
||||
ForcePushWhitelistTeams []string `json:"force_push_whitelist_teams"`
|
||||
ForcePushWhitelistDeployKeys bool `json:"force_push_whitelist_deploy_keys"`
|
||||
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
|
||||
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
|
||||
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
|
||||
|
@ -63,6 +68,11 @@ type CreateBranchProtectionOption struct {
|
|||
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
|
||||
PushWhitelistTeams []string `json:"push_whitelist_teams"`
|
||||
PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"`
|
||||
EnableForcePush bool `json:"enable_force_push"`
|
||||
EnableForcePushWhitelist bool `json:"enable_force_push_whitelist"`
|
||||
ForcePushWhitelistUsernames []string `json:"force_push_whitelist_usernames"`
|
||||
ForcePushWhitelistTeams []string `json:"force_push_whitelist_teams"`
|
||||
ForcePushWhitelistDeployKeys bool `json:"force_push_whitelist_deploy_keys"`
|
||||
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
|
||||
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
|
||||
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
|
||||
|
@ -89,6 +99,11 @@ type EditBranchProtectionOption struct {
|
|||
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
|
||||
PushWhitelistTeams []string `json:"push_whitelist_teams"`
|
||||
PushWhitelistDeployKeys *bool `json:"push_whitelist_deploy_keys"`
|
||||
EnableForcePush *bool `json:"enable_force_push"`
|
||||
EnableForcePushWhitelist *bool `json:"enable_force_push_whitelist"`
|
||||
ForcePushWhitelistUsernames []string `json:"force_push_whitelist_usernames"`
|
||||
ForcePushWhitelistTeams []string `json:"force_push_whitelist_teams"`
|
||||
ForcePushWhitelistDeployKeys *bool `json:"force_push_whitelist_deploy_keys"`
|
||||
EnableMergeWhitelist *bool `json:"enable_merge_whitelist"`
|
||||
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
|
||||
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
|
||||
|
|
|
@ -2269,6 +2269,7 @@ settings.event_wiki_desc = Wiki page created, renamed, edited or deleted.
|
|||
settings.event_release = Release
|
||||
settings.event_release_desc = Release published, updated or deleted in a repository.
|
||||
settings.event_push = Push
|
||||
settings.event_force_push = Force Push
|
||||
settings.event_push_desc = Git push to a repository.
|
||||
settings.event_repository = Repository
|
||||
settings.event_repository_desc = Repository created or deleted.
|
||||
|
@ -2362,8 +2363,14 @@ settings.protect_this_branch = Enable Branch Protection
|
|||
settings.protect_this_branch_desc = Prevents deletion and restricts Git pushing and merging to the branch.
|
||||
settings.protect_disable_push = Disable Push
|
||||
settings.protect_disable_push_desc = No pushing will be allowed to this branch.
|
||||
settings.protect_disable_force_push = Disable Force Push
|
||||
settings.protect_disable_force_push_desc = No force pushing will be allowed to this branch.
|
||||
settings.protect_enable_push = Enable Push
|
||||
settings.protect_enable_push_desc = Anyone with write access will be allowed to push to this branch (but not force push).
|
||||
settings.protect_enable_force_push_all = Enable Force Push
|
||||
settings.protect_enable_force_push_all_desc = Anyone with push access will be allowed to force push to this branch.
|
||||
settings.protect_enable_force_push_whitelist = Whitelist Restricted Force Push
|
||||
settings.protect_enable_force_push_whitelist_desc = Only whitelisted users or teams with push access will be allowed to force push to this branch.
|
||||
settings.protect_enable_merge = Enable Merge
|
||||
settings.protect_enable_merge_desc = Anyone with write access will be allowed to merge the pull requests into this branch.
|
||||
settings.protect_whitelist_committers = Whitelist Restricted Push
|
||||
|
@ -2371,6 +2378,10 @@ settings.protect_whitelist_committers_desc = Only whitelisted users or teams wil
|
|||
settings.protect_whitelist_deploy_keys = Whitelist deploy keys with write access to push.
|
||||
settings.protect_whitelist_users = Whitelisted users for pushing:
|
||||
settings.protect_whitelist_teams = Whitelisted teams for pushing:
|
||||
settings.protect_whitelist_search_teams = Search teams…
|
||||
settings.protect_force_push_whitelist_users = Whitelisted users for force pushing:
|
||||
settings.protect_force_push_whitelist_teams = Whitelisted teams for force pushing:
|
||||
settings.protect_force_push_whitelist_deploy_keys = Whitelist deploy keys with push access to force push.
|
||||
settings.protect_merge_whitelist_committers = Enable Merge Whitelist
|
||||
settings.protect_merge_whitelist_committers_desc = Allow only whitelisted users or teams to merge pull requests into this branch.
|
||||
settings.protect_merge_whitelist_users = Whitelisted users for merging:
|
||||
|
|
|
@ -553,6 +553,15 @@ func CreateBranchProtection(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
|
||||
return
|
||||
}
|
||||
forcePushWhitelistUsers, err := user_model.GetUserIDsByNames(ctx, form.ForcePushWhitelistUsernames, false)
|
||||
if err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
|
||||
return
|
||||
}
|
||||
ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
|
||||
return
|
||||
}
|
||||
mergeWhitelistUsers, err := user_model.GetUserIDsByNames(ctx, form.MergeWhitelistUsernames, false)
|
||||
if err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
|
@ -571,7 +580,7 @@ func CreateBranchProtection(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
|
||||
return
|
||||
}
|
||||
var whitelistTeams, mergeWhitelistTeams, approvalsWhitelistTeams []int64
|
||||
var whitelistTeams, forcePushWhitelistTeams, mergeWhitelistTeams, approvalsWhitelistTeams []int64
|
||||
if repo.Owner.IsOrganization() {
|
||||
whitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.PushWhitelistTeams, false)
|
||||
if err != nil {
|
||||
|
@ -582,6 +591,15 @@ func CreateBranchProtection(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err)
|
||||
return
|
||||
}
|
||||
forcePushWhitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.ForcePushWhitelistTeams, false)
|
||||
if err != nil {
|
||||
if organization.IsErrTeamNotExist(err) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err)
|
||||
return
|
||||
}
|
||||
ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err)
|
||||
return
|
||||
}
|
||||
mergeWhitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.MergeWhitelistTeams, false)
|
||||
if err != nil {
|
||||
if organization.IsErrTeamNotExist(err) {
|
||||
|
@ -607,8 +625,11 @@ func CreateBranchProtection(ctx *context.APIContext) {
|
|||
RuleName: ruleName,
|
||||
CanPush: form.EnablePush,
|
||||
EnableWhitelist: form.EnablePush && form.EnablePushWhitelist,
|
||||
EnableMergeWhitelist: form.EnableMergeWhitelist,
|
||||
WhitelistDeployKeys: form.EnablePush && form.EnablePushWhitelist && form.PushWhitelistDeployKeys,
|
||||
CanForcePush: form.EnablePush && form.EnableForcePush,
|
||||
EnableForcePushWhitelist: form.EnablePush && form.EnableForcePush && form.EnableForcePushWhitelist,
|
||||
ForcePushWhitelistDeployKeys: form.EnablePush && form.EnableForcePush && form.EnableForcePushWhitelist && form.ForcePushWhitelistDeployKeys,
|
||||
EnableMergeWhitelist: form.EnableMergeWhitelist,
|
||||
EnableStatusCheck: form.EnableStatusCheck,
|
||||
StatusCheckContexts: form.StatusCheckContexts,
|
||||
EnableApprovalsWhitelist: form.EnableApprovalsWhitelist,
|
||||
|
@ -626,6 +647,8 @@ func CreateBranchProtection(ctx *context.APIContext) {
|
|||
err = git_model.UpdateProtectBranch(ctx, ctx.Repo.Repository, protectBranch, git_model.WhitelistOptions{
|
||||
UserIDs: whitelistUsers,
|
||||
TeamIDs: whitelistTeams,
|
||||
ForcePushUserIDs: forcePushWhitelistUsers,
|
||||
ForcePushTeamIDs: forcePushWhitelistTeams,
|
||||
MergeUserIDs: mergeWhitelistUsers,
|
||||
MergeTeamIDs: mergeWhitelistTeams,
|
||||
ApprovalsUserIDs: approvalsWhitelistUsers,
|
||||
|
@ -756,6 +779,27 @@ func EditBranchProtection(ctx *context.APIContext) {
|
|||
}
|
||||
}
|
||||
|
||||
if form.EnableForcePush != nil {
|
||||
if !*form.EnableForcePush {
|
||||
protectBranch.CanForcePush = false
|
||||
protectBranch.EnableForcePushWhitelist = false
|
||||
protectBranch.ForcePushWhitelistDeployKeys = false
|
||||
} else {
|
||||
protectBranch.CanForcePush = true
|
||||
if form.EnableForcePushWhitelist != nil {
|
||||
if !*form.EnableForcePushWhitelist {
|
||||
protectBranch.EnableForcePushWhitelist = false
|
||||
protectBranch.ForcePushWhitelistDeployKeys = false
|
||||
} else {
|
||||
protectBranch.EnableForcePushWhitelist = true
|
||||
if form.ForcePushWhitelistDeployKeys != nil {
|
||||
protectBranch.ForcePushWhitelistDeployKeys = *form.ForcePushWhitelistDeployKeys
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if form.EnableMergeWhitelist != nil {
|
||||
protectBranch.EnableMergeWhitelist = *form.EnableMergeWhitelist
|
||||
}
|
||||
|
@ -808,7 +852,7 @@ func EditBranchProtection(ctx *context.APIContext) {
|
|||
protectBranch.BlockOnOutdatedBranch = *form.BlockOnOutdatedBranch
|
||||
}
|
||||
|
||||
var whitelistUsers []int64
|
||||
var whitelistUsers, forcePushWhitelistUsers, mergeWhitelistUsers, approvalsWhitelistUsers []int64
|
||||
if form.PushWhitelistUsernames != nil {
|
||||
whitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.PushWhitelistUsernames, false)
|
||||
if err != nil {
|
||||
|
@ -822,7 +866,19 @@ func EditBranchProtection(ctx *context.APIContext) {
|
|||
} else {
|
||||
whitelistUsers = protectBranch.WhitelistUserIDs
|
||||
}
|
||||
var mergeWhitelistUsers []int64
|
||||
if form.ForcePushWhitelistUsernames != nil {
|
||||
forcePushWhitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.ForcePushWhitelistUsernames, false)
|
||||
if err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
|
||||
return
|
||||
}
|
||||
ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
forcePushWhitelistUsers = protectBranch.ForcePushWhitelistUserIDs
|
||||
}
|
||||
if form.MergeWhitelistUsernames != nil {
|
||||
mergeWhitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.MergeWhitelistUsernames, false)
|
||||
if err != nil {
|
||||
|
@ -836,7 +892,6 @@ func EditBranchProtection(ctx *context.APIContext) {
|
|||
} else {
|
||||
mergeWhitelistUsers = protectBranch.MergeWhitelistUserIDs
|
||||
}
|
||||
var approvalsWhitelistUsers []int64
|
||||
if form.ApprovalsWhitelistUsernames != nil {
|
||||
approvalsWhitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.ApprovalsWhitelistUsernames, false)
|
||||
if err != nil {
|
||||
|
@ -851,7 +906,7 @@ func EditBranchProtection(ctx *context.APIContext) {
|
|||
approvalsWhitelistUsers = protectBranch.ApprovalsWhitelistUserIDs
|
||||
}
|
||||
|
||||
var whitelistTeams, mergeWhitelistTeams, approvalsWhitelistTeams []int64
|
||||
var whitelistTeams, forcePushWhitelistTeams, mergeWhitelistTeams, approvalsWhitelistTeams []int64
|
||||
if repo.Owner.IsOrganization() {
|
||||
if form.PushWhitelistTeams != nil {
|
||||
whitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.PushWhitelistTeams, false)
|
||||
|
@ -866,6 +921,19 @@ func EditBranchProtection(ctx *context.APIContext) {
|
|||
} else {
|
||||
whitelistTeams = protectBranch.WhitelistTeamIDs
|
||||
}
|
||||
if form.ForcePushWhitelistTeams != nil {
|
||||
forcePushWhitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.ForcePushWhitelistTeams, false)
|
||||
if err != nil {
|
||||
if organization.IsErrTeamNotExist(err) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err)
|
||||
return
|
||||
}
|
||||
ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
forcePushWhitelistTeams = protectBranch.ForcePushWhitelistTeamIDs
|
||||
}
|
||||
if form.MergeWhitelistTeams != nil {
|
||||
mergeWhitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.MergeWhitelistTeams, false)
|
||||
if err != nil {
|
||||
|
@ -897,6 +965,8 @@ func EditBranchProtection(ctx *context.APIContext) {
|
|||
err = git_model.UpdateProtectBranch(ctx, ctx.Repo.Repository, protectBranch, git_model.WhitelistOptions{
|
||||
UserIDs: whitelistUsers,
|
||||
TeamIDs: whitelistTeams,
|
||||
ForcePushUserIDs: forcePushWhitelistUsers,
|
||||
ForcePushTeamIDs: forcePushWhitelistTeams,
|
||||
MergeUserIDs: mergeWhitelistUsers,
|
||||
MergeTeamIDs: mergeWhitelistTeams,
|
||||
ApprovalsUserIDs: approvalsWhitelistUsers,
|
||||
|
|
|
@ -183,6 +183,8 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r
|
|||
return
|
||||
}
|
||||
|
||||
isForcePush := false
|
||||
|
||||
// 2. Disallow force pushes to protected branches
|
||||
if oldCommitID != objectFormat.EmptyObjectID().String() {
|
||||
output, _, err := git.NewCommand(ctx, "rev-list", "--max-count=1").AddDynamicArguments(oldCommitID, "^"+newCommitID).RunStdString(&git.RunOpts{Dir: repo.RepoPath(), Env: ctx.env})
|
||||
|
@ -193,12 +195,15 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r
|
|||
})
|
||||
return
|
||||
} else if len(output) > 0 {
|
||||
log.Warn("Forbidden: Branch: %s in %-v is protected from force push", branchName, repo)
|
||||
ctx.JSON(http.StatusForbidden, private.Response{
|
||||
UserMsg: fmt.Sprintf("branch %s is protected from force push", branchName),
|
||||
})
|
||||
return
|
||||
|
||||
if protectBranch.CanForcePush {
|
||||
isForcePush = true
|
||||
} else {
|
||||
log.Warn("Forbidden: Branch: %s in %-v is protected from force push", branchName, repo)
|
||||
ctx.JSON(http.StatusForbidden, private.Response{
|
||||
UserMsg: fmt.Sprintf("branch %s is protected from force push", branchName),
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,10 +250,15 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r
|
|||
}
|
||||
}
|
||||
|
||||
// 5. Check if the doer is allowed to push
|
||||
// 5. Check if the doer is allowed to push (and force-push if the incoming push is a force-push)
|
||||
var canPush bool
|
||||
if ctx.opts.DeployKeyID != 0 {
|
||||
canPush = !changedProtectedfiles && protectBranch.CanPush && (!protectBranch.EnableWhitelist || protectBranch.WhitelistDeployKeys)
|
||||
// This flag is only ever true if protectBranch.CanForcePush is true
|
||||
if isForcePush {
|
||||
canPush = !changedProtectedfiles && protectBranch.CanPush && (!protectBranch.EnableForcePushWhitelist || protectBranch.ForcePushWhitelistDeployKeys)
|
||||
} else {
|
||||
canPush = !changedProtectedfiles && protectBranch.CanPush && (!protectBranch.EnableWhitelist || protectBranch.WhitelistDeployKeys)
|
||||
}
|
||||
} else {
|
||||
user, err := user_model.GetUserByID(ctx, ctx.opts.UserID)
|
||||
if err != nil {
|
||||
|
@ -258,7 +268,11 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r
|
|||
})
|
||||
return
|
||||
}
|
||||
canPush = !changedProtectedfiles && protectBranch.CanUserPush(ctx, user)
|
||||
if isForcePush {
|
||||
canPush = !changedProtectedfiles && protectBranch.CanUserForcePush(ctx, user)
|
||||
} else {
|
||||
canPush = !changedProtectedfiles && protectBranch.CanUserPush(ctx, user)
|
||||
}
|
||||
}
|
||||
|
||||
// 6. If we're not allowed to push directly
|
||||
|
@ -294,6 +308,13 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r
|
|||
}
|
||||
|
||||
// Or we're simply not able to push to this protected branch
|
||||
if isForcePush {
|
||||
log.Warn("Forbidden: User %d is not allowed to force-push to protected branch: %s in %-v", ctx.opts.UserID, branchName, repo)
|
||||
ctx.JSON(http.StatusForbidden, private.Response{
|
||||
UserMsg: fmt.Sprintf("Not allowed to force-push to protected branch %s", branchName),
|
||||
})
|
||||
return
|
||||
}
|
||||
log.Warn("Forbidden: User %d is not allowed to push to protected branch: %s in %-v", ctx.opts.UserID, branchName, repo)
|
||||
ctx.JSON(http.StatusForbidden, private.Response{
|
||||
UserMsg: fmt.Sprintf("Not allowed to push to protected branch %s", branchName),
|
||||
|
|
|
@ -77,6 +77,7 @@ func SettingsProtectedBranch(c *context.Context) {
|
|||
}
|
||||
c.Data["Users"] = users
|
||||
c.Data["whitelist_users"] = strings.Join(base.Int64sToStrings(rule.WhitelistUserIDs), ",")
|
||||
c.Data["force_push_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.ForcePushWhitelistUserIDs), ",")
|
||||
c.Data["merge_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.MergeWhitelistUserIDs), ",")
|
||||
c.Data["approvals_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.ApprovalsWhitelistUserIDs), ",")
|
||||
c.Data["status_check_contexts"] = strings.Join(rule.StatusCheckContexts, "\n")
|
||||
|
@ -91,6 +92,7 @@ func SettingsProtectedBranch(c *context.Context) {
|
|||
}
|
||||
c.Data["Teams"] = teams
|
||||
c.Data["whitelist_teams"] = strings.Join(base.Int64sToStrings(rule.WhitelistTeamIDs), ",")
|
||||
c.Data["force_push_whitelist_teams"] = strings.Join(base.Int64sToStrings(rule.ForcePushWhitelistTeamIDs), ",")
|
||||
c.Data["merge_whitelist_teams"] = strings.Join(base.Int64sToStrings(rule.MergeWhitelistTeamIDs), ",")
|
||||
c.Data["approvals_whitelist_teams"] = strings.Join(base.Int64sToStrings(rule.ApprovalsWhitelistTeamIDs), ",")
|
||||
}
|
||||
|
@ -149,7 +151,7 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
var whitelistUsers, whitelistTeams, mergeWhitelistUsers, mergeWhitelistTeams, approvalsWhitelistUsers, approvalsWhitelistTeams []int64
|
||||
var whitelistUsers, whitelistTeams, forcePushWhitelistUsers, forcePushWhitelistTeams, mergeWhitelistUsers, mergeWhitelistTeams, approvalsWhitelistUsers, approvalsWhitelistTeams []int64
|
||||
protectBranch.RuleName = f.RuleName
|
||||
if f.RequiredApprovals < 0 {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.protected_branch_required_approvals_min"))
|
||||
|
@ -178,6 +180,27 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
|
|||
protectBranch.WhitelistDeployKeys = false
|
||||
}
|
||||
|
||||
switch f.EnableForcePush {
|
||||
case "all":
|
||||
protectBranch.CanForcePush = true
|
||||
protectBranch.EnableForcePushWhitelist = false
|
||||
protectBranch.ForcePushWhitelistDeployKeys = false
|
||||
case "whitelist":
|
||||
protectBranch.CanForcePush = true
|
||||
protectBranch.EnableForcePushWhitelist = true
|
||||
protectBranch.ForcePushWhitelistDeployKeys = f.ForcePushWhitelistDeployKeys
|
||||
if strings.TrimSpace(f.ForcePushWhitelistUsers) != "" {
|
||||
forcePushWhitelistUsers, _ = base.StringsToInt64s(strings.Split(f.ForcePushWhitelistUsers, ","))
|
||||
}
|
||||
if strings.TrimSpace(f.ForcePushWhitelistTeams) != "" {
|
||||
forcePushWhitelistTeams, _ = base.StringsToInt64s(strings.Split(f.ForcePushWhitelistTeams, ","))
|
||||
}
|
||||
default:
|
||||
protectBranch.CanForcePush = false
|
||||
protectBranch.EnableForcePushWhitelist = false
|
||||
protectBranch.ForcePushWhitelistDeployKeys = false
|
||||
}
|
||||
|
||||
protectBranch.EnableMergeWhitelist = f.EnableMergeWhitelist
|
||||
if f.EnableMergeWhitelist {
|
||||
if strings.TrimSpace(f.MergeWhitelistUsers) != "" {
|
||||
|
@ -237,6 +260,8 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
|
|||
err = git_model.UpdateProtectBranch(ctx, ctx.Repo.Repository, protectBranch, git_model.WhitelistOptions{
|
||||
UserIDs: whitelistUsers,
|
||||
TeamIDs: whitelistTeams,
|
||||
ForcePushUserIDs: forcePushWhitelistUsers,
|
||||
ForcePushTeamIDs: forcePushWhitelistTeams,
|
||||
MergeUserIDs: mergeWhitelistUsers,
|
||||
MergeTeamIDs: mergeWhitelistTeams,
|
||||
ApprovalsUserIDs: approvalsWhitelistUsers,
|
||||
|
|
|
@ -134,6 +134,7 @@ func ToBranchProtection(ctx context.Context, bp *git_model.ProtectedBranch, repo
|
|||
}
|
||||
|
||||
pushWhitelistUsernames := getWhitelistEntities(readers, bp.WhitelistUserIDs)
|
||||
forcePushWhitelistUsernames := getWhitelistEntities(readers, bp.ForcePushWhitelistUserIDs)
|
||||
mergeWhitelistUsernames := getWhitelistEntities(readers, bp.MergeWhitelistUserIDs)
|
||||
approvalsWhitelistUsernames := getWhitelistEntities(readers, bp.ApprovalsWhitelistUserIDs)
|
||||
|
||||
|
@ -143,6 +144,7 @@ func ToBranchProtection(ctx context.Context, bp *git_model.ProtectedBranch, repo
|
|||
}
|
||||
|
||||
pushWhitelistTeams := getWhitelistEntities(teamReaders, bp.WhitelistTeamIDs)
|
||||
forcePushWhitelistTeams := getWhitelistEntities(teamReaders, bp.ForcePushWhitelistTeamIDs)
|
||||
mergeWhitelistTeams := getWhitelistEntities(teamReaders, bp.MergeWhitelistTeamIDs)
|
||||
approvalsWhitelistTeams := getWhitelistEntities(teamReaders, bp.ApprovalsWhitelistTeamIDs)
|
||||
|
||||
|
@ -159,6 +161,11 @@ func ToBranchProtection(ctx context.Context, bp *git_model.ProtectedBranch, repo
|
|||
PushWhitelistUsernames: pushWhitelistUsernames,
|
||||
PushWhitelistTeams: pushWhitelistTeams,
|
||||
PushWhitelistDeployKeys: bp.WhitelistDeployKeys,
|
||||
EnableForcePush: bp.CanForcePush,
|
||||
EnableForcePushWhitelist: bp.EnableForcePushWhitelist,
|
||||
ForcePushWhitelistUsernames: forcePushWhitelistUsernames,
|
||||
ForcePushWhitelistTeams: forcePushWhitelistTeams,
|
||||
ForcePushWhitelistDeployKeys: bp.ForcePushWhitelistDeployKeys,
|
||||
EnableMergeWhitelist: bp.EnableMergeWhitelist,
|
||||
MergeWhitelistUsernames: mergeWhitelistUsernames,
|
||||
MergeWhitelistTeams: mergeWhitelistTeams,
|
||||
|
|
|
@ -195,6 +195,10 @@ type ProtectBranchForm struct {
|
|||
WhitelistUsers string
|
||||
WhitelistTeams string
|
||||
WhitelistDeployKeys bool
|
||||
EnableForcePush string
|
||||
ForcePushWhitelistUsers string
|
||||
ForcePushWhitelistTeams string
|
||||
ForcePushWhitelistDeployKeys bool
|
||||
EnableMergeWhitelist bool
|
||||
MergeWhitelistUsers string
|
||||
MergeWhitelistTeams string
|
||||
|
|
|
@ -116,27 +116,25 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *issues_model.PullRequest,
|
|||
return false, false, err
|
||||
}
|
||||
|
||||
// can't do rebase on protected branch because need force push
|
||||
if pb == nil {
|
||||
if err := pr.LoadBaseRepo(ctx); err != nil {
|
||||
return false, false, err
|
||||
if err := pr.LoadBaseRepo(ctx); err != nil {
|
||||
return false, false, err
|
||||
}
|
||||
prUnit, err := pr.BaseRepo.GetUnit(ctx, unit.TypePullRequests)
|
||||
if err != nil {
|
||||
if repo_model.IsErrUnitTypeNotExist(err) {
|
||||
return false, false, nil
|
||||
}
|
||||
prUnit, err := pr.BaseRepo.GetUnit(ctx, unit.TypePullRequests)
|
||||
if err != nil {
|
||||
if repo_model.IsErrUnitTypeNotExist(err) {
|
||||
return false, false, nil
|
||||
}
|
||||
log.Error("pr.BaseRepo.GetUnit(unit.TypePullRequests): %v", err)
|
||||
return false, false, err
|
||||
}
|
||||
rebaseAllowed = prUnit.PullRequestsConfig().AllowRebaseUpdate
|
||||
log.Error("pr.BaseRepo.GetUnit(unit.TypePullRequests): %v", err)
|
||||
return false, false, err
|
||||
}
|
||||
|
||||
// Update function need push permission
|
||||
rebaseAllowed = prUnit.PullRequestsConfig().AllowRebaseUpdate
|
||||
|
||||
// If branch protected, disable rebase unless user is whitelisted to force push (which extends regular push)
|
||||
if pb != nil {
|
||||
pb.Repo = pull.BaseRepo
|
||||
if !pb.CanUserPush(ctx, user) {
|
||||
return false, false, nil
|
||||
if !pb.CanUserForcePush(ctx, user) {
|
||||
rebaseAllowed = false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,6 +94,69 @@
|
|||
<p class="help">{{ctx.Locale.Tr "repo.settings.require_signed_commits_desc"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<h5 class="ui dividing header">{{ctx.Locale.Tr "repo.settings.event_force_push"}}</h5>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input type="radio" name="enable_force_push" value="none" class="toggle-target-disabled" data-target="#force_push_whitelist_box" {{if not .Rule.CanForcePush}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.protect_disable_force_push"}}</label>
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.protect_disable_force_push_desc"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input type="radio" name="enable_force_push" value="all" class="toggle-target-disabled" data-target="#force_push_whitelist_box" {{if and (.Rule.CanForcePush) (not .Rule.EnableForcePushWhitelist)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.protect_enable_force_push_all"}}</label>
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.protect_enable_force_push_all_desc"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grouped fields">
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input type="radio" name="enable_force_push" value="whitelist" class="toggle-target-enabled" data-target="#force_push_whitelist_box" {{if and (.Rule.CanForcePush) (.Rule.EnableForcePushWhitelist)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.protect_enable_force_push_whitelist"}}</label>
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.protect_enable_force_push_whitelist_desc"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="force_push_whitelist_box" class="grouped fields {{if not .Rule.EnableForcePushWhitelist}}disabled{{end}}">
|
||||
<div class="checkbox-sub-item field">
|
||||
<label>{{ctx.Locale.Tr "repo.settings.protect_force_push_whitelist_users"}}</label>
|
||||
<div class="ui multiple search selection dropdown">
|
||||
<input type="hidden" name="force_push_whitelist_users" value="{{.force_push_whitelist_users}}">
|
||||
<div class="default text">{{ctx.Locale.Tr "repo.settings.protect_whitelist_search_users"}}</div>
|
||||
<div class="menu">
|
||||
{{range .Users}}
|
||||
<div class="item" data-value="{{.ID}}">
|
||||
{{ctx.AvatarUtils.Avatar . 28 "mini"}}{{template "repo/search_name" .}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{if .Owner.IsOrganization}}
|
||||
<div class="checkbox-sub-item field">
|
||||
<label>{{ctx.Locale.Tr "repo.settings.protect_force_push_whitelist_teams"}}</label>
|
||||
<div class="ui multiple search selection dropdown">
|
||||
<input type="hidden" name="force_push_whitelist_teams" value="{{.force_push_whitelist_teams}}">
|
||||
<div class="default text">{{ctx.Locale.Tr "repo.settings.protect_whitelist_search_teams"}}</div>
|
||||
<div class="menu">
|
||||
{{range .Teams}}
|
||||
<div class="item" data-value="{{.ID}}">
|
||||
{{svg "octicon-people"}}
|
||||
{{.Name}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="checkbox-sub-item field">
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="force_push_whitelist_deploy_keys" {{if .Rule.ForcePushWhitelistDeployKeys}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.protect_force_push_whitelist_deploy_keys"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h5 class="ui dividing header">{{ctx.Locale.Tr "repo.settings.event_pull_request_approvals"}}</h5>
|
||||
<div class="field">
|
||||
<label>{{ctx.Locale.Tr "repo.settings.protect_required_approvals"}}</label>
|
||||
|
|
|
@ -18253,6 +18253,14 @@
|
|||
"type": "boolean",
|
||||
"x-go-name": "EnableApprovalsWhitelist"
|
||||
},
|
||||
"enable_force_push": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "EnableForcePush"
|
||||
},
|
||||
"enable_force_push_whitelist": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "EnableForcePushWhitelist"
|
||||
},
|
||||
"enable_merge_whitelist": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "EnableMergeWhitelist"
|
||||
|
@ -18269,6 +18277,24 @@
|
|||
"type": "boolean",
|
||||
"x-go-name": "EnableStatusCheck"
|
||||
},
|
||||
"force_push_whitelist_deploy_keys": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "ForcePushWhitelistDeployKeys"
|
||||
},
|
||||
"force_push_whitelist_teams": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-name": "ForcePushWhitelistTeams"
|
||||
},
|
||||
"force_push_whitelist_usernames": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-name": "ForcePushWhitelistUsernames"
|
||||
},
|
||||
"ignore_stale_approvals": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "IgnoreStaleApprovals"
|
||||
|
@ -18917,6 +18943,14 @@
|
|||
"type": "boolean",
|
||||
"x-go-name": "EnableApprovalsWhitelist"
|
||||
},
|
||||
"enable_force_push": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "EnableForcePush"
|
||||
},
|
||||
"enable_force_push_whitelist": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "EnableForcePushWhitelist"
|
||||
},
|
||||
"enable_merge_whitelist": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "EnableMergeWhitelist"
|
||||
|
@ -18933,6 +18967,24 @@
|
|||
"type": "boolean",
|
||||
"x-go-name": "EnableStatusCheck"
|
||||
},
|
||||
"force_push_whitelist_deploy_keys": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "ForcePushWhitelistDeployKeys"
|
||||
},
|
||||
"force_push_whitelist_teams": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-name": "ForcePushWhitelistTeams"
|
||||
},
|
||||
"force_push_whitelist_usernames": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-name": "ForcePushWhitelistUsernames"
|
||||
},
|
||||
"ignore_stale_approvals": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "IgnoreStaleApprovals"
|
||||
|
@ -20076,6 +20128,14 @@
|
|||
"type": "boolean",
|
||||
"x-go-name": "EnableApprovalsWhitelist"
|
||||
},
|
||||
"enable_force_push": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "EnableForcePush"
|
||||
},
|
||||
"enable_force_push_whitelist": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "EnableForcePushWhitelist"
|
||||
},
|
||||
"enable_merge_whitelist": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "EnableMergeWhitelist"
|
||||
|
@ -20092,6 +20152,24 @@
|
|||
"type": "boolean",
|
||||
"x-go-name": "EnableStatusCheck"
|
||||
},
|
||||
"force_push_whitelist_deploy_keys": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "ForcePushWhitelistDeployKeys"
|
||||
},
|
||||
"force_push_whitelist_teams": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-name": "ForcePushWhitelistTeams"
|
||||
},
|
||||
"force_push_whitelist_usernames": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-name": "ForcePushWhitelistUsernames"
|
||||
},
|
||||
"ignore_stale_approvals": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "IgnoreStaleApprovals"
|
||||
|
|
Loading…
Reference in New Issue