Skip to content
This repository was archived by the owner on Apr 15, 2026. It is now read-only.

Commit fc28628

Browse files
refactor: use go-github v81 SDK for enterprise teams
- Replace custom API implementations with go-github v81 SDK functions - Use EnterpriseService methods: CreateTeam, GetTeam, UpdateTeam, DeleteTeam, ListTeams, ListAssignments, AddMultipleAssignments, RemoveMultipleAssignments, GetTeamMembership, AddTeamMember, RemoveTeamMember - Change ID separator from '/' to ':' to reuse existing util.go functions - Move single-use helper functions to their respective files - Simplify util_enterprise_teams.go to only findEnterpriseTeamByID - Update test files to use testAccConf patterns
1 parent 90861ea commit fc28628

11 files changed

Lines changed: 287 additions & 647 deletions

github/data_source_github_enterprise_team.go

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"strconv"
77
"strings"
88

9+
"github.com/google/go-github/v81/github"
910
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1011
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1112
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
@@ -65,7 +66,7 @@ func dataSourceGithubEnterpriseTeamRead(ctx context.Context, d *schema.ResourceD
6566
client := meta.(*Owner).v3client
6667
enterpriseSlug := strings.TrimSpace(d.Get("enterprise_slug").(string))
6768

68-
var te *enterpriseTeam
69+
var te *github.EnterpriseTeam
6970
if v, ok := d.GetOk("team_id"); ok {
7071
teamID := int64(v.(int))
7172
if teamID != 0 {
@@ -85,14 +86,14 @@ func dataSourceGithubEnterpriseTeamRead(ctx context.Context, d *schema.ResourceD
8586
if teamSlug == "" {
8687
return diag.FromErr(fmt.Errorf("one of slug or team_id must be set"))
8788
}
88-
found, _, err := getEnterpriseTeamBySlug(ctx, client, enterpriseSlug, teamSlug)
89+
found, _, err := client.Enterprise.GetTeam(ctx, enterpriseSlug, teamSlug)
8990
if err != nil {
9091
return diag.FromErr(err)
9192
}
9293
te = found
9394
}
9495

95-
d.SetId(buildSlashTwoPartID(enterpriseSlug, strconv.FormatInt(te.ID, 10)))
96+
d.SetId(buildTwoPartID(enterpriseSlug, strconv.FormatInt(te.ID, 10)))
9697
if err := d.Set("enterprise_slug", enterpriseSlug); err != nil {
9798
return diag.FromErr(err)
9899
}
@@ -114,15 +115,18 @@ func dataSourceGithubEnterpriseTeamRead(ctx context.Context, d *schema.ResourceD
114115
return diag.FromErr(err)
115116
}
116117
}
117-
orgSel := te.OrganizationSelectionType
118+
orgSel := ""
119+
if te.OrganizationSelectionType != nil {
120+
orgSel = *te.OrganizationSelectionType
121+
}
118122
if orgSel == "" {
119123
orgSel = "disabled"
120124
}
121125
if err := d.Set("organization_selection_type", orgSel); err != nil {
122126
return diag.FromErr(err)
123127
}
124-
if te.GroupID != nil {
125-
if err := d.Set("group_id", *te.GroupID); err != nil {
128+
if te.GroupID != "" {
129+
if err := d.Set("group_id", te.GroupID); err != nil {
126130
return diag.FromErr(err)
127131
}
128132
} else {
@@ -133,3 +137,22 @@ func dataSourceGithubEnterpriseTeamRead(ctx context.Context, d *schema.ResourceD
133137

134138
return nil
135139
}
140+
141+
// findEnterpriseTeamBySlugOrID finds a team by slug. If the slug looks like a numeric ID,
142+
// it will search for a team with that ID. Otherwise, it uses GetTeam to fetch directly by slug.
143+
func findEnterpriseTeamBySlugOrID(ctx context.Context, client *github.Client, enterpriseSlug, teamSlugOrID string) (*github.EnterpriseTeam, error) {
144+
// First, try to get the team directly by slug
145+
team, resp, err := client.Enterprise.GetTeam(ctx, enterpriseSlug, teamSlugOrID)
146+
if err == nil {
147+
return team, nil
148+
}
149+
// If we got a 404, try searching by ID in case it's a numeric ID
150+
if resp != nil && resp.StatusCode == 404 {
151+
// Try to parse as int64 and search by ID
152+
var id int64
153+
if _, scanErr := fmt.Sscanf(teamSlugOrID, "%d", &id); scanErr == nil {
154+
return findEnterpriseTeamByID(ctx, client, enterpriseSlug, id)
155+
}
156+
}
157+
return nil, err
158+
}

github/data_source_github_enterprise_team_membership.go

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111

1212
func dataSourceGithubEnterpriseTeamMembership() *schema.Resource {
1313
return &schema.Resource{
14-
Description: "Manages membership in a GitHub enterprise team.",
14+
Description: "Gets information about a user's membership in a GitHub enterprise team.",
1515
ReadContext: dataSourceGithubEnterpriseTeamMembershipRead,
1616

1717
Schema: map[string]*schema.Schema{
@@ -30,23 +30,13 @@ func dataSourceGithubEnterpriseTeamMembership() *schema.Resource {
3030
"username": {
3131
Type: schema.TypeString,
3232
Required: true,
33-
Description: "The GitHub username.",
33+
Description: "The username of the user.",
3434
ValidateDiagFunc: validation.ToDiagFunc(validation.All(validation.StringIsNotWhiteSpace, validation.StringIsNotEmpty)),
3535
},
36-
"role": {
37-
Type: schema.TypeString,
36+
"user_id": {
37+
Type: schema.TypeInt,
3838
Computed: true,
39-
Description: "The role of the user in the enterprise team, if returned by the API.",
40-
},
41-
"state": {
42-
Type: schema.TypeString,
43-
Computed: true,
44-
Description: "The membership state, if returned by the API.",
45-
},
46-
"etag": {
47-
Type: schema.TypeString,
48-
Computed: true,
49-
Description: "ETag of the membership response.",
39+
Description: "The ID of the user.",
5040
},
5141
},
5242
}
@@ -57,12 +47,14 @@ func dataSourceGithubEnterpriseTeamMembershipRead(ctx context.Context, d *schema
5747
enterpriseSlug := strings.TrimSpace(d.Get("enterprise_slug").(string))
5848
enterpriseTeam := strings.TrimSpace(d.Get("enterprise_team").(string))
5949
username := strings.TrimSpace(d.Get("username").(string))
60-
m, resp, err := getEnterpriseTeamMembershipDetails(ctx, client, enterpriseSlug, enterpriseTeam, username)
50+
51+
// Get the membership using the SDK
52+
user, _, err := client.Enterprise.GetTeamMembership(ctx, enterpriseSlug, enterpriseTeam, username)
6153
if err != nil {
6254
return diag.FromErr(err)
6355
}
6456

65-
d.SetId(buildSlashThreePartID(enterpriseSlug, enterpriseTeam, username))
57+
d.SetId(buildThreePartID(enterpriseSlug, enterpriseTeam, username))
6658
if err := d.Set("enterprise_slug", enterpriseSlug); err != nil {
6759
return diag.FromErr(err)
6860
}
@@ -72,18 +64,11 @@ func dataSourceGithubEnterpriseTeamMembershipRead(ctx context.Context, d *schema
7264
if err := d.Set("username", username); err != nil {
7365
return diag.FromErr(err)
7466
}
75-
if m != nil {
76-
if err := d.Set("role", m.Role); err != nil {
77-
return diag.FromErr(err)
78-
}
79-
if err := d.Set("state", m.State); err != nil {
80-
return diag.FromErr(err)
81-
}
82-
}
83-
if resp != nil {
84-
if err := d.Set("etag", resp.Header.Get("ETag")); err != nil {
67+
if user != nil && user.ID != nil {
68+
if err := d.Set("user_id", int(*user.ID)); err != nil {
8569
return diag.FromErr(err)
8670
}
8771
}
72+
8873
return nil
8974
}

github/data_source_github_enterprise_team_organizations.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"strings"
66

7+
"github.com/google/go-github/v81/github"
78
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
89
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
910
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
@@ -42,19 +43,19 @@ func dataSourceGithubEnterpriseTeamOrganizationsRead(ctx context.Context, d *sch
4243
client := meta.(*Owner).v3client
4344
enterpriseSlug := strings.TrimSpace(d.Get("enterprise_slug").(string))
4445
enterpriseTeam := strings.TrimSpace(d.Get("enterprise_team").(string))
45-
orgs, err := listEnterpriseTeamOrganizations(ctx, client, enterpriseSlug, enterpriseTeam)
46+
orgs, err := listAllEnterpriseTeamOrganizations(ctx, client, enterpriseSlug, enterpriseTeam)
4647
if err != nil {
4748
return diag.FromErr(err)
4849
}
4950

5051
slugs := make([]string, 0, len(orgs))
5152
for _, org := range orgs {
52-
if org.Login != "" {
53-
slugs = append(slugs, org.Login)
53+
if org.Login != nil && *org.Login != "" {
54+
slugs = append(slugs, *org.Login)
5455
}
5556
}
5657

57-
d.SetId(buildSlashTwoPartID(enterpriseSlug, enterpriseTeam))
58+
d.SetId(buildTwoPartID(enterpriseSlug, enterpriseTeam))
5859
if err := d.Set("enterprise_slug", enterpriseSlug); err != nil {
5960
return diag.FromErr(err)
6061
}
@@ -66,3 +67,23 @@ func dataSourceGithubEnterpriseTeamOrganizationsRead(ctx context.Context, d *sch
6667
}
6768
return nil
6869
}
70+
71+
// listAllEnterpriseTeamOrganizations returns all organizations assigned to an enterprise team with pagination handled.
72+
func listAllEnterpriseTeamOrganizations(ctx context.Context, client *github.Client, enterpriseSlug, enterpriseTeam string) ([]*github.Organization, error) {
73+
var all []*github.Organization
74+
opt := &github.ListOptions{PerPage: maxPerPage}
75+
76+
for {
77+
orgs, resp, err := client.Enterprise.ListAssignments(ctx, enterpriseSlug, enterpriseTeam, opt)
78+
if err != nil {
79+
return nil, err
80+
}
81+
all = append(all, orgs...)
82+
if resp.NextPage == 0 {
83+
break
84+
}
85+
opt.Page = resp.NextPage
86+
}
87+
88+
return all, nil
89+
}

github/data_source_github_enterprise_team_test.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package github
22

33
import (
44
"fmt"
5-
"os"
65
"testing"
76

87
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
@@ -34,7 +33,7 @@ func TestAccGithubEnterpriseTeamDataSource(t *testing.T) {
3433
`, testAccConf.enterpriseSlug, randomID)
3534

3635
resource.Test(t, resource.TestCase{
37-
PreCheck: func() { skipUnlessMode(t, enterprise) },
36+
PreCheck: func() { skipUnlessMode(t, enterprise) },
3837
ProviderFactories: providerFactories,
3938
Steps: []resource.TestStep{
4039
{
@@ -81,7 +80,7 @@ func TestAccGithubEnterpriseTeamOrganizationsDataSource(t *testing.T) {
8180
`, testAccConf.enterpriseSlug, randomID, testAccConf.owner)
8281

8382
resource.Test(t, resource.TestCase{
84-
PreCheck: func() { skipUnlessMode(t, enterprise) },
83+
PreCheck: func() { skipUnlessMode(t, enterprise) },
8584
ProviderFactories: providerFactories,
8685
Steps: []resource.TestStep{
8786
{
@@ -98,11 +97,7 @@ func TestAccGithubEnterpriseTeamOrganizationsDataSource(t *testing.T) {
9897

9998
func TestAccGithubEnterpriseTeamMembershipDataSource(t *testing.T) {
10099
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
101-
username := os.Getenv("GITHUB_TEST_USER")
102-
103-
if username == "" {
104-
t.Skip("Skipping because `GITHUB_TEST_USER` is not set")
105-
}
100+
username := testAccConf.username
106101

107102
config := fmt.Sprintf(`
108103
data "github_enterprise" "enterprise" {
@@ -129,7 +124,7 @@ func TestAccGithubEnterpriseTeamMembershipDataSource(t *testing.T) {
129124
`, testAccConf.enterpriseSlug, randomID, username, username)
130125

131126
resource.Test(t, resource.TestCase{
132-
PreCheck: func() { skipUnlessMode(t, enterprise) },
127+
PreCheck: func() { skipUnlessMode(t, enterprise) },
133128
ProviderFactories: providerFactories,
134129
Steps: []resource.TestStep{
135130
{

github/data_source_github_enterprise_teams.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"strings"
66

7+
"github.com/google/go-github/v81/github"
78
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
89
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
910
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
@@ -67,7 +68,7 @@ func dataSourceGithubEnterpriseTeams() *schema.Resource {
6768
func dataSourceGithubEnterpriseTeamsRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
6869
client := meta.(*Owner).v3client
6970
enterpriseSlug := strings.TrimSpace(d.Get("enterprise_slug").(string))
70-
teams, err := listEnterpriseTeams(ctx, client, enterpriseSlug)
71+
teams, err := listAllEnterpriseTeams(ctx, client, enterpriseSlug)
7172
if err != nil {
7273
return diag.FromErr(err)
7374
}
@@ -84,13 +85,16 @@ func dataSourceGithubEnterpriseTeamsRead(ctx context.Context, d *schema.Resource
8485
} else {
8586
m["description"] = ""
8687
}
87-
orgSel := t.OrganizationSelectionType
88+
orgSel := ""
89+
if t.OrganizationSelectionType != nil {
90+
orgSel = *t.OrganizationSelectionType
91+
}
8892
if orgSel == "" {
8993
orgSel = "disabled"
9094
}
9195
m["organization_selection_type"] = orgSel
92-
if t.GroupID != nil {
93-
m["group_id"] = *t.GroupID
96+
if t.GroupID != "" {
97+
m["group_id"] = t.GroupID
9498
} else {
9599
m["group_id"] = ""
96100
}
@@ -106,3 +110,23 @@ func dataSourceGithubEnterpriseTeamsRead(ctx context.Context, d *schema.Resource
106110
}
107111
return nil
108112
}
113+
114+
// listAllEnterpriseTeams returns all enterprise teams with pagination handled.
115+
func listAllEnterpriseTeams(ctx context.Context, client *github.Client, enterpriseSlug string) ([]*github.EnterpriseTeam, error) {
116+
var all []*github.EnterpriseTeam
117+
opt := &github.ListOptions{PerPage: maxPerPage}
118+
119+
for {
120+
teams, resp, err := client.Enterprise.ListTeams(ctx, enterpriseSlug, opt)
121+
if err != nil {
122+
return nil, err
123+
}
124+
all = append(all, teams...)
125+
if resp.NextPage == 0 {
126+
break
127+
}
128+
opt.Page = resp.NextPage
129+
}
130+
131+
return all, nil
132+
}

github/data_source_github_enterprise_teams_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func TestAccGithubEnterpriseTeamsDataSource(t *testing.T) {
2828
`, testAccConf.enterpriseSlug, randomID)
2929

3030
resource.Test(t, resource.TestCase{
31-
PreCheck: func() { skipUnlessMode(t, enterprise) },
31+
PreCheck: func() { skipUnlessMode(t, enterprise) },
3232
ProviderFactories: providerFactories,
3333
Steps: []resource.TestStep{
3434
{

0 commit comments

Comments
 (0)