From ae4de2c25d18f8b0fcf04d86f3e5419b70880763 Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Wed, 7 Jan 2026 18:44:59 +0000 Subject: [PATCH] feat: Add team notification settings Signed-off-by: Steve Hipwell --- github/data_source_github_team.go | 81 +++---- github/data_source_github_team_test.go | 4 + github/resource_github_team.go | 280 +++++++++++++++---------- github/resource_github_team_test.go | 92 ++++---- website/docs/d/team.html.markdown | 23 +- website/docs/r/team.html.markdown | 12 +- 6 files changed, 290 insertions(+), 202 deletions(-) diff --git a/github/data_source_github_team.go b/github/data_source_github_team.go index 8d0576ca0c..f5f1b22af4 100644 --- a/github/data_source_github_team.go +++ b/github/data_source_github_team.go @@ -8,13 +8,14 @@ import ( "github.com/shurcooL/githubv4" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) func dataSourceGithubTeam() *schema.Resource { return &schema.Resource{ - Read: dataSourceGithubTeamRead, + ReadContext: dataSourceGithubTeamRead, Schema: map[string]*schema.Schema{ "slug": { @@ -33,10 +34,15 @@ func dataSourceGithubTeam() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "permission": { + "notification_setting": { Type: schema.TypeString, Computed: true, }, + "permission": { + Type: schema.TypeString, + Computed: true, + Deprecated: "Closing down notice.", + }, "members": { Type: schema.TypeList, Computed: true, @@ -88,30 +94,50 @@ func dataSourceGithubTeam() *schema.Resource { Optional: true, Default: 100, ValidateDiagFunc: toDiagFunc(validation.IntBetween(0, 100), "results_per_page"), + Deprecated: "This is deprecated and will be removed in a future release.", }, }, } } -func dataSourceGithubTeamRead(d *schema.ResourceData, meta any) error { - slug := d.Get("slug").(string) - +func dataSourceGithubTeamRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { client := meta.(*Owner).v3client - orgId := meta.(*Owner).id - ctx := context.Background() - summaryOnly := d.Get("summary_only").(bool) - resultsPerPage := d.Get("results_per_page").(int) + owner := meta.(*Owner).name + + slug := d.Get("slug").(string) team, _, err := client.Teams.GetTeamBySlug(ctx, meta.(*Owner).name, slug) if err != nil { - return err + return diag.FromErr(err) + } + + d.SetId(strconv.FormatInt(team.GetID(), 10)) + if err = d.Set("name", team.GetName()); err != nil { + return diag.FromErr(err) + } + if err = d.Set("description", team.GetDescription()); err != nil { + return diag.FromErr(err) + } + if err = d.Set("privacy", team.GetPrivacy()); err != nil { + return diag.FromErr(err) + } + if err = d.Set("notification_setting", team.GetNotificationSetting()); err != nil { + return diag.FromErr(err) + } + if err = d.Set("permission", team.GetPermission()); err != nil { + return diag.FromErr(err) + } + if err = d.Set("node_id", team.GetNodeID()); err != nil { + return diag.FromErr(err) } var members []string var repositories []string var repositories_detailed []any + summaryOnly := d.Get("summary_only").(bool) if !summaryOnly { + resultsPerPage := d.Get("results_per_page").(int) options := github.TeamListTeamMembersOptions{ ListOptions: github.ListOptions{ PerPage: resultsPerPage, @@ -120,9 +146,9 @@ func dataSourceGithubTeamRead(d *schema.ResourceData, meta any) error { if d.Get("membership_type").(string) == "all" { for { - member, resp, err := client.Teams.ListTeamMembersByID(ctx, orgId, team.GetID(), &options) + member, resp, err := client.Teams.ListTeamMembersBySlug(ctx, owner, team.GetSlug(), &options) if err != nil { - return err + return diag.FromErr(err) } for _, v := range member { @@ -160,7 +186,7 @@ func dataSourceGithubTeamRead(d *schema.ResourceData, meta any) error { for { nameErr := client.Query(ctx, &query, variables) if nameErr != nil { - return nameErr + return diag.FromErr(nameErr) } for _, v := range query.Organization.Team.Members.Nodes { members = append(members, v.Login) @@ -173,12 +199,11 @@ func dataSourceGithubTeamRead(d *schema.ResourceData, meta any) error { } } - repositories_detailed = make([]any, 0, resultsPerPage) // removed this from the loop - + repositories_detailed = make([]any, 0, resultsPerPage) for { - repository, resp, err := client.Teams.ListTeamReposByID(ctx, orgId, team.GetID(), &options.ListOptions) + repository, resp, err := client.Teams.ListTeamReposBySlug(ctx, owner, team.GetSlug(), &options.ListOptions) if err != nil { - return err + return diag.FromErr(err) } for _, v := range repository { @@ -197,30 +222,14 @@ func dataSourceGithubTeamRead(d *schema.ResourceData, meta any) error { } } - d.SetId(strconv.FormatInt(team.GetID(), 10)) - if err = d.Set("name", team.GetName()); err != nil { - return err - } if err = d.Set("members", members); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("repositories", repositories); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("repositories_detailed", repositories_detailed); err != nil { - return err - } - if err = d.Set("description", team.GetDescription()); err != nil { - return err - } - if err = d.Set("privacy", team.GetPrivacy()); err != nil { - return err - } - if err = d.Set("permission", team.GetPermission()); err != nil { - return err - } - if err = d.Set("node_id", team.GetNodeID()); err != nil { - return err + return diag.FromErr(err) } return nil diff --git a/github/data_source_github_team_test.go b/github/data_source_github_team_test.go index 9696431ae8..4c4c6326f5 100644 --- a/github/data_source_github_team_test.go +++ b/github/data_source_github_team_test.go @@ -25,6 +25,8 @@ func TestAccGithubTeamDataSource(t *testing.T) { check := resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrSet("data.github_team.test", "name"), resource.TestCheckResourceAttrSet("data.github_team.test", "node_id"), + resource.TestCheckResourceAttrSet("data.github_team.test", "privacy"), + resource.TestCheckResourceAttrSet("data.github_team.test", "notification_setting"), ) resource.Test(t, resource.TestCase{ @@ -104,6 +106,8 @@ func TestAccGithubTeamDataSource(t *testing.T) { check := resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrSet("data.github_team.test", "name"), resource.TestCheckResourceAttrSet("data.github_team.test", "node_id"), + resource.TestCheckResourceAttrSet("data.github_team.test", "privacy"), + resource.TestCheckResourceAttrSet("data.github_team.test", "notification_setting"), resource.TestCheckResourceAttr("data.github_team.test", "members.#", "0"), resource.TestCheckResourceAttr("data.github_team.test", "repositories.#", "0"), ) diff --git a/github/resource_github_team.go b/github/resource_github_team.go index 901431696b..5eb0d6f757 100644 --- a/github/resource_github_team.go +++ b/github/resource_github_team.go @@ -8,19 +8,19 @@ import ( "strconv" "github.com/google/go-github/v81/github" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/shurcooL/githubv4" ) func resourceGithubTeam() *schema.Resource { return &schema.Resource{ - Create: resourceGithubTeamCreate, - Read: resourceGithubTeamRead, - Update: resourceGithubTeamUpdate, - Delete: resourceGithubTeamDelete, + CreateContext: resourceGithubTeamCreate, + ReadContext: resourceGithubTeamRead, + UpdateContext: resourceGithubTeamUpdate, + DeleteContext: resourceGithubTeamDelete, Importer: &schema.ResourceImporter{ - State: resourceGithubTeamImport, + StateContext: resourceGithubTeamImport, }, CustomizeDiff: customdiff.Sequence( @@ -47,6 +47,13 @@ func resourceGithubTeam() *schema.Resource { Description: "The level of privacy for the team. Must be one of 'secret' or 'closed'.", ValidateDiagFunc: validateValueFunc([]string{"secret", "closed"}), }, + "notification_setting": { + Type: schema.TypeString, + Optional: true, + Default: "notifications_enabled", + Description: "The notification setting for the team. Must be one of 'notifications_enabled' or 'notifications_disabled'.", + ValidateDiagFunc: validateValueFunc([]string{"notifications_enabled", "notifications_disabled"}), + }, "parent_team_id": { Type: schema.TypeString, Optional: true, @@ -59,18 +66,6 @@ func resourceGithubTeam() *schema.Resource { return false }, }, - "parent_team_read_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The id of the parent team read in Github.", - }, - "parent_team_read_slug": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The id of the parent team read in Github.", - }, "ldap_dn": { Type: schema.TypeString, Optional: true, @@ -81,44 +76,58 @@ func resourceGithubTeam() *schema.Resource { Optional: true, Default: false, Description: "Adds a default maintainer to the team. Adds the creating user to the team when 'true'.", + Deprecated: "Use github_team_membership or github_team_members resource to manage team memberships explicitly.", }, "slug": { Type: schema.TypeString, Computed: true, Description: "The slug of the created team.", }, - "etag": { - Type: schema.TypeString, + "members_count": { + Type: schema.TypeInt, Computed: true, }, + "parent_team_read_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The id of the parent team read in Github.", + }, + "parent_team_read_slug": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The id of the parent team read in Github.", + }, "node_id": { Type: schema.TypeString, Computed: true, Description: "The Node ID of the created team.", }, - "members_count": { - Type: schema.TypeInt, + "etag": { + Type: schema.TypeString, Computed: true, }, }, } } -func resourceGithubTeamCreate(d *schema.ResourceData, meta any) error { +func resourceGithubTeamCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client - ownerName := meta.(*Owner).name + name := d.Get("name").(string) newTeam := github.NewTeam{ - Name: name, - Description: github.Ptr(d.Get("description").(string)), - Privacy: github.Ptr(d.Get("privacy").(string)), + Name: name, + Description: github.Ptr(d.Get("description").(string)), + Privacy: github.Ptr(d.Get("privacy").(string)), + NotificationSetting: github.Ptr(d.Get("notification_setting").(string)), } if ldapDN := d.Get("ldap_dn").(string); ldapDN != "" { @@ -128,18 +137,19 @@ func resourceGithubTeamCreate(d *schema.ResourceData, meta any) error { if parentTeamID, ok := d.GetOk("parent_team_id"); ok { teamId, err := getTeamID(parentTeamID.(string), meta) if err != nil { - return err + return diag.FromErr(err) } newTeam.ParentTeamID = &teamId } - ctx := context.Background() - githubTeam, _, err := client.Teams.CreateTeam(ctx, - ownerName, newTeam) + team, resp, err := client.Teams.CreateTeam(ctx, ownerName, newTeam) if err != nil { - return err + return diag.FromErr(err) } + slug := team.GetSlug() + membersCount := team.GetMembersCount() + /* When using a GitHub App for authentication, `members:write` permissions on the App are needed. @@ -153,33 +163,66 @@ func resourceGithubTeamCreate(d *schema.ResourceData, meta any) error { Note that this is best-effort: when running this with a PAT that does not have admin permissions on the parent team, the operation might still fail to set the parent team. */ - if newTeam.ParentTeamID != nil && githubTeam.Parent == nil { - _, _, err := client.Teams.EditTeamByID(ctx, - *githubTeam.Organization.ID, - *githubTeam.ID, - newTeam, - false) + if newTeam.ParentTeamID != nil && team.Parent == nil { + _, resp, err = client.Teams.EditTeamBySlug(ctx, ownerName, slug, newTeam, false) if err != nil { - return err + return diag.FromErr(err) } } create_default_maintainer := d.Get("create_default_maintainer").(bool) - if !create_default_maintainer { + if !create_default_maintainer && membersCount > 0 { log.Printf("[DEBUG] Removing default maintainer from team: %s (%s)", name, ownerName) - if err := removeDefaultMaintainer(*githubTeam.Slug, meta); err != nil { - return err + err := removeTeamMembers(ctx, client, ownerName, slug) + if err != nil { + return diag.FromErr(err) } + + membersCount = 0 } - d.SetId(strconv.FormatInt(githubTeam.GetID(), 10)) - return resourceGithubTeamRead(d, meta) + d.SetId(strconv.FormatInt(team.GetID(), 10)) + if err = d.Set("slug", team.GetSlug()); err != nil { + return diag.FromErr(err) + } + if err = d.Set("members_count", membersCount); err != nil { + return diag.FromErr(err) + } + if parent := team.Parent; parent != nil { + if err = d.Set("parent_team_id", strconv.FormatInt(team.Parent.GetID(), 10)); err != nil { + return diag.FromErr(err) + } + if err = d.Set("parent_team_read_id", strconv.FormatInt(team.Parent.GetID(), 10)); err != nil { + return diag.FromErr(err) + } + if err = d.Set("parent_team_read_slug", parent.Slug); err != nil { + return diag.FromErr(err) + } + } else { + if err = d.Set("parent_team_id", ""); err != nil { + return diag.FromErr(err) + } + if err = d.Set("parent_team_read_id", ""); err != nil { + return diag.FromErr(err) + } + if err = d.Set("parent_team_read_slug", ""); err != nil { + return diag.FromErr(err) + } + } + if err = d.Set("node_id", team.GetNodeID()); err != nil { + return diag.FromErr(err) + } + if err = d.Set("etag", resp.Header.Get("ETag")); err != nil { + return diag.FromErr(err) + } + + return nil } -func resourceGithubTeamRead(d *schema.ResourceData, meta any) error { +func resourceGithubTeamRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client @@ -187,9 +230,9 @@ func resourceGithubTeamRead(d *schema.ResourceData, meta any) error { id, err := strconv.ParseInt(d.Id(), 10, 64) if err != nil { - return unconvertibleIdErr(d.Id(), err) + return diag.FromErr(unconvertibleIdErr(d.Id(), err)) } - ctx := context.WithValue(context.Background(), ctxId, d.Id()) + if !d.IsNewResource() { ctx = context.WithValue(ctx, ctxEtag, d.Get("etag").(string)) } @@ -208,62 +251,65 @@ func resourceGithubTeamRead(d *schema.ResourceData, meta any) error { return nil } } - return err + return diag.FromErr(err) } - if err = d.Set("etag", resp.Header.Get("ETag")); err != nil { - return err + if err = d.Set("slug", team.GetSlug()); err != nil { + return diag.FromErr(err) } if err = d.Set("description", team.GetDescription()); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("name", team.GetName()); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("privacy", team.GetPrivacy()); err != nil { - return err + return diag.FromErr(err) + } + if err = d.Set("notification_setting", team.GetNotificationSetting()); err != nil { + return diag.FromErr(err) } if parent := team.Parent; parent != nil { if err = d.Set("parent_team_id", strconv.FormatInt(team.Parent.GetID(), 10)); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("parent_team_read_id", strconv.FormatInt(team.Parent.GetID(), 10)); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("parent_team_read_slug", parent.Slug); err != nil { - return err + return diag.FromErr(err) } } else { if err = d.Set("parent_team_id", ""); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("parent_team_read_id", ""); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("parent_team_read_slug", ""); err != nil { - return err + return diag.FromErr(err) } } if err = d.Set("ldap_dn", team.GetLDAPDN()); err != nil { - return err + return diag.FromErr(err) } - if err = d.Set("slug", team.GetSlug()); err != nil { - return err + if err = d.Set("members_count", team.GetMembersCount()); err != nil { + return diag.FromErr(err) } if err = d.Set("node_id", team.GetNodeID()); err != nil { - return err + return diag.FromErr(err) } - if err = d.Set("members_count", team.GetMembersCount()); err != nil { - return err + if err = d.Set("etag", resp.Header.Get("ETag")); err != nil { + return diag.FromErr(err) } return nil } -func resourceGithubTeamUpdate(d *schema.ResourceData, meta any) error { +func resourceGithubTeamUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client @@ -271,14 +317,15 @@ func resourceGithubTeamUpdate(d *schema.ResourceData, meta any) error { var removeParentTeam bool editedTeam := github.NewTeam{ - Name: d.Get("name").(string), - Description: github.Ptr(d.Get("description").(string)), - Privacy: github.Ptr(d.Get("privacy").(string)), + Name: d.Get("name").(string), + Description: github.Ptr(d.Get("description").(string)), + Privacy: github.Ptr(d.Get("privacy").(string)), + NotificationSetting: github.Ptr(d.Get("notification_setting").(string)), } if parentTeamID, ok := d.GetOk("parent_team_id"); ok { teamId, err := getTeamID(parentTeamID.(string), meta) if err != nil { - return err + return diag.FromErr(err) } editedTeam.ParentTeamID = &teamId removeParentTeam = false @@ -288,13 +335,12 @@ func resourceGithubTeamUpdate(d *schema.ResourceData, meta any) error { teamId, err := strconv.ParseInt(d.Id(), 10, 64) if err != nil { - return unconvertibleIdErr(d.Id(), err) + return diag.FromErr(unconvertibleIdErr(d.Id(), err)) } - ctx := context.WithValue(context.Background(), ctxId, d.Id()) - team, _, err := client.Teams.EditTeamByID(ctx, orgId, teamId, editedTeam, removeParentTeam) + team, resp, err := client.Teams.EditTeamByID(ctx, orgId, teamId, editedTeam, removeParentTeam) if err != nil { - return err + return diag.FromErr(err) } if d.HasChange("ldap_dn") { @@ -304,18 +350,52 @@ func resourceGithubTeamUpdate(d *schema.ResourceData, meta any) error { } _, _, err = client.Admin.UpdateTeamLDAPMapping(ctx, team.GetID(), mapping) if err != nil { - return err + return diag.FromErr(err) } } d.SetId(strconv.FormatInt(team.GetID(), 10)) - return resourceGithubTeamRead(d, meta) + if err = d.Set("slug", team.GetSlug()); err != nil { + return diag.FromErr(err) + } + if err = d.Set("members_count", team.GetMembersCount()); err != nil { + return diag.FromErr(err) + } + if parent := team.Parent; parent != nil { + if err = d.Set("parent_team_id", strconv.FormatInt(team.Parent.GetID(), 10)); err != nil { + return diag.FromErr(err) + } + if err = d.Set("parent_team_read_id", strconv.FormatInt(team.Parent.GetID(), 10)); err != nil { + return diag.FromErr(err) + } + if err = d.Set("parent_team_read_slug", parent.Slug); err != nil { + return diag.FromErr(err) + } + } else { + if err = d.Set("parent_team_id", ""); err != nil { + return diag.FromErr(err) + } + if err = d.Set("parent_team_read_id", ""); err != nil { + return diag.FromErr(err) + } + if err = d.Set("parent_team_read_slug", ""); err != nil { + return diag.FromErr(err) + } + } + if err = d.Set("node_id", team.GetNodeID()); err != nil { + return diag.FromErr(err) + } + if err = d.Set("etag", resp.Header.Get("ETag")); err != nil { + return diag.FromErr(err) + } + + return nil } -func resourceGithubTeamDelete(d *schema.ResourceData, meta any) error { +func resourceGithubTeamDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { err := checkOrganization(meta) if err != nil { - return err + return diag.FromErr(err) } client := meta.(*Owner).v3client @@ -323,9 +403,8 @@ func resourceGithubTeamDelete(d *schema.ResourceData, meta any) error { id, err := strconv.ParseInt(d.Id(), 10, 64) if err != nil { - return unconvertibleIdErr(d.Id(), err) + return diag.FromErr(unconvertibleIdErr(d.Id(), err)) } - ctx := context.WithValue(context.Background(), ctxId, d.Id()) _, err = client.Teams.DeleteTeamByID(ctx, orgId, id) /* @@ -349,12 +428,13 @@ func resourceGithubTeamDelete(d *schema.ResourceData, meta any) error { return nil } } + return diag.FromErr(err) } } - return err + return nil } -func resourceGithubTeamImport(d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) { +func resourceGithubTeamImport(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) { teamId, err := getTeamID(d.Id(), meta) if err != nil { return nil, err @@ -368,36 +448,14 @@ func resourceGithubTeamImport(d *schema.ResourceData, meta any) ([]*schema.Resou return []*schema.ResourceData{d}, nil } -func removeDefaultMaintainer(teamSlug string, meta any) error { - client := meta.(*Owner).v3client - orgName := meta.(*Owner).name - v4client := meta.(*Owner).v4client - - type User struct { - Login githubv4.String - } - - var query struct { - Organization struct { - Team struct { - Members struct { - Nodes []User - } - } `graphql:"team(slug:$slug)"` - } `graphql:"organization(login:$login)"` - } - variables := map[string]any{ - "slug": githubv4.String(teamSlug), - "login": githubv4.String(orgName), - } - - err := v4client.Query(meta.(*Owner).StopContext, &query, variables) +func removeTeamMembers(ctx context.Context, client *github.Client, owner, slug string) error { + users, _, err := client.Teams.ListTeamMembersBySlug(ctx, owner, slug, &github.TeamListTeamMembersOptions{}) if err != nil { return err } - for _, user := range query.Organization.Team.Members.Nodes { - _, err := client.Teams.RemoveTeamMembershipBySlug(meta.(*Owner).StopContext, orgName, teamSlug, string(user.Login)) + for _, user := range users { + _, err := client.Teams.RemoveTeamMembershipBySlug(ctx, owner, slug, user.GetLogin()) if err != nil { return err } diff --git a/github/resource_github_team_test.go b/github/resource_github_team_test.go index 1bf8c62baa..19e41faaef 100644 --- a/github/resource_github_team_test.go +++ b/github/resource_github_team_test.go @@ -12,14 +12,36 @@ func TestAccGithubTeam(t *testing.T) { t.Run("creates a team configured with defaults", func(t *testing.T) { randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) config := fmt.Sprintf(` - resource "github_team" "test" { - name = "tf-acc-%s" - } - `, randomID) +resource "github_team" "test" { + name = "tf-acc-%s" +} +`, randomID) - check := resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet("github_team.test", "slug"), - ) + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("github_team.test", "slug"), + resource.TestCheckResourceAttr("github_team.test", "privacy", "secret"), + resource.TestCheckResourceAttr("github_team.test", "notification_setting", "notifications_enabled"), + ), + }, + }, + }) + }) + + t.Run("creates a team configured with alternatives", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + config := fmt.Sprintf(` +resource "github_team" "test" { + name = "tf-acc-%s" + privacy = "closed" + notification_setting = "notifications_disabled" +} +`, randomID) resource.Test(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, @@ -27,7 +49,11 @@ func TestAccGithubTeam(t *testing.T) { Steps: []resource.TestStep{ { Config: config, - Check: check, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("github_team.test", "slug"), + resource.TestCheckResourceAttr("github_team.test", "privacy", "closed"), + resource.TestCheckResourceAttr("github_team.test", "notification_setting", "notifications_disabled"), + ), }, }, }) @@ -110,15 +136,11 @@ func TestAccGithubTeam(t *testing.T) { t.Run("creates a team and removes the default maintainer", func(t *testing.T) { randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) config := fmt.Sprintf(` - resource "github_team" "test" { - name = "tf-acc-%s" - create_default_maintainer = false - } - `, randomID) - - check := resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("github_team.test", "members_count", "0"), - ) +resource "github_team" "test" { + name = "tf-acc-%s" + create_default_maintainer = false +} +`, randomID) resource.Test(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, @@ -126,45 +148,39 @@ func TestAccGithubTeam(t *testing.T) { Steps: []resource.TestStep{ { Config: config, - Check: check, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("github_team.test", "members_count", "0"), + ), }, }, }) }) - t.Run("marks the slug as computed when the name changes", func(t *testing.T) { + t.Run("updates_slug", func(t *testing.T) { randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) - config := fmt.Sprintf(` - resource "github_team" "test" { - name = "tf-acc-%s" - } - `, randomID) + slug := fmt.Sprintf("tf-acc-%s", randomID) + slugUpdated := fmt.Sprintf("tf-acc-updated-%s", randomID) - configUpdated := fmt.Sprintf(` - resource "github_team" "test" { - name = "tf-acc-updated-%s" - } - - resource "github_team" "other" { - name = "tf-acc-other-%s" - description = github_team.test.slug - } - `, randomID, randomID) + config := ` +resource "github_team" "test" { + name = "%s" +} +` resource.Test(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, Steps: []resource.TestStep{ { - Config: config, + Config: fmt.Sprintf(config, slug), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("github_team.test", "slug", fmt.Sprintf("tf-acc-%s", randomID)), + resource.TestCheckResourceAttr("github_team.test", "slug", slug), ), }, { - Config: configUpdated, + Config: fmt.Sprintf(config, slugUpdated), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("github_team.other", "description", fmt.Sprintf("tf-acc-updated-%s", randomID)), + resource.TestCheckResourceAttr("github_team.test", "slug", slugUpdated), ), }, }, diff --git a/website/docs/d/team.html.markdown b/website/docs/d/team.html.markdown index fdfca6f9dc..f8fdde4de5 100644 --- a/website/docs/d/team.html.markdown +++ b/website/docs/d/team.html.markdown @@ -20,18 +20,19 @@ data "github_team" "example" { ## Argument Reference * `slug` - (Required) The team slug. -* `membership_type` - (Optional) Type of membership to be requested to fill the list of members. Can be either "all" or "immediate". Default: "all" +* `membership_type` - (Optional) Type of membership to be requested to fill the list of members. Can be either `all` _(default)_ or `immediate`. * `summary_only` - (Optional) Exclude the members and repositories of the team from the returned result. Defaults to `false`. -* `results_per_page` - (Optional) Set the number of results per graphql query. Reducing this number can alleviate timeout errors. Accepts a value between 0 - 100. Defaults to `100`. +* `results_per_page` - (**DEPRECATED**) (Optional) Set the number of results per REST API query. Accepts a value between 0 - 100 _(defaults to `100`)_. ## Attributes Reference -* `id` - the ID of the team. -* `node_id` - the Node ID of the team. -* `name` - the team's full name. -* `description` - the team's description. -* `privacy` - the team's privacy type. -* `permission` - the team's permission level. -* `members` - List of team members (list of GitHub usernames). Not returned if `summary_only = true` -* `repositories` - (**DEPRECATED**) List of team repositories (list of repo names). Not returned if `summary_only = true` -* `repositories_detailed` - List of team repositories (each item comprises of `repo_id`, `repo_name` & [`role_name`](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team_repository#permission)). Not returned if `summary_only = true` +* `id` - ID of the team. +* `node_id` - Node ID of the team. +* `name` - Team's full name. +* `description` - Team's description. +* `privacy` - Team's privacy type. Can either be `closed` or `secret`. +* `notification_setting` - Teams's notification setting. Can be either `notifications_enabled` or `notifications_disabled`. +* `permission` - (**DEPRECATED**) The permission that new repositories will be added to the team with when none is specified. +* `members` - List of team members (list of GitHub usernames). Not returned if `summary_only = true`. +* `repositories` - (**DEPRECATED**) List of team repositories (list of repo names). Not returned if `summary_only = true`. +* `repositories_detailed` - List of team repositories (each item comprises of `repo_id`, `repo_name` & [`role_name`](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team_repository#permission)). Not returned if `summary_only = true`. diff --git a/website/docs/r/team.html.markdown b/website/docs/r/team.html.markdown index 491467f7f0..baa295ee56 100644 --- a/website/docs/r/team.html.markdown +++ b/website/docs/r/team.html.markdown @@ -29,11 +29,11 @@ The following arguments are supported: * `name` - (Required) The name of the team. * `description` - (Optional) A description of the team. -* `privacy` - (Optional) The level of privacy for the team. Must be one of `secret` or `closed`. - Defaults to `secret`. +* `privacy` - (Optional) The level of privacy for the team. Must be one of `secret` _(default)_ or `closed`. +* `notification_setting` - (Optional) The notification setting for the team. Must be one of `notifications_enabled` _(default)_ or `notifications_disabled`. * `parent_team_id` - (Optional) The ID or slug of the parent team, if this is a nested team. * `ldap_dn` - (Optional) The LDAP Distinguished Name of the group where membership will be synchronized. Only available in GitHub Enterprise Server. -* `create_default_maintainer` - (Optional) Adds a default maintainer to the team. Defaults to `false` and adds the creating user to the team when `true`. +* `create_default_maintainer` - (**DEPRECATED**) (Optional) Adds a default maintainer to the team. Defaults to `false` and adds the creating user to the team when `true`. ## Attributes Reference @@ -49,7 +49,7 @@ The following attributes are exported: GitHub Teams can be imported using the GitHub team ID or name e.g. -``` -$ terraform import github_team.core 1234567 -$ terraform import github_team.core Administrators +```shell +terraform import github_team.core 1234567 +terraform import github_team.core Administrators ```