feat(orgs): auto-create default teams on org creation (#513) #708
@@ -3,6 +3,7 @@
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- Auto-create default teams on org creation: Developers (write), Reviewers (read), CI/CD (actions+packages) (#513)
|
||||
- Branch protection delete allowlist: configurable per-user/team/deploy-key allowlist for deleting protected branches (#696)
|
||||
- Workflow subdirectory discovery: workflows in subdirectories of `.mokogitea/workflows/` are now auto-discovered (#693)
|
||||
- API token scope `read:licensing` / `write:licensing` for licensing endpoints (#697)
|
||||
|
||||
@@ -323,6 +323,60 @@ func (org *Organization) UnitPermission(ctx context.Context, doer *user_model.Us
|
||||
}
|
||||
|
||||
// CreateOrganization creates record of a new organization.
|
||||
// DefaultTeamSpec defines a team to auto-create when a new organization is created.
|
||||
type DefaultTeamSpec struct {
|
||||
Name string
|
||||
Description string
|
||||
AccessMode perm.AccessMode
|
||||
IncludesAllRepositories bool
|
||||
CanCreateOrgRepo bool
|
||||
Units map[unit.Type]perm.AccessMode
|
||||
}
|
||||
|
||||
// DefaultOrgTeams is the list of teams created for every new organization
|
||||
// (in addition to the mandatory Owners team). Override in tests or via init.
|
||||
var DefaultOrgTeams = []DefaultTeamSpec{
|
||||
{
|
||||
Name: "Developers",
|
||||
Description: "Members with write access to code, issues, and pull requests",
|
||||
AccessMode: perm.AccessModeWrite,
|
||||
IncludesAllRepositories: true,
|
||||
Units: map[unit.Type]perm.AccessMode{
|
||||
unit.TypeCode: perm.AccessModeWrite,
|
||||
unit.TypeIssues: perm.AccessModeWrite,
|
||||
unit.TypePullRequests: perm.AccessModeWrite,
|
||||
unit.TypeReleases: perm.AccessModeRead,
|
||||
unit.TypeWiki: perm.AccessModeWrite,
|
||||
unit.TypeProjects: perm.AccessModeWrite,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Reviewers",
|
||||
Description: "Members with read access for code review",
|
||||
AccessMode: perm.AccessModeRead,
|
||||
IncludesAllRepositories: true,
|
||||
Units: map[unit.Type]perm.AccessMode{
|
||||
unit.TypeCode: perm.AccessModeRead,
|
||||
unit.TypeIssues: perm.AccessModeRead,
|
||||
unit.TypePullRequests: perm.AccessModeRead,
|
||||
unit.TypeReleases: perm.AccessModeRead,
|
||||
unit.TypeWiki: perm.AccessModeRead,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "CI/CD",
|
||||
Description: "Members with write access to actions and packages",
|
||||
AccessMode: perm.AccessModeWrite,
|
||||
IncludesAllRepositories: true,
|
||||
Units: map[unit.Type]perm.AccessMode{
|
||||
unit.TypeCode: perm.AccessModeRead,
|
||||
unit.TypeActions: perm.AccessModeWrite,
|
||||
unit.TypePackages: perm.AccessModeWrite,
|
||||
unit.TypeReleases: perm.AccessModeWrite,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func CreateOrganization(ctx context.Context, org *Organization, owner *user_model.User) (err error) {
|
||||
if !owner.CanCreateOrganization() {
|
||||
return ErrUserNotAllowedCreateOrg{}
|
||||
@@ -348,7 +402,7 @@ func CreateOrganization(ctx context.Context, org *Organization, owner *user_mode
|
||||
}
|
||||
org.UseCustomAvatar = true
|
||||
org.MaxRepoCreation = -1
|
||||
org.NumTeams = 1
|
||||
org.NumTeams = 1 + len(DefaultOrgTeams)
|
||||
org.NumMembers = 1
|
||||
org.Type = user_model.UserTypeOrganization
|
||||
|
||||
@@ -413,6 +467,37 @@ func CreateOrganization(ctx context.Context, org *Organization, owner *user_mode
|
||||
}); err != nil {
|
||||
return fmt.Errorf("insert team-user relation: %w", err)
|
||||
}
|
||||
|
||||
for _, spec := range DefaultOrgTeams {
|
||||
dt := &Team{
|
||||
OrgID: org.ID,
|
||||
LowerName: strings.ToLower(spec.Name),
|
||||
Name: spec.Name,
|
||||
Description: spec.Description,
|
||||
AccessMode: spec.AccessMode,
|
||||
IncludesAllRepositories: spec.IncludesAllRepositories,
|
||||
CanCreateOrgRepo: spec.CanCreateOrgRepo,
|
||||
}
|
||||
if err = db.Insert(ctx, dt); err != nil {
|
||||
return fmt.Errorf("insert default team %q: %w", spec.Name, err)
|
||||
}
|
||||
|
||||
dtUnits := make([]TeamUnit, 0, len(spec.Units))
|
||||
for tp, am := range spec.Units {
|
||||
dtUnits = append(dtUnits, TeamUnit{
|
||||
OrgID: org.ID,
|
||||
TeamID: dt.ID,
|
||||
Type: tp,
|
||||
AccessMode: am,
|
||||
})
|
||||
}
|
||||
if len(dtUnits) > 0 {
|
||||
if err = db.Insert(ctx, &dtUnits); err != nil {
|
||||
return fmt.Errorf("insert default team %q units: %w", spec.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user