Skip to content

Commit 61d0821

Browse files
authored
fix: Refactored github_repository_collaborators for team id (#2420)
Signed-off-by: Steve Hipwell <[email protected]>
1 parent 5809617 commit 61d0821

File tree

2 files changed

+81
-47
lines changed

2 files changed

+81
-47
lines changed

github/resource_github_repository_collaborators.go

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"log"
7+
"slices"
78
"sort"
89
"strconv"
910

@@ -136,37 +137,46 @@ func flattenUserCollaborators(objs []userCollaborator, invites []invitedCollabor
136137

137138
type teamCollaborator struct {
138139
permission string
140+
teamID int64
139141
teamSlug string
140142
}
141143

142144
func (c teamCollaborator) Empty() bool {
143145
return c == teamCollaborator{}
144146
}
145147

146-
func flattenTeamCollaborator(obj teamCollaborator) interface{} {
148+
func flattenTeamCollaborator(obj teamCollaborator, teamIDs []int64) interface{} {
147149
if obj.Empty() {
148150
return nil
149151
}
152+
153+
var teamIDString string
154+
if slices.Contains(teamIDs, obj.teamID) {
155+
teamIDString = strconv.FormatInt(obj.teamID, 10)
156+
} else {
157+
teamIDString = obj.teamSlug
158+
}
159+
150160
transformed := map[string]interface{}{
151161
"permission": obj.permission,
152-
"team_id": obj.teamSlug,
162+
"team_id": teamIDString,
153163
}
154164

155165
return transformed
156166
}
157167

158-
func flattenTeamCollaborators(objs []teamCollaborator) []interface{} {
168+
func flattenTeamCollaborators(objs []teamCollaborator, teamIDs []int64) []interface{} {
159169
if objs == nil {
160170
return nil
161171
}
162172

163173
sort.SliceStable(objs, func(i, j int) bool {
164-
return objs[i].teamSlug < objs[j].teamSlug
174+
return objs[i].teamID < objs[j].teamID
165175
})
166176

167177
items := make([]interface{}, len(objs))
168178
for i, obj := range objs {
169-
items[i] = flattenTeamCollaborator(obj)
179+
items[i] = flattenTeamCollaborator(obj, teamIDs)
170180
}
171181

172182
return items
@@ -248,7 +258,7 @@ func listTeams(client *github.Client, isOrg bool, ctx context.Context, owner, re
248258
for _, t := range repoTeams {
249259
permissionName := getPermission(t.GetPermission())
250260

251-
teamCollaborators = append(teamCollaborators, teamCollaborator{permissionName, t.GetSlug()})
261+
teamCollaborators = append(teamCollaborators, teamCollaborator{permissionName, t.GetID(), t.GetSlug()})
252262
}
253263

254264
if resp.NextPage == 0 {
@@ -376,33 +386,31 @@ func matchUserCollaboratorsAndInvites(
376386
func matchTeamCollaborators(
377387
repoName string, want []interface{}, has []teamCollaborator, meta interface{}) error {
378388
client := meta.(*Owner).v3client
389+
orgID := meta.(*Owner).id
379390
owner := meta.(*Owner).name
380391
ctx := context.Background()
381392

393+
remove := make([]teamCollaborator, 0)
382394
for _, hasTeam := range has {
383395
var wantPerm string
384396
for _, w := range want {
385397
teamData := w.(map[string]interface{})
386398
teamIDString := teamData["team_id"].(string)
387-
teamSlug, err := getTeamSlug(teamIDString, meta)
399+
teamID, err := getTeamID(teamIDString, meta)
388400
if err != nil {
389401
return err
390402
}
391-
if teamSlug == hasTeam.teamSlug {
403+
if teamID == hasTeam.teamID {
392404
wantPerm = teamData["permission"].(string)
393405
break
394406
}
395407
}
396408
if wantPerm == "" { // user should NOT have permission
397-
log.Printf("[DEBUG] Removing team %s from repo: %s.", hasTeam.teamSlug, repoName)
398-
_, err := client.Teams.RemoveTeamRepoBySlug(ctx, owner, hasTeam.teamSlug, owner, repoName)
399-
if err != nil {
400-
return err
401-
}
409+
remove = append(remove, hasTeam)
402410
} else if wantPerm != hasTeam.permission { // permission should be updated
403-
log.Printf("[DEBUG] Updating team %s permission from %s to %s for repo: %s.", hasTeam.teamSlug, hasTeam.permission, wantPerm, repoName)
404-
_, err := client.Teams.AddTeamRepoBySlug(
405-
ctx, owner, hasTeam.teamSlug, owner, repoName, &github.TeamAddTeamRepoOptions{
411+
log.Printf("[DEBUG] Updating team %d permission from %s to %s for repo: %s.", hasTeam.teamID, hasTeam.permission, wantPerm, repoName)
412+
_, err := client.Teams.AddTeamRepoByID(
413+
ctx, orgID, hasTeam.teamID, owner, repoName, &github.TeamAddTeamRepoOptions{
406414
Permission: wantPerm,
407415
},
408416
)
@@ -415,32 +423,41 @@ func matchTeamCollaborators(
415423
for _, t := range want {
416424
teamData := t.(map[string]interface{})
417425
teamIDString := teamData["team_id"].(string)
418-
teamSlug, err := getTeamSlug(teamIDString, meta)
426+
teamID, err := getTeamID(teamIDString, meta)
419427
if err != nil {
420428
return err
421429
}
422-
permission := teamData["permission"].(string)
423430
var found bool
424431
for _, c := range has {
425-
if teamSlug == c.teamSlug {
432+
if teamID == c.teamID {
426433
found = true
427434
break
428435
}
429436
}
430437
if found {
431438
continue
432439
}
440+
permission := teamData["permission"].(string)
433441
// team needs to be added
434-
log.Printf("[DEBUG] Adding team %s with permission %s for repo: %s.", teamSlug, permission, repoName)
435-
_, err = client.Teams.AddTeamRepoBySlug(
436-
ctx, owner, teamSlug, owner, repoName, &github.TeamAddTeamRepoOptions{
442+
log.Printf("[DEBUG] Adding team %s with permission %s for repo: %s.", teamIDString, permission, repoName)
443+
_, err = client.Teams.AddTeamRepoByID(
444+
ctx, orgID, teamID, owner, repoName, &github.TeamAddTeamRepoOptions{
437445
Permission: permission,
438446
},
439447
)
440448
if err != nil {
441449
return err
442450
}
443451
}
452+
453+
for _, team := range remove {
454+
log.Printf("[DEBUG] Removing team %d from repo: %s.", team.teamID, repoName)
455+
_, err := client.Teams.RemoveTeamRepoByID(ctx, orgID, team.teamID, owner, repoName)
456+
if err != nil {
457+
return err
458+
}
459+
}
460+
444461
return nil
445462
}
446463

@@ -454,6 +471,14 @@ func resourceGithubRepositoryCollaboratorsCreate(d *schema.ResourceData, meta in
454471
repoName := d.Get("repository").(string)
455472
ctx := context.Background()
456473

474+
teamsMap := make(map[string]struct{})
475+
for _, team := range teams {
476+
teamIDString := team.(map[string]interface{})["team_id"].(string)
477+
if _, found := teamsMap[teamIDString]; found {
478+
return fmt.Errorf("duplicate set member: %s", teamIDString)
479+
}
480+
teamsMap[teamIDString] = struct{}{}
481+
}
457482
usersMap := make(map[string]struct{})
458483
for _, user := range users {
459484
username := user.(map[string]interface{})["username"].(string)
@@ -462,26 +487,18 @@ func resourceGithubRepositoryCollaboratorsCreate(d *schema.ResourceData, meta in
462487
}
463488
usersMap[username] = struct{}{}
464489
}
465-
teamsMap := make(map[string]struct{})
466-
for _, team := range teams {
467-
teamID := team.(map[string]interface{})["team_id"].(string)
468-
if _, found := teamsMap[teamID]; found {
469-
return fmt.Errorf("duplicate set member: %s", teamID)
470-
}
471-
teamsMap[teamID] = struct{}{}
472-
}
473490

474491
userCollaborators, invitations, teamCollaborators, err := listAllCollaborators(client, isOrg, ctx, owner, repoName)
475492
if err != nil {
476493
return deleteResourceOn404AndSwallow304OtherwiseReturnError(err, d, "repository collaborators (%s/%s)", owner, repoName)
477494
}
478495

479-
err = matchUserCollaboratorsAndInvites(repoName, users, userCollaborators, invitations, meta)
496+
err = matchTeamCollaborators(repoName, teams, teamCollaborators, meta)
480497
if err != nil {
481498
return err
482499
}
483500

484-
err = matchTeamCollaborators(repoName, teams, teamCollaborators, meta)
501+
err = matchUserCollaboratorsAndInvites(repoName, users, userCollaborators, invitations, meta)
485502
if err != nil {
486503
return err
487504
}
@@ -509,6 +526,11 @@ func resourceGithubRepositoryCollaboratorsRead(d *schema.ResourceData, meta inte
509526
invitationIds[i.username] = strconv.FormatInt(i.invitationID, 10)
510527
}
511528

529+
teamIDs := make([]int64, len(teamCollaborators))
530+
for i, t := range teamCollaborators {
531+
teamIDs[i] = t.teamID
532+
}
533+
512534
err = d.Set("repository", repoName)
513535
if err != nil {
514536
return err
@@ -517,7 +539,7 @@ func resourceGithubRepositoryCollaboratorsRead(d *schema.ResourceData, meta inte
517539
if err != nil {
518540
return err
519541
}
520-
err = d.Set("team", flattenTeamCollaborators(teamCollaborators))
542+
err = d.Set("team", flattenTeamCollaborators(teamCollaborators, teamIDs))
521543
if err != nil {
522544
return err
523545
}

github/resource_github_repository_collaborators_test.go

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func TestAccGithubRepositoryCollaborators(t *testing.T) {
6464
}
6565
6666
resource "github_team" "test" {
67-
name = "%[1]s"
67+
name = "test"
6868
}
6969
7070
resource "github_repository_collaborators" "test_repo_collaborators" {
@@ -75,7 +75,7 @@ func TestAccGithubRepositoryCollaborators(t *testing.T) {
7575
permission = "admin"
7676
}
7777
team {
78-
team_id = github_team.test.slug
78+
team_id = github_team.test.id
7979
permission = "pull"
8080
}
8181
}
@@ -155,8 +155,8 @@ func TestAccGithubRepositoryCollaborators(t *testing.T) {
155155
if strings.HasPrefix(name, "user.") && strings.HasSuffix(name, ".permission") && val != "admin" {
156156
return fmt.Errorf("expected user.*.permission to be set to admin, was %s", val)
157157
}
158-
if strings.HasPrefix(name, "team.") && strings.HasSuffix(name, ".team_id") && val != teamAttrs["slug"] {
159-
return fmt.Errorf("expected team.*.team_id to be set to %s, was %s", teamAttrs["slug"], val)
158+
if strings.HasPrefix(name, "team.") && strings.HasSuffix(name, ".team_id") && val != teamAttrs["id"] {
159+
return fmt.Errorf("expected team.*.team_id to be set to %s, was %s", teamAttrs["id"], val)
160160
}
161161
if strings.HasPrefix(name, "team.") && strings.HasSuffix(name, ".permission") && val != "pull" {
162162
return fmt.Errorf("expected team.*.permission to be set to pull, was %s", val)
@@ -238,7 +238,11 @@ func TestAccGithubRepositoryCollaborators(t *testing.T) {
238238
}
239239
240240
resource "github_team" "test" {
241-
name = "%[1]s"
241+
name = "test"
242+
}
243+
244+
resource "github_team" "test2" {
245+
name = "test2"
242246
}
243247
244248
resource "github_repository_collaborators" "test_repo_collaborators" {
@@ -253,7 +257,11 @@ func TestAccGithubRepositoryCollaborators(t *testing.T) {
253257
permission = "admin"
254258
}
255259
team {
256-
team_id = github_team.test.slug
260+
team_id = github_team.test.id
261+
permission = "pull"
262+
}
263+
team {
264+
team_id = github_team.test2.id
257265
permission = "pull"
258266
}
259267
}
@@ -267,7 +275,11 @@ func TestAccGithubRepositoryCollaborators(t *testing.T) {
267275
}
268276
269277
resource "github_team" "test" {
270-
name = "%[1]s"
278+
name = "test"
279+
}
280+
281+
resource "github_team" "test2" {
282+
name = "test2"
271283
}
272284
273285
resource "github_repository_collaborators" "test_repo_collaborators" {
@@ -278,7 +290,7 @@ func TestAccGithubRepositoryCollaborators(t *testing.T) {
278290
permission = "push"
279291
}
280292
team {
281-
team_id = github_team.test.slug
293+
team_id = github_team.test.id
282294
permission = "push"
283295
}
284296
}
@@ -361,8 +373,8 @@ func TestAccGithubRepositoryCollaborators(t *testing.T) {
361373
if strings.HasPrefix(name, "user.") && strings.HasSuffix(name, ".permission") && val != "push" {
362374
return fmt.Errorf("expected user.*.permission to be set to push, was %s", val)
363375
}
364-
if strings.HasPrefix(name, "team.") && strings.HasSuffix(name, ".team_id") && val != teamAttrs["slug"] {
365-
return fmt.Errorf("expected team.*.team_id to be set to %s, was %s", teamAttrs["slug"], val)
376+
if strings.HasPrefix(name, "team.") && strings.HasSuffix(name, ".team_id") && val != teamAttrs["id"] {
377+
return fmt.Errorf("expected team.*.team_id to be set to %s, was %s", teamAttrs["id"], val)
366378
}
367379
if strings.HasPrefix(name, "team.") && strings.HasSuffix(name, ".permission") && val != "push" {
368380
return fmt.Errorf("expected team.*.permission to be set to push, was %s", val)
@@ -436,7 +448,7 @@ func TestAccGithubRepositoryCollaborators(t *testing.T) {
436448
}
437449
438450
resource "github_team" "test" {
439-
name = "%[1]s"
451+
name = "test"
440452
}
441453
442454
resource "github_repository_collaborators" "test_repo_collaborators" {
@@ -451,7 +463,7 @@ func TestAccGithubRepositoryCollaborators(t *testing.T) {
451463
permission = "admin"
452464
}
453465
team {
454-
team_id = github_team.test.slug
466+
team_id = github_team.test.id
455467
permission = "pull"
456468
}
457469
}
@@ -465,9 +477,9 @@ func TestAccGithubRepositoryCollaborators(t *testing.T) {
465477
}
466478
467479
resource "github_team" "test" {
468-
name = "%[1]s"
480+
name = "test"
469481
}
470-
`, repoName, inOrgUser)
482+
`, repoName)
471483

472484
testCase := func(t *testing.T, mode, config, configUpdate string, testCheck func(state *terraform.State) error) {
473485
resource.Test(t, resource.TestCase{

0 commit comments

Comments
 (0)