Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion feature/github-repo-importer/cmd/validate-org_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ func TestValidateOrg_StagedMembersResolveAgainstPromotedTeams(t *testing.T) {
stagedDir := filepath.Join(dir, "importer_tmp_dir", "organisation")
require.NoError(t, os.MkdirAll(stagedDir, 0o755))
require.NoError(t, os.WriteFile(filepath.Join(stagedDir, "members.yaml"),
[]byte("members:\n - username: alice\n role: owner\n teams:\n - name: platform\n"), 0o644))
[]byte("members:\n - username: alice\n role: owner\n teams:\n - name: platform\n role: maintainer\n"), 0o644))

out, err := runValidateOrgCmd(t, dir, "alice")

Expand Down
15 changes: 15 additions & 0 deletions feature/github-repo-importer/pkg/github/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ func (c *MembersConfig) ValidateEntries(knownTeams []string) []error {
}
memberTeams[teamKey] = struct{}{}

if member.Role == MemberRoleOwner && effectiveTeamRole(team.Role) == TeamRoleMember {
if team.Role == "" {
errs = append(errs, fmt.Errorf("member %q is an organisation owner, so team %q needs role %q: the role defaults to %q when omitted, and GitHub reports owners as maintainers of every team they belong to, so the plan would keep proposing this change without it ever taking effect", member.Username, team.Name, TeamRoleMaintainer, TeamRoleMember))
} else {
errs = append(errs, fmt.Errorf("member %q is an organisation owner, so team %q cannot use role %q: GitHub reports owners as maintainers of every team they belong to, so the plan would keep proposing this change without it ever taking effect", member.Username, team.Name, TeamRoleMember))
}
}

if _, ok := teamSet[team.Name]; ok {
continue
}
Expand All @@ -71,6 +79,13 @@ func (c *MembersConfig) ValidateEntries(knownTeams []string) []error {
return errs
}

func effectiveTeamRole(role string) string {
if role == "" {
return TeamRoleMember
}
return role
}

// ValidateProtectedOwners checks that every protected owner is present and still an owner.
func (c *MembersConfig) ValidateProtectedOwners(protectedOwners []string) []error {
var errs []error
Expand Down
33 changes: 32 additions & 1 deletion feature/github-repo-importer/pkg/github/members_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,45 @@ func TestMembersConfigValidate(t *testing.T) {
name: "valid config with team member and maintainer roles",
config: MembersConfig{
Members: []Member{
{Username: "alice", Role: MemberRoleOwner, Teams: []TeamMembership{{Name: "platform"}}},
{Username: "alice", Role: MemberRoleOwner, Teams: []TeamMembership{{Name: "platform", Role: TeamRoleMaintainer}}},
{Username: "bob", Role: MemberRoleMember, Teams: []TeamMembership{{Name: "platform", Role: TeamRoleMaintainer}, {Name: "security-core"}}},
{Username: "carol", Role: MemberRoleMember},
},
},
protectedOwners: []string{"alice"},
wantErrors: nil,
},
{
name: "owner given a plain member role in a team is rejected",
config: MembersConfig{
Members: []Member{
{Username: "alice", Role: MemberRoleOwner, Teams: []TeamMembership{{Name: "platform", Role: TeamRoleMember}}},
},
},
wantErrors: []string{
`member "alice" is an organisation owner, so team "platform" cannot use role "member": GitHub reports owners as maintainers of every team they belong to, so the plan would keep proposing this change without it ever taking effect`,
},
},
{
name: "owner with an omitted team role is rejected, since it defaults to member",
config: MembersConfig{
Members: []Member{
{Username: "alice", Role: MemberRoleOwner, Teams: []TeamMembership{{Name: "platform"}}},
},
},
wantErrors: []string{
`member "alice" is an organisation owner, so team "platform" needs role "maintainer": the role defaults to "member" when omitted, and GitHub reports owners as maintainers of every team they belong to, so the plan would keep proposing this change without it ever taking effect`,
},
},
{
name: "a plain member may hold either team role",
config: MembersConfig{
Members: []Member{
{Username: "bob", Role: MemberRoleMember, Teams: []TeamMembership{{Name: "platform", Role: TeamRoleMember}, {Name: "security-core"}}},
},
},
wantErrors: nil,
},
{
name: "duplicate username rejected",
config: MembersConfig{
Expand Down
Loading