From 269d3455eb910bc240f7715535b238db065b6020 Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Sun, 22 Feb 2026 21:31:21 +0200 Subject: [PATCH 01/15] Update docs Signed-off-by: Timo Sand --- website/docs/r/team_settings.html.markdown | 28 ++++++++++++++-------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/website/docs/r/team_settings.html.markdown b/website/docs/r/team_settings.html.markdown index 318062904e..11dd23cdfb 100644 --- a/website/docs/r/team_settings.html.markdown +++ b/website/docs/r/team_settings.html.markdown @@ -11,7 +11,7 @@ This resource manages the team settings (in particular the request review delega Creating this resource will alter the team Code Review settings. -The team must both belong to the same organization configured in the provider on GitHub. +The team must both belong to the same organization configured in the provider on GitHub. ~> **Note**: This resource relies on the v4 GraphQl GitHub API. If this API is not available, or the Stone Crop schema preview is not available, then this resource will not work as intended. @@ -38,26 +38,34 @@ resource "github_team_settings" "code_review_settings" { The following arguments are supported: -* `team_id` - (Required) The GitHub team id or the GitHub team slug -* `review_request_delegation` - (Optional) The settings for delegating code reviews to individuals on behalf of the team. If this block is present, even without any fields, then review request delegation will be enabled for the team. See [GitHub Review Request Delegation](#github-review-request-delegation-configuration) below for details. See [GitHub's documentation](https://docs.github.com/en/organizations/organizing-members-into-teams/managing-code-review-settings-for-your-team#configuring-team-notifications) for more configuration details. +- `team_id` - (Required) The GitHub team id or the GitHub team slug +- `review_request_delegation` - (Optional) The settings for delegating code reviews to individuals on behalf of the team. If this block is present, even without any fields, then review request delegation will be enabled for the team. See [GitHub Review Request Delegation](#github-review-request-delegation-configuration) below for details. See [GitHub's documentation](https://docs.github.com/en/organizations/organizing-members-into-teams/managing-code-review-settings-for-your-team#configuring-team-notifications) for more configuration details. ### GitHub Review Request Delegation Configuration The following arguments are supported: -* `algorithm` - (Optional) The algorithm to use when assigning pull requests to team members. Supported values are `ROUND_ROBIN` and `LOAD_BALANCE`. Default value is `ROUND_ROBIN` -* `member_count` - (Optional) The number of team members to assign to a pull request -* `notify` - (Optional) whether to notify the entire team when at least one member is also assigned to the pull request +- `algorithm` - (Optional) The algorithm to use when assigning pull requests to team members. Supported values are `ROUND_ROBIN` and `LOAD_BALANCE`. Default value is `ROUND_ROBIN` +- `member_count` - (Optional) The number of team members to assign to a pull request +- `notify` - (Optional) whether to notify the entire team when at least one member is also assigned to the pull request +## Attributes Reference + +The following additional attributes are exported: + +- `team_slug` - The slug of the Team. +- `team_uid` - The unique node ID of the Team on GitHub. Corresponds to the ID of the `github_team_settings` resource. ## Import GitHub Teams can be imported using the GitHub team ID, or the team slug e.g. +```text +terraform import github_team_settings.code_review_settings 1234567 ``` -$ terraform import github_team.code_review_settings 1234567 -``` + or, + +```text +terraform import github_team_settings.code_review_settings SomeTeam ``` -$ terraform import github_team_settings.code_review_settings SomeTeam -``` \ No newline at end of file From 03e79195f0337231e12fdb3c93bf1531d77a7582 Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Mon, 23 Feb 2026 10:11:10 +0200 Subject: [PATCH 02/15] Update tests and add missing coverage Signed-off-by: Timo Sand --- github/resource_github_team_settings_test.go | 220 +++++++++++++++++-- 1 file changed, 202 insertions(+), 18 deletions(-) diff --git a/github/resource_github_team_settings_test.go b/github/resource_github_team_settings_test.go index fb3276b198..1548a8e893 100644 --- a/github/resource_github_team_settings_test.go +++ b/github/resource_github_team_settings_test.go @@ -1,6 +1,7 @@ package github import ( + "context" "fmt" "regexp" "strings" @@ -8,6 +9,10 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" "github.com/shurcooL/githubv4" ) @@ -29,20 +34,27 @@ func TestAccGithubTeamSettings(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, Steps: []resource.TestStep{ { Config: config, - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet("github_team_settings.test", "team_id"), - ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("team_id"), knownvalue.NotNull()), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("team_slug"), knownvalue.NotNull()), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("team_uid"), knownvalue.NotNull()), + }, }, { Config: strings.Replace(config, `github_team.test.id`, `github_team.test.slug`, 1), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet("github_team_settings.test", "team_id"), - ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("team_id"), knownvalue.NotNull()), + }, }, }, }) @@ -71,30 +83,39 @@ func TestAccGithubTeamSettings(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, Steps: []resource.TestStep{ { Config: fmt.Sprintf(config, teamName, testAlgorithm, 1, true), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("github_team_settings.test", "review_request_delegation.0.algorithm", string(testAlgorithm)), - ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("algorithm"), + knownvalue.StringExact(string(testAlgorithm))), + }, }, { Config: fmt.Sprintf(config, teamName, githubv4.TeamReviewAssignmentAlgorithmLoadBalance, 1, true), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("github_team_settings.test", "review_request_delegation.0.algorithm", string(githubv4.TeamReviewAssignmentAlgorithmLoadBalance)), - ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("algorithm"), + knownvalue.StringExact(string(githubv4.TeamReviewAssignmentAlgorithmLoadBalance))), + }, }, { Config: fmt.Sprintf(config, teamName, testAlgorithm, 3, true), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("github_team_settings.test", "review_request_delegation.0.member_count", "3"), - ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("member_count"), + knownvalue.Int64Exact(3)), + }, }, { Config: fmt.Sprintf(config, teamName, testAlgorithm, 3, false), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("github_team_settings.test", "review_request_delegation.0.notify", "false"), - ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("notify"), + knownvalue.Bool(false)), + }, }, }, }) @@ -122,6 +143,7 @@ func TestAccGithubTeamSettings(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, Steps: []resource.TestStep{ { Config: config, @@ -130,4 +152,166 @@ func TestAccGithubTeamSettings(t *testing.T) { }, }) }) + + t.Run("manages removing review request delegation", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) + + configWithDelegation := fmt.Sprintf(` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = "${github_team.test.id}" + review_request_delegation { + algorithm = "ROUND_ROBIN" + member_count = 1 + notify = true + } + } + `, teamName) + + configWithoutDelegation := fmt.Sprintf(` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = "${github_team.test.id}" + } + `, teamName) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, + Steps: []resource.TestStep{ + { + Config: configWithDelegation, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("algorithm"), + knownvalue.StringExact("ROUND_ROBIN")), + }, + }, + { + Config: configWithoutDelegation, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation"), + knownvalue.ListExact([]knownvalue.Check{})), + }, + }, + { + Config: configWithDelegation, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("algorithm"), + knownvalue.StringExact("ROUND_ROBIN")), + }, + }, + }, + }) + }) + + t.Run("creates_with_empty_review_request_delegation_block_without_error", func(t *testing.T) { + t.Skip("TODO this isn't working as expected") + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) + config := fmt.Sprintf(` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = "${github_team.test.id}" + review_request_delegation {} + } + `, teamName) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("algorithm"), knownvalue.StringExact(string(githubv4.TeamReviewAssignmentAlgorithmRoundRobin))), + statecheck.ExpectKnownValue("github_team_settings.test", tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("notify"), knownvalue.Bool(false)), + }, + }, + }, + }) + }) + t.Run("validates_member_count_greater_than_0", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) + config := fmt.Sprintf(` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = "${github_team.test.id}" + review_request_delegation { + member_count = 0 + } + } + `, teamName) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ExpectError: regexp.MustCompile(`expected member_count to be at least (1), got 0`), + }, + }, + }) + }) +} + +func testAccCheckGithubTeamSettingsDestroy(s *terraform.State) error { + meta, err := getTestMeta() + if err != nil { + return err + } + graphql := meta.v4client + orgName := meta.name + + for _, rs := range s.RootModule().Resources { + if rs.Type != "github_team_settings" { + continue + } + + teamSlug := rs.Primary.Attributes["team_slug"] + if teamSlug == "" { + continue + } + + query := queryTeamSettings{} + variables := map[string]any{ + "slug": githubv4.String(teamSlug), + "login": githubv4.String(orgName), + } + + err := graphql.Query(context.Background(), &query, variables) + if err != nil { + // Team itself may have been destroyed, which is fine + continue + } + + if query.Organization.Team.ReviewRequestDelegation { + return fmt.Errorf("team %s still has review request delegation enabled", teamSlug) + } + } + return nil } From b3470098ab56c31448a93c13533c8cc3390378cc Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Mon, 23 Feb 2026 11:58:29 +0200 Subject: [PATCH 03/15] Add more tests to cover `Import` and a few more `Update` cases Signed-off-by: Timo Sand --- github/resource_github_team_settings_test.go | 260 ++++++++++++++++++- 1 file changed, 259 insertions(+), 1 deletion(-) diff --git a/github/resource_github_team_settings_test.go b/github/resource_github_team_settings_test.go index 1548a8e893..86f511eee7 100644 --- a/github/resource_github_team_settings_test.go +++ b/github/resource_github_team_settings_test.go @@ -7,6 +7,7 @@ import ( "strings" "testing" + "github.com/hashicorp/terraform-plugin-testing/compare" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/knownvalue" @@ -272,7 +273,264 @@ func TestAccGithubTeamSettings(t *testing.T) { Steps: []resource.TestStep{ { Config: config, - ExpectError: regexp.MustCompile(`expected member_count to be at least (1), got 0`), + ExpectError: regexp.MustCompile(`expected member_count to be at least \(1\), got 0`), + }, + }, + }) + }) + + t.Run("imports_team_settings_without_delegation_using_team_id", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) + + config := fmt.Sprintf(` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = "${github_team.test.id}" + } + `, teamName) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.CompareValuePairs("github_team_settings.test", tfjsonpath.New("team_id"), "github_team.test", tfjsonpath.New("id"), compare.ValuesSame()), + }, + }, + { + ResourceName: "github_team_settings.test", + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources["github_team.test"] + if !ok { + return "", fmt.Errorf("not found: github_team.test") + } + return rs.Primary.ID, nil + }, + }, + }, + }) + }) + t.Run("imports_team_settings_without_delegation_using_team_slug", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) + + config := fmt.Sprintf(` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = github_team.test.slug + } + `, teamName) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.CompareValuePairs("github_team_settings.test", tfjsonpath.New("team_id"), "github_team.test", tfjsonpath.New("slug"), compare.ValuesSame()), + }, + }, + { + ResourceName: "github_team_settings.test", + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources["github_team.test"] + if !ok { + return "", fmt.Errorf("not found: github_team.test") + } + return rs.Primary.Attributes["slug"], nil + }, + }, + }, + }) + }) + + t.Run("imports team settings with delegation", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) + + config := fmt.Sprintf(` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = github_team.test.id + review_request_delegation { + algorithm = "ROUND_ROBIN" + member_count = 2 + notify = true + } + } + `, teamName) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("algorithm"), + knownvalue.StringExact("ROUND_ROBIN")), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("member_count"), + knownvalue.Int64Exact(2)), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("notify"), + knownvalue.Bool(true)), + }, + }, + { + ResourceName: "github_team_settings.test", + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources["github_team.test"] + if !ok { + return "", fmt.Errorf("not found: github_team.test") + } + return rs.Primary.Attributes["id"], nil + }, + }, + }, + }) + }) + + t.Run("manages adding review request delegation to existing team settings", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) + + configWithoutDelegation := fmt.Sprintf(` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = "${github_team.test.id}" + } + `, teamName) + + configWithDelegation := fmt.Sprintf(` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = "${github_team.test.id}" + review_request_delegation { + algorithm = "LOAD_BALANCE" + member_count = 2 + notify = true + } + } + `, teamName) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, + Steps: []resource.TestStep{ + { + Config: configWithoutDelegation, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation"), + knownvalue.ListExact([]knownvalue.Check{})), + }, + }, + { + Config: configWithDelegation, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("algorithm"), + knownvalue.StringExact("LOAD_BALANCE")), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("member_count"), + knownvalue.Int64Exact(2)), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("notify"), + knownvalue.Bool(true)), + }, + }, + }, + }) + }) + + t.Run("manages updating only notify field", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) + + config := ` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = "${github_team.test.id}" + review_request_delegation { + algorithm = "ROUND_ROBIN" + member_count = 1 + notify = %t + } + } + ` + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(config, teamName, true), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("notify"), + knownvalue.Bool(true)), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("algorithm"), + knownvalue.StringExact("ROUND_ROBIN")), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("member_count"), + knownvalue.Int64Exact(1)), + }, + }, + { + Config: fmt.Sprintf(config, teamName, false), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("notify"), + knownvalue.Bool(false)), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("algorithm"), + knownvalue.StringExact("ROUND_ROBIN")), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("member_count"), + knownvalue.Int64Exact(1)), + }, }, }, }) From be34688667e16f5108a5abb7e2749257ef12c0a4 Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Mon, 23 Feb 2026 12:03:18 +0200 Subject: [PATCH 04/15] Refactor `Import` to be Context-aware Signed-off-by: Timo Sand --- github/resource_github_team_settings.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/github/resource_github_team_settings.go b/github/resource_github_team_settings.go index 505b45053e..e2a71c1590 100644 --- a/github/resource_github_team_settings.go +++ b/github/resource_github_team_settings.go @@ -17,7 +17,7 @@ func resourceGithubTeamSettings() *schema.Resource { Update: resourceGithubTeamSettingsUpdate, Delete: resourceGithubTeamSettingsDelete, Importer: &schema.ResourceImporter{ - State: resourceGithubTeamSettingsImport, + StateContext: resourceGithubTeamSettingsImport, }, Schema: map[string]*schema.Schema{ "team_id": { @@ -186,8 +186,8 @@ func resourceGithubTeamSettingsDelete(d *schema.ResourceData, meta any) error { return graphql.Mutate(ctx, &mutation, defaultTeamReviewAssignmentSettings(d.Id()), nil) } -func resourceGithubTeamSettingsImport(d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) { - nodeId, slug, err := resolveTeamIDs(d.Id(), meta.(*Owner), context.Background()) +func resourceGithubTeamSettingsImport(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) { + nodeId, slug, err := resolveTeamIDs(d.Id(), meta.(*Owner), ctx) if err != nil { return nil, err } @@ -201,7 +201,7 @@ func resourceGithubTeamSettingsImport(d *schema.ResourceData, meta any) ([]*sche if err = d.Set("team_uid", nodeId); err != nil { return nil, err } - return []*schema.ResourceData{d}, resourceGithubTeamSettingsRead(d, meta) + return []*schema.ResourceData{d}, nil } func resolveTeamIDs(idOrSlug string, meta *Owner, ctx context.Context) (nodeId, slug string, err error) { From 37fbbfb6d8ce68225878b16cdf467a71e51d1e01 Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Mon, 23 Feb 2026 12:17:38 +0200 Subject: [PATCH 05/15] Refactor to use Context-aware functions Signed-off-by: Timo Sand --- github/resource_github_team_settings.go | 77 ++++++++++++++----------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/github/resource_github_team_settings.go b/github/resource_github_team_settings.go index e2a71c1590..235fdf9ecb 100644 --- a/github/resource_github_team_settings.go +++ b/github/resource_github_team_settings.go @@ -5,6 +5,7 @@ import ( "errors" "strconv" + "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" "github.com/shurcooL/githubv4" @@ -12,10 +13,10 @@ import ( func resourceGithubTeamSettings() *schema.Resource { return &schema.Resource{ - Create: resourceGithubTeamSettingsCreate, - Read: resourceGithubTeamSettingsRead, - Update: resourceGithubTeamSettingsUpdate, - Delete: resourceGithubTeamSettingsDelete, + CreateContext: resourceGithubTeamSettingsCreate, + ReadContext: resourceGithubTeamSettingsRead, + UpdateContext: resourceGithubTeamSettingsUpdate, + DeleteContext: resourceGithubTeamSettingsDelete, Importer: &schema.ResourceImporter{ StateContext: resourceGithubTeamSettingsImport, }, @@ -72,36 +73,32 @@ func resourceGithubTeamSettings() *schema.Resource { } } -func resourceGithubTeamSettingsCreate(d *schema.ResourceData, meta any) error { - err := checkOrganization(meta) - if err != nil { - return err +func resourceGithubTeamSettingsCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { + if err := checkOrganization(meta); err != nil { + return diag.FromErr(err) } + teamIDString := d.Get("team_id").(string) + // Given a string that is either a team id or team slug, return the // get the basic details of the team including node_id and slug - ctx := context.Background() - - teamIDString, _ := d.Get("team_id").(string) - nodeId, slug, err := resolveTeamIDs(teamIDString, meta.(*Owner), ctx) if err != nil { - return err + return diag.FromErr(err) } d.SetId(nodeId) if err = d.Set("team_slug", slug); err != nil { - return err + return diag.FromErr(err) } if err = d.Set("team_uid", nodeId); err != nil { - return err + return diag.FromErr(err) } - return resourceGithubTeamSettingsUpdate(d, meta) + return resourceGithubTeamSettingsUpdate(ctx, d, meta) } -func resourceGithubTeamSettingsRead(d *schema.ResourceData, meta any) error { - err := checkOrganization(meta) - if err != nil { - return err +func resourceGithubTeamSettingsRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { + if err := checkOrganization(meta); err != nil { + return diag.FromErr(err) } graphql := meta.(*Owner).v4client @@ -115,9 +112,9 @@ func resourceGithubTeamSettingsRead(d *schema.ResourceData, meta any) error { "login": githubv4.String(orgName), } - e := graphql.Query(meta.(*Owner).StopContext, &query, variables) - if e != nil { - return e + err := graphql.Query(ctx, &query, variables) + if err != nil { + return diag.FromErr(err) } if query.Organization.Team.ReviewRequestDelegation { @@ -126,21 +123,19 @@ func resourceGithubTeamSettingsRead(d *schema.ResourceData, meta any) error { reviewRequestDelegation["member_count"] = query.Organization.Team.ReviewRequestDelegationCount reviewRequestDelegation["notify"] = query.Organization.Team.ReviewRequestDelegationNotifyAll if err = d.Set("review_request_delegation", []any{reviewRequestDelegation}); err != nil { - return err + return diag.FromErr(err) } } else { if err = d.Set("review_request_delegation", []any{}); err != nil { - return err + return diag.FromErr(err) } } return nil } -func resourceGithubTeamSettingsUpdate(d *schema.ResourceData, meta any) error { +func resourceGithubTeamSettingsUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { if d.HasChange("review_request_delegation") || d.IsNewResource() { - - ctx := context.WithValue(context.Background(), ctxId, d.Id()) graphql := meta.(*Owner).v4client if setting := d.Get("review_request_delegation").([]any); len(setting) == 0 { var mutation struct { @@ -149,7 +144,11 @@ func resourceGithubTeamSettingsUpdate(d *schema.ResourceData, meta any) error { } `graphql:"updateTeamReviewAssignment(input:$input)"` } - return graphql.Mutate(ctx, &mutation, defaultTeamReviewAssignmentSettings(d.Id()), nil) + err := graphql.Mutate(ctx, &mutation, defaultTeamReviewAssignmentSettings(d.Id()), nil) + if err != nil { + return diag.FromErr(err) + } + return nil } else { settings := d.Get("review_request_delegation").([]any)[0].(map[string]any) @@ -160,21 +159,25 @@ func resourceGithubTeamSettingsUpdate(d *schema.ResourceData, meta any) error { } teamReviewAlgorithm := githubv4.TeamReviewAssignmentAlgorithm(settings["algorithm"].(string)) - return graphql.Mutate(ctx, &mutation, githubv4.UpdateTeamReviewAssignmentInput{ + updateTeamReviewAssignmentInput := githubv4.UpdateTeamReviewAssignmentInput{ ID: d.Id(), Enabled: githubv4.Boolean(true), Algorithm: &teamReviewAlgorithm, TeamMemberCount: new(githubv4.Int(settings["member_count"].(int))), NotifyTeam: new(githubv4.Boolean(settings["notify"].(bool))), - }, nil) + } + err := graphql.Mutate(ctx, &mutation, updateTeamReviewAssignmentInput, nil) + if err != nil { + return diag.FromErr(err) + } + return nil } } - return resourceGithubTeamSettingsRead(d, meta) + return resourceGithubTeamSettingsRead(ctx, d, meta) } -func resourceGithubTeamSettingsDelete(d *schema.ResourceData, meta any) error { - ctx := context.WithValue(context.Background(), ctxId, d.Id()) +func resourceGithubTeamSettingsDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { graphql := meta.(*Owner).v4client var mutation struct { @@ -183,7 +186,11 @@ func resourceGithubTeamSettingsDelete(d *schema.ResourceData, meta any) error { } `graphql:"updateTeamReviewAssignment(input:$input)"` } - return graphql.Mutate(ctx, &mutation, defaultTeamReviewAssignmentSettings(d.Id()), nil) + err := graphql.Mutate(ctx, &mutation, defaultTeamReviewAssignmentSettings(d.Id()), nil) + if err != nil { + return diag.FromErr(err) + } + return nil } func resourceGithubTeamSettingsImport(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) { From 42ae7ec70e86a13303611a978dd950e5bf1034b7 Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Mon, 23 Feb 2026 12:23:41 +0200 Subject: [PATCH 06/15] Use `resource.ParallelTest` to make testing quicker Signed-off-by: Timo Sand --- github/resource_github_team_settings_test.go | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/github/resource_github_team_settings_test.go b/github/resource_github_team_settings_test.go index 86f511eee7..901ea865ab 100644 --- a/github/resource_github_team_settings_test.go +++ b/github/resource_github_team_settings_test.go @@ -32,7 +32,7 @@ func TestAccGithubTeamSettings(t *testing.T) { } `, teamName) - resource.Test(t, resource.TestCase{ + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, CheckDestroy: testAccCheckGithubTeamSettingsDestroy, @@ -81,7 +81,7 @@ func TestAccGithubTeamSettings(t *testing.T) { } ` - resource.Test(t, resource.TestCase{ + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, CheckDestroy: testAccCheckGithubTeamSettingsDestroy, @@ -141,7 +141,7 @@ func TestAccGithubTeamSettings(t *testing.T) { } `, teamName) - resource.Test(t, resource.TestCase{ + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, CheckDestroy: testAccCheckGithubTeamSettingsDestroy, @@ -185,7 +185,7 @@ func TestAccGithubTeamSettings(t *testing.T) { } `, teamName) - resource.Test(t, resource.TestCase{ + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, CheckDestroy: testAccCheckGithubTeamSettingsDestroy, @@ -234,7 +234,7 @@ func TestAccGithubTeamSettings(t *testing.T) { } `, teamName) - resource.Test(t, resource.TestCase{ + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, CheckDestroy: testAccCheckGithubTeamSettingsDestroy, @@ -266,7 +266,7 @@ func TestAccGithubTeamSettings(t *testing.T) { } `, teamName) - resource.Test(t, resource.TestCase{ + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, CheckDestroy: testAccCheckGithubTeamSettingsDestroy, @@ -294,7 +294,7 @@ func TestAccGithubTeamSettings(t *testing.T) { } `, teamName) - resource.Test(t, resource.TestCase{ + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, CheckDestroy: testAccCheckGithubTeamSettingsDestroy, @@ -335,7 +335,7 @@ func TestAccGithubTeamSettings(t *testing.T) { } `, teamName) - resource.Test(t, resource.TestCase{ + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, CheckDestroy: testAccCheckGithubTeamSettingsDestroy, @@ -382,7 +382,7 @@ func TestAccGithubTeamSettings(t *testing.T) { } `, teamName) - resource.Test(t, resource.TestCase{ + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, CheckDestroy: testAccCheckGithubTeamSettingsDestroy, @@ -448,7 +448,7 @@ func TestAccGithubTeamSettings(t *testing.T) { } `, teamName) - resource.Test(t, resource.TestCase{ + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, CheckDestroy: testAccCheckGithubTeamSettingsDestroy, @@ -499,7 +499,7 @@ func TestAccGithubTeamSettings(t *testing.T) { } ` - resource.Test(t, resource.TestCase{ + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { skipUnlessHasOrgs(t) }, ProviderFactories: providerFactories, CheckDestroy: testAccCheckGithubTeamSettingsDestroy, From 9cc66d83887807e1cbae50ea0500d8bbb1c76cce Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Mon, 23 Feb 2026 12:24:00 +0200 Subject: [PATCH 07/15] Remove unused call to `Read` Signed-off-by: Timo Sand --- github/resource_github_team_settings.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/resource_github_team_settings.go b/github/resource_github_team_settings.go index 235fdf9ecb..64308d05a6 100644 --- a/github/resource_github_team_settings.go +++ b/github/resource_github_team_settings.go @@ -174,7 +174,7 @@ func resourceGithubTeamSettingsUpdate(ctx context.Context, d *schema.ResourceDat } } - return resourceGithubTeamSettingsRead(ctx, d, meta) + return nil } func resourceGithubTeamSettingsDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { From ee40cec448c5e6e9b0862beeff99d36611c4ce08 Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Mon, 23 Feb 2026 12:39:17 +0200 Subject: [PATCH 08/15] Uncouple `Create` and `Update` Signed-off-by: Timo Sand --- github/resource_github_team_settings.go | 89 +++++++++++++++++++------ 1 file changed, 67 insertions(+), 22 deletions(-) diff --git a/github/resource_github_team_settings.go b/github/resource_github_team_settings.go index 64308d05a6..a455066099 100644 --- a/github/resource_github_team_settings.go +++ b/github/resource_github_team_settings.go @@ -5,6 +5,7 @@ import ( "errors" "strconv" + "github.com/hashicorp/terraform-plugin-log/tflog" "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" @@ -73,19 +74,28 @@ func resourceGithubTeamSettings() *schema.Resource { } } -func resourceGithubTeamSettingsCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { - if err := checkOrganization(meta); err != nil { +func resourceGithubTeamSettingsCreate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + meta := m.(*Owner) + if err := checkOrganization(m); err != nil { return diag.FromErr(err) } + graphql := meta.v4client teamIDString := d.Get("team_id").(string) + tflog.Debug(ctx, "Resolving team_id to Team node_id and slug", map[string]any{ + "team_id": teamIDString, + }) // Given a string that is either a team id or team slug, return the // get the basic details of the team including node_id and slug - nodeId, slug, err := resolveTeamIDs(teamIDString, meta.(*Owner), ctx) + nodeId, slug, err := resolveTeamIDs(teamIDString, meta, ctx) if err != nil { return diag.FromErr(err) } + tflog.Trace(ctx, "Resolved team_id to Team node_id and slug", map[string]any{ + "node_id": nodeId, + "slug": slug, + }) d.SetId(nodeId) if err = d.Set("team_slug", slug); err != nil { return diag.FromErr(err) @@ -93,7 +103,42 @@ func resourceGithubTeamSettingsCreate(ctx context.Context, d *schema.ResourceDat if err = d.Set("team_uid", nodeId); err != nil { return diag.FromErr(err) } - return resourceGithubTeamSettingsUpdate(ctx, d, meta) + + reviewRequestDelegation := d.Get("review_request_delegation").([]any) + + var mutation struct { + UpdateTeamReviewAssignment struct { + ClientMutationId githubv4.ID `graphql:"clientMutationId"` + } `graphql:"updateTeamReviewAssignment(input:$input)"` + } + + if len(reviewRequestDelegation) == 0 { + tflog.Debug(ctx, "No review request delegation settings provided, disabling review request delegation", map[string]any{ + "team_id": d.Id(), + "team_slug": slug, + }) + + err := graphql.Mutate(ctx, &mutation, defaultTeamReviewAssignmentSettings(d.Id()), nil) + if err != nil { + return diag.FromErr(err) + } + } else { + settings := reviewRequestDelegation[0].(map[string]any) + + teamReviewAlgorithm := githubv4.TeamReviewAssignmentAlgorithm(settings["algorithm"].(string)) + updateTeamReviewAssignmentInput := githubv4.UpdateTeamReviewAssignmentInput{ + ID: d.Id(), + Enabled: githubv4.Boolean(true), + Algorithm: &teamReviewAlgorithm, + TeamMemberCount: githubv4.NewInt(githubv4.Int(settings["member_count"].(int))), + NotifyTeam: githubv4.NewBoolean(githubv4.Boolean(settings["notify"].(bool))), + } + err := graphql.Mutate(ctx, &mutation, updateTeamReviewAssignmentInput, nil) + if err != nil { + return diag.FromErr(err) + } + } + return nil } func resourceGithubTeamSettingsRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { @@ -134,29 +179,30 @@ func resourceGithubTeamSettingsRead(ctx context.Context, d *schema.ResourceData, return nil } -func resourceGithubTeamSettingsUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { - if d.HasChange("review_request_delegation") || d.IsNewResource() { - graphql := meta.(*Owner).v4client - if setting := d.Get("review_request_delegation").([]any); len(setting) == 0 { - var mutation struct { - UpdateTeamReviewAssignment struct { - ClientMutationId githubv4.ID `graphql:"clientMutationId"` - } `graphql:"updateTeamReviewAssignment(input:$input)"` - } +func resourceGithubTeamSettingsUpdate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + if d.HasChange("review_request_delegation") { + meta := m.(*Owner) + graphql := meta.v4client + reviewRequestDelegation := d.Get("review_request_delegation").([]any) + + var mutation struct { + UpdateTeamReviewAssignment struct { + ClientMutationId githubv4.ID `graphql:"clientMutationId"` + } `graphql:"updateTeamReviewAssignment(input:$input)"` + } + + if len(reviewRequestDelegation) == 0 { + tflog.Debug(ctx, "No review request delegation settings provided, disabling review request delegation", map[string]any{ + "team_id": d.Id(), + "team_slug": d.Get("team_slug").(string), + }) err := graphql.Mutate(ctx, &mutation, defaultTeamReviewAssignmentSettings(d.Id()), nil) if err != nil { return diag.FromErr(err) } - return nil } else { - settings := d.Get("review_request_delegation").([]any)[0].(map[string]any) - - var mutation struct { - UpdateTeamReviewAssignment struct { - ClientMutationId githubv4.ID `graphql:"clientMutationId"` - } `graphql:"updateTeamReviewAssignment(input:$input)"` - } + settings := reviewRequestDelegation[0].(map[string]any) teamReviewAlgorithm := githubv4.TeamReviewAssignmentAlgorithm(settings["algorithm"].(string)) updateTeamReviewAssignmentInput := githubv4.UpdateTeamReviewAssignmentInput{ @@ -170,7 +216,6 @@ func resourceGithubTeamSettingsUpdate(ctx context.Context, d *schema.ResourceDat if err != nil { return diag.FromErr(err) } - return nil } } From c0b61737d4cbbf4e60ab1be33b0fe613352433c1 Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Mon, 23 Feb 2026 12:49:33 +0200 Subject: [PATCH 09/15] Fix resource to be able to set empty `review_request_delegation` block Signed-off-by: Timo Sand --- github/resource_github_team_settings.go | 21 ++++++++++++++++---- github/resource_github_team_settings_test.go | 1 - 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/github/resource_github_team_settings.go b/github/resource_github_team_settings.go index a455066099..396b8813c8 100644 --- a/github/resource_github_team_settings.go +++ b/github/resource_github_team_settings.go @@ -53,10 +53,10 @@ func resourceGithubTeamSettings() *schema.Resource { ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{string(githubv4.TeamReviewAssignmentAlgorithmRoundRobin), string(githubv4.TeamReviewAssignmentAlgorithmLoadBalance)}, false)), }, "member_count": { - Type: schema.TypeInt, - Optional: true, - RequiredWith: []string{"review_request_delegation"}, - Description: "The number of team members to assign to a pull request.", + Type: schema.TypeInt, + Optional: true, + Default: 1, + Description: "The number of team members to assign to a pull request.", ValidateDiagFunc: validation.ToDiagFunc(validation.All( validation.IntAtLeast(1), )), @@ -112,6 +112,13 @@ func resourceGithubTeamSettingsCreate(ctx context.Context, d *schema.ResourceDat } `graphql:"updateTeamReviewAssignment(input:$input)"` } + tflog.Debug(ctx, "Review request delegation settings", map[string]any{ + "team_id": d.Id(), + "team_slug": slug, + "review_request_delegation": reviewRequestDelegation, + "length_of_settings": len(reviewRequestDelegation), + }) + if len(reviewRequestDelegation) == 0 { tflog.Debug(ctx, "No review request delegation settings provided, disabling review request delegation", map[string]any{ "team_id": d.Id(), @@ -123,6 +130,11 @@ func resourceGithubTeamSettingsCreate(ctx context.Context, d *schema.ResourceDat return diag.FromErr(err) } } else { + tflog.Debug(ctx, "Review request delegation settings provided, setting according to provided configuration", map[string]any{ + "team_id": d.Id(), + "team_slug": slug, + "review_request_delegation": reviewRequestDelegation, + }) settings := reviewRequestDelegation[0].(map[string]any) teamReviewAlgorithm := githubv4.TeamReviewAssignmentAlgorithm(settings["algorithm"].(string)) @@ -133,6 +145,7 @@ func resourceGithubTeamSettingsCreate(ctx context.Context, d *schema.ResourceDat TeamMemberCount: githubv4.NewInt(githubv4.Int(settings["member_count"].(int))), NotifyTeam: githubv4.NewBoolean(githubv4.Boolean(settings["notify"].(bool))), } + err := graphql.Mutate(ctx, &mutation, updateTeamReviewAssignmentInput, nil) if err != nil { return diag.FromErr(err) diff --git a/github/resource_github_team_settings_test.go b/github/resource_github_team_settings_test.go index 901ea865ab..3db6337f0d 100644 --- a/github/resource_github_team_settings_test.go +++ b/github/resource_github_team_settings_test.go @@ -219,7 +219,6 @@ func TestAccGithubTeamSettings(t *testing.T) { }) t.Run("creates_with_empty_review_request_delegation_block_without_error", func(t *testing.T) { - t.Skip("TODO this isn't working as expected") randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) config := fmt.Sprintf(` From 4e10e23c8ef6f0aaf85b325ba7587f22fd24cb47 Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Mon, 23 Feb 2026 16:14:43 +0200 Subject: [PATCH 10/15] Add top-level `notify` to enable setting it without `review_request_delegation` Mark nested `notify` as deprecated Signed-off-by: Timo Sand --- github/resource_github_team_settings.go | 83 ++++++++-- github/resource_github_team_settings_test.go | 161 ++++++++++++++++++- website/docs/r/team_settings.html.markdown | 28 +++- 3 files changed, 252 insertions(+), 20 deletions(-) diff --git a/github/resource_github_team_settings.go b/github/resource_github_team_settings.go index 396b8813c8..08baf22cda 100644 --- a/github/resource_github_team_settings.go +++ b/github/resource_github_team_settings.go @@ -38,6 +38,13 @@ func resourceGithubTeamSettings() *schema.Resource { Computed: true, Description: "The unique ID of the Team on GitHub. Corresponds to the ID of the 'github_team_settings' resource.", }, + "notify": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Whether to notify the entire team when at least one member is also assigned to the pull request.", + ConflictsWith: []string{"review_request_delegation.0.notify"}, + }, "review_request_delegation": { Type: schema.TypeList, MaxItems: 1, @@ -62,10 +69,12 @@ func resourceGithubTeamSettings() *schema.Resource { )), }, "notify": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Description: "whether to notify the entire team when at least one member is also assigned to the pull request.", + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "whether to notify the entire team when at least one member is also assigned to the pull request.", + Deprecated: "Use the top-level notify attribute instead.", + ConflictsWith: []string{"notify"}, }, }, }, @@ -119,13 +128,19 @@ func resourceGithubTeamSettingsCreate(ctx context.Context, d *schema.ResourceDat "length_of_settings": len(reviewRequestDelegation), }) + notify := resolveNotify(ctx, d) + if len(reviewRequestDelegation) == 0 { tflog.Debug(ctx, "No review request delegation settings provided, disabling review request delegation", map[string]any{ "team_id": d.Id(), "team_slug": slug, + "notify": notify, }) - err := graphql.Mutate(ctx, &mutation, defaultTeamReviewAssignmentSettings(d.Id()), nil) + input := defaultTeamReviewAssignmentSettings(d.Id()) + input.NotifyTeam = new(githubv4.Boolean(notify)) + + err := graphql.Mutate(ctx, &mutation, input, nil) if err != nil { return diag.FromErr(err) } @@ -134,6 +149,7 @@ func resourceGithubTeamSettingsCreate(ctx context.Context, d *schema.ResourceDat "team_id": d.Id(), "team_slug": slug, "review_request_delegation": reviewRequestDelegation, + "notify": notify, }) settings := reviewRequestDelegation[0].(map[string]any) @@ -142,8 +158,8 @@ func resourceGithubTeamSettingsCreate(ctx context.Context, d *schema.ResourceDat ID: d.Id(), Enabled: githubv4.Boolean(true), Algorithm: &teamReviewAlgorithm, - TeamMemberCount: githubv4.NewInt(githubv4.Int(settings["member_count"].(int))), - NotifyTeam: githubv4.NewBoolean(githubv4.Boolean(settings["notify"].(bool))), + TeamMemberCount: new(githubv4.Int(settings["member_count"].(int))), + NotifyTeam: new(githubv4.Boolean(notify)), } err := graphql.Mutate(ctx, &mutation, updateTeamReviewAssignmentInput, nil) @@ -175,11 +191,29 @@ func resourceGithubTeamSettingsRead(ctx context.Context, d *schema.ResourceData, return diag.FromErr(err) } + notifyValue := query.Organization.Team.ReviewRequestDelegationNotifyAll + + // Set notify in the location matching the user's config: top-level or + // deprecated nested field inside review_request_delegation. + _, usesDeprecatedNotify := d.GetOk("review_request_delegation.0.notify") + tflog.Debug(ctx, "Uses deprecated notify", map[string]any{ + "uses_deprecated_notify": usesDeprecatedNotify, + "notify_value": notifyValue, + }) + + if !usesDeprecatedNotify { + if err = d.Set("notify", notifyValue); err != nil { + return diag.FromErr(err) + } + } + if query.Organization.Team.ReviewRequestDelegation { reviewRequestDelegation := make(map[string]any) reviewRequestDelegation["algorithm"] = query.Organization.Team.ReviewRequestDelegationAlgorithm reviewRequestDelegation["member_count"] = query.Organization.Team.ReviewRequestDelegationCount - reviewRequestDelegation["notify"] = query.Organization.Team.ReviewRequestDelegationNotifyAll + if usesDeprecatedNotify { + reviewRequestDelegation["notify"] = notifyValue + } if err = d.Set("review_request_delegation", []any{reviewRequestDelegation}); err != nil { return diag.FromErr(err) } @@ -193,10 +227,11 @@ func resourceGithubTeamSettingsRead(ctx context.Context, d *schema.ResourceData, } func resourceGithubTeamSettingsUpdate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { - if d.HasChange("review_request_delegation") { + if d.HasChange("review_request_delegation") || d.HasChange("notify") { meta := m.(*Owner) graphql := meta.v4client reviewRequestDelegation := d.Get("review_request_delegation").([]any) + notify := resolveNotify(ctx, d) var mutation struct { UpdateTeamReviewAssignment struct { @@ -208,9 +243,13 @@ func resourceGithubTeamSettingsUpdate(ctx context.Context, d *schema.ResourceDat tflog.Debug(ctx, "No review request delegation settings provided, disabling review request delegation", map[string]any{ "team_id": d.Id(), "team_slug": d.Get("team_slug").(string), + "notify": notify, }) - err := graphql.Mutate(ctx, &mutation, defaultTeamReviewAssignmentSettings(d.Id()), nil) + input := defaultTeamReviewAssignmentSettings(d.Id()) + input.NotifyTeam = new(githubv4.Boolean(notify)) + + err := graphql.Mutate(ctx, &mutation, input, nil) if err != nil { return diag.FromErr(err) } @@ -299,6 +338,30 @@ func resolveTeamIDs(idOrSlug string, meta *Owner, ctx context.Context) (nodeId, } } +// resolveNotify returns the notify value from the top-level attribute or the +// deprecated nested attribute inside review_request_delegation. The top-level +// attribute takes precedence. Since ConflictsWith prevents both from being set, +// only one source can be active at a time. +func resolveNotify(ctx context.Context, d *schema.ResourceData) bool { + // Check if top-level notify is explicitly configured. + if v, ok := d.GetOk("notify"); ok { + tflog.Debug(ctx, "Top-level notify is explicitly configured", map[string]any{ + "notify": v, + }) + return v.(bool) + } + + // Fall back to deprecated nested field + if v, ok := d.GetOk("review_request_delegation.0.notify"); ok { + tflog.Debug(ctx, "Deprecated nested notify is explicitly configured", map[string]any{ + "notify": v, + }) + return v.(bool) + } + + return false +} + func defaultTeamReviewAssignmentSettings(id string) githubv4.UpdateTeamReviewAssignmentInput { roundRobinAlgo := githubv4.TeamReviewAssignmentAlgorithmRoundRobin return githubv4.UpdateTeamReviewAssignmentInput{ diff --git a/github/resource_github_team_settings_test.go b/github/resource_github_team_settings_test.go index 3db6337f0d..268d89e993 100644 --- a/github/resource_github_team_settings_test.go +++ b/github/resource_github_team_settings_test.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/plancheck" "github.com/hashicorp/terraform-plugin-testing/statecheck" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" @@ -373,10 +374,10 @@ func TestAccGithubTeamSettings(t *testing.T) { resource "github_team_settings" "test" { team_id = github_team.test.id + notify = true review_request_delegation { algorithm = "ROUND_ROBIN" member_count = 2 - notify = true } } `, teamName) @@ -397,13 +398,22 @@ func TestAccGithubTeamSettings(t *testing.T) { knownvalue.Int64Exact(2)), statecheck.ExpectKnownValue("github_team_settings.test", tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("notify"), + knownvalue.Bool(false)), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("notify"), knownvalue.Bool(true)), }, }, { - ResourceName: "github_team_settings.test", - ImportState: true, - ImportStateVerify: true, + ResourceName: "github_team_settings.test", + ImportStateKind: resource.ImportBlockWithID, + ImportState: true, + ImportPlanChecks: resource.ImportPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectKnownValue("github_team_settings.test", tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("notify"), knownvalue.Bool(false)), + plancheck.ExpectKnownValue("github_team_settings.test", tfjsonpath.New("notify"), knownvalue.Bool(true)), + }, + }, ImportStateIdFunc: func(s *terraform.State) (string, error) { rs, ok := s.RootModule().Resources["github_team.test"] if !ok { @@ -478,6 +488,149 @@ func TestAccGithubTeamSettings(t *testing.T) { }) }) + t.Run("manages top-level notify without delegation", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) + + config := ` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = "${github_team.test.id}" + notify = %t + } + ` + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(config, teamName, true), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("notify"), + knownvalue.Bool(true)), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation"), + knownvalue.ListExact([]knownvalue.Check{})), + }, + }, + { + Config: fmt.Sprintf(config, teamName, false), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("notify"), + knownvalue.Bool(false)), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation"), + knownvalue.ListExact([]knownvalue.Check{})), + }, + }, + }, + }) + }) + + t.Run("manages top-level notify with delegation", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) + + config := ` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = "${github_team.test.id}" + notify = %t + review_request_delegation { + algorithm = "ROUND_ROBIN" + member_count = 2 + } + } + ` + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(config, teamName, true), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("notify"), + knownvalue.Bool(true)), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("algorithm"), + knownvalue.StringExact("ROUND_ROBIN")), + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("member_count"), + knownvalue.Int64Exact(2)), + }, + }, + { + Config: fmt.Sprintf(config, teamName, false), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("notify"), + knownvalue.Bool(false)), + }, + }, + }, + }) + }) + + t.Run("imports team settings with top-level notify", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) + + config := fmt.Sprintf(` + resource "github_team" "test" { + name = "%s" + description = "generated by terraform provider automated testing" + } + + resource "github_team_settings" "test" { + team_id = github_team.test.id + notify = true + } + `, teamName) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { skipUnlessHasOrgs(t) }, + ProviderFactories: providerFactories, + CheckDestroy: testAccCheckGithubTeamSettingsDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue("github_team_settings.test", + tfjsonpath.New("notify"), + knownvalue.Bool(true)), + }, + }, + { + ResourceName: "github_team_settings.test", + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources["github_team.test"] + if !ok { + return "", fmt.Errorf("not found: github_team.test") + } + return rs.Primary.Attributes["id"], nil + }, + }, + }, + }) + }) + t.Run("manages updating only notify field", func(t *testing.T) { randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) teamName := fmt.Sprintf("%steam-settings-%s", testResourcePrefix, randomID) diff --git a/website/docs/r/team_settings.html.markdown b/website/docs/r/team_settings.html.markdown index 11dd23cdfb..674b410fcc 100644 --- a/website/docs/r/team_settings.html.markdown +++ b/website/docs/r/team_settings.html.markdown @@ -17,19 +17,34 @@ The team must both belong to the same organization configured in the provider on ## Example Usage +### Notify without delegation + +```hcl +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_team_settings" "code_review_settings" { + team_id = github_team.some_team.id + notify = true +} +``` + +### Notify with delegation + ```hcl -# Add a repository to the team resource "github_team" "some_team" { name = "SomeTeam" description = "Some cool team" } resource "github_team_settings" "code_review_settings" { - team_id = github_team.some_team.id + team_id = github_team.some_team.id + notify = true review_request_delegation { - algorithm = "ROUND_ROBIN" - member_count = 1 - notify = true + algorithm = "ROUND_ROBIN" + member_count = 1 } } ``` @@ -39,6 +54,7 @@ resource "github_team_settings" "code_review_settings" { The following arguments are supported: - `team_id` - (Required) The GitHub team id or the GitHub team slug +- `notify` - (Optional) Whether to notify the entire team when at least one member is also assigned to the pull request. Can be set independently of `review_request_delegation`. Default value is `false`. - `review_request_delegation` - (Optional) The settings for delegating code reviews to individuals on behalf of the team. If this block is present, even without any fields, then review request delegation will be enabled for the team. See [GitHub Review Request Delegation](#github-review-request-delegation-configuration) below for details. See [GitHub's documentation](https://docs.github.com/en/organizations/organizing-members-into-teams/managing-code-review-settings-for-your-team#configuring-team-notifications) for more configuration details. ### GitHub Review Request Delegation Configuration @@ -47,7 +63,7 @@ The following arguments are supported: - `algorithm` - (Optional) The algorithm to use when assigning pull requests to team members. Supported values are `ROUND_ROBIN` and `LOAD_BALANCE`. Default value is `ROUND_ROBIN` - `member_count` - (Optional) The number of team members to assign to a pull request -- `notify` - (Optional) whether to notify the entire team when at least one member is also assigned to the pull request +- `notify` - (Optional, **Deprecated**: Use the top-level `notify` attribute instead.) Whether to notify the entire team when at least one member is also assigned to the pull request. Conflicts with the top-level `notify` attribute. ## Attributes Reference From 1b5617344878bd09767effe8306ec52d4617df95 Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Mon, 23 Feb 2026 16:23:22 +0200 Subject: [PATCH 11/15] Update docs Signed-off-by: Timo Sand --- website/docs/r/team_settings.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/team_settings.html.markdown b/website/docs/r/team_settings.html.markdown index 674b410fcc..c09d8ad051 100644 --- a/website/docs/r/team_settings.html.markdown +++ b/website/docs/r/team_settings.html.markdown @@ -62,7 +62,7 @@ The following arguments are supported: The following arguments are supported: - `algorithm` - (Optional) The algorithm to use when assigning pull requests to team members. Supported values are `ROUND_ROBIN` and `LOAD_BALANCE`. Default value is `ROUND_ROBIN` -- `member_count` - (Optional) The number of team members to assign to a pull request +- `member_count` - (Optional) The number of team members to assign to a pull request. Default value is `1`. - `notify` - (Optional, **Deprecated**: Use the top-level `notify` attribute instead.) Whether to notify the entire team when at least one member is also assigned to the pull request. Conflicts with the top-level `notify` attribute. ## Attributes Reference From 4871e6379455e07d29b88dffb25077dd05d0d4cc Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Tue, 24 Feb 2026 22:02:20 +0200 Subject: [PATCH 12/15] Consolidate `getTeamSlugContext` and `resolveTeamIDs` to use shared logic with `getTeam` Signed-off-by: Timo Sand --- github/resource_github_team_settings.go | 38 +++++-------------------- github/util_team.go | 25 ++++++++++++++++ 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/github/resource_github_team_settings.go b/github/resource_github_team_settings.go index 08baf22cda..0a6272acc0 100644 --- a/github/resource_github_team_settings.go +++ b/github/resource_github_team_settings.go @@ -2,8 +2,6 @@ package github import ( "context" - "errors" - "strconv" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -97,7 +95,7 @@ func resourceGithubTeamSettingsCreate(ctx context.Context, d *schema.ResourceDat }) // Given a string that is either a team id or team slug, return the // get the basic details of the team including node_id and slug - nodeId, slug, err := resolveTeamIDs(teamIDString, meta, ctx) + nodeId, slug, err := resolveTeamIDs(ctx, meta, teamIDString) if err != nil { return diag.FromErr(err) } @@ -291,7 +289,7 @@ func resourceGithubTeamSettingsDelete(ctx context.Context, d *schema.ResourceDat } func resourceGithubTeamSettingsImport(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) { - nodeId, slug, err := resolveTeamIDs(d.Id(), meta.(*Owner), ctx) + nodeId, slug, err := resolveTeamIDs(ctx, meta.(*Owner), d.Id()) if err != nil { return nil, err } @@ -308,34 +306,12 @@ func resourceGithubTeamSettingsImport(ctx context.Context, d *schema.ResourceDat return []*schema.ResourceData{d}, nil } -func resolveTeamIDs(idOrSlug string, meta *Owner, ctx context.Context) (nodeId, slug string, err error) { - client := meta.v3client - orgName := meta.name - orgId := meta.id - - teamId, parseIntErr := strconv.ParseInt(idOrSlug, 10, 64) - if parseIntErr != nil { - // The given id not an integer, assume it is a team slug - team, _, slugErr := client.Teams.GetTeamBySlug(ctx, orgName, idOrSlug) - if slugErr != nil { - return "", "", errors.New(parseIntErr.Error() + slugErr.Error()) - } - return team.GetNodeID(), team.GetSlug(), nil - } else { - // The given id is an integer, assume it is a team id - team, _, teamIdErr := client.Teams.GetTeamByID(ctx, orgId, teamId) - if teamIdErr != nil { - // There isn't a team with the given ID, assume it is a teamslug - team, _, slugErr := client.Teams.GetTeamBySlug(ctx, orgName, idOrSlug) - if slugErr != nil { - return "", "", errors.New(teamIdErr.Error() + slugErr.Error()) - } - - return team.GetNodeID(), team.GetSlug(), nil - } - - return team.GetNodeID(), team.GetSlug(), nil +func resolveTeamIDs(ctx context.Context, meta *Owner, idOrSlug string) (nodeId, slug string, err error) { + team, err := getTeam(ctx, meta, idOrSlug) + if err != nil { + return "", "", err } + return team.GetNodeID(), team.GetSlug(), nil } // resolveNotify returns the notify value from the top-level attribute or the diff --git a/github/util_team.go b/github/util_team.go index 8f674054d3..e79c2d2eea 100644 --- a/github/util_team.go +++ b/github/util_team.go @@ -2,6 +2,7 @@ package github import ( "context" + "fmt" "strconv" "github.com/google/go-github/v84/github" @@ -150,3 +151,27 @@ func lookupTeamID(ctx context.Context, client *github.Client, orgName, slug stri } return team.GetID(), nil } + +// Given a string that is either a team id or team slug, return the +// team object it is referring to. +func getTeam(ctx context.Context, meta *Owner, idOrSlug string) (*github.Team, error) { + client := meta.v3client + orgName := meta.name + orgId := meta.id + + if id, ok := parseTeamID(idOrSlug); ok { + // The given id is an integer, assume it is the team ID. + team, _, err := client.Teams.GetTeamByID(ctx, orgId, id) + if err != nil { + return nil, fmt.Errorf("failed to get team by ID (%d): %w", id, err) + } + return team, nil + } + + // The given id not an integer, assume it is a team slug + team, _, err := client.Teams.GetTeamBySlug(ctx, orgName, idOrSlug) + if err != nil { + return nil, fmt.Errorf("failed to get team by slug (%s): %w", idOrSlug, err) + } + return team, nil +} From 85f61a7817aca1ff1e52ac79b71cf9643bcf418b Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Fri, 27 Mar 2026 19:33:48 +0200 Subject: [PATCH 13/15] Remove named returns --- github/resource_github_team_settings.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/resource_github_team_settings.go b/github/resource_github_team_settings.go index 0a6272acc0..6da6491223 100644 --- a/github/resource_github_team_settings.go +++ b/github/resource_github_team_settings.go @@ -306,7 +306,7 @@ func resourceGithubTeamSettingsImport(ctx context.Context, d *schema.ResourceDat return []*schema.ResourceData{d}, nil } -func resolveTeamIDs(ctx context.Context, meta *Owner, idOrSlug string) (nodeId, slug string, err error) { +func resolveTeamIDs(ctx context.Context, meta *Owner, idOrSlug string) (string, string, error) { team, err := getTeam(ctx, meta, idOrSlug) if err != nil { return "", "", err From e304bb3b35cab2a94405e0238fd818d44721a5c2 Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Thu, 16 Apr 2026 20:56:11 +0300 Subject: [PATCH 14/15] Fix missing reference Signed-off-by: Timo Sand --- github/resource_github_team_settings.go | 2 +- github/resource_github_team_settings_test.go | 16 ++++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/github/resource_github_team_settings.go b/github/resource_github_team_settings.go index 6da6491223..b16cde4ba8 100644 --- a/github/resource_github_team_settings.go +++ b/github/resource_github_team_settings.go @@ -260,7 +260,7 @@ func resourceGithubTeamSettingsUpdate(ctx context.Context, d *schema.ResourceDat Enabled: githubv4.Boolean(true), Algorithm: &teamReviewAlgorithm, TeamMemberCount: new(githubv4.Int(settings["member_count"].(int))), - NotifyTeam: new(githubv4.Boolean(settings["notify"].(bool))), + NotifyTeam: new(githubv4.Boolean(notify)), } err := graphql.Mutate(ctx, &mutation, updateTeamReviewAssignmentInput, nil) if err != nil { diff --git a/github/resource_github_team_settings_test.go b/github/resource_github_team_settings_test.go index 268d89e993..190629588e 100644 --- a/github/resource_github_team_settings_test.go +++ b/github/resource_github_team_settings_test.go @@ -390,18 +390,10 @@ func TestAccGithubTeamSettings(t *testing.T) { { Config: config, ConfigStateChecks: []statecheck.StateCheck{ - statecheck.ExpectKnownValue("github_team_settings.test", - tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("algorithm"), - knownvalue.StringExact("ROUND_ROBIN")), - statecheck.ExpectKnownValue("github_team_settings.test", - tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("member_count"), - knownvalue.Int64Exact(2)), - statecheck.ExpectKnownValue("github_team_settings.test", - tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("notify"), - knownvalue.Bool(false)), - statecheck.ExpectKnownValue("github_team_settings.test", - tfjsonpath.New("notify"), - knownvalue.Bool(true)), + statecheck.ExpectKnownValue("github_team_settings.test", tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("algorithm"), knownvalue.StringExact("ROUND_ROBIN")), + statecheck.ExpectKnownValue("github_team_settings.test", tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("member_count"), knownvalue.Int64Exact(2)), + statecheck.ExpectKnownValue("github_team_settings.test", tfjsonpath.New("review_request_delegation").AtSliceIndex(0).AtMapKey("notify"), knownvalue.Bool(false)), + statecheck.ExpectKnownValue("github_team_settings.test", tfjsonpath.New("notify"), knownvalue.Bool(true)), }, }, { From 2668ba7d296f384ae5772e2da47e36a60a6df809 Mon Sep 17 00:00:00 2001 From: Timo Sand Date: Thu, 16 Apr 2026 22:07:06 +0300 Subject: [PATCH 15/15] Simplify `resolveNotify` Signed-off-by: Timo Sand --- github/resource_github_team_settings.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/github/resource_github_team_settings.go b/github/resource_github_team_settings.go index b16cde4ba8..a003a7d8b1 100644 --- a/github/resource_github_team_settings.go +++ b/github/resource_github_team_settings.go @@ -320,19 +320,19 @@ func resolveTeamIDs(ctx context.Context, meta *Owner, idOrSlug string) (string, // only one source can be active at a time. func resolveNotify(ctx context.Context, d *schema.ResourceData) bool { // Check if top-level notify is explicitly configured. - if v, ok := d.GetOk("notify"); ok { + if v := d.Get("notify").(bool); v { tflog.Debug(ctx, "Top-level notify is explicitly configured", map[string]any{ "notify": v, }) - return v.(bool) + return v } // Fall back to deprecated nested field - if v, ok := d.GetOk("review_request_delegation.0.notify"); ok { + if v := d.Get("review_request_delegation.0.notify").(bool); v { tflog.Debug(ctx, "Deprecated nested notify is explicitly configured", map[string]any{ "notify": v, }) - return v.(bool) + return v } return false