44 "context"
55 "fmt"
66 "log"
7+ "slices"
78 "sort"
89 "strconv"
910
@@ -136,37 +137,46 @@ func flattenUserCollaborators(objs []userCollaborator, invites []invitedCollabor
136137
137138type teamCollaborator struct {
138139 permission string
140+ teamID int64
139141 teamSlug string
140142}
141143
142144func (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(
376386func 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 }
0 commit comments