Skip to content

Commit

Permalink
Add support for a summary view of org teams. (integrations#1176)
Browse files Browse the repository at this point in the history
Add a flag input to optionally skip returning the repositories and members on calling the github_organization_teams data source.
This improves performance of the graphql call when only summary information is needed.
Especially important on orgs with large numbers of teams/members.

- Add summary_only optional flag input to skip returning members and repositories
- Add 'results_per_page' optional int to reduce the results per page returned.
- Update docs to reflect change
  • Loading branch information
david-bain committed Oct 31, 2022
1 parent 9285758 commit a7e8fa3
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 7 deletions.
18 changes: 17 additions & 1 deletion github/data_source_github_organization_teams.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package github

import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/shurcooL/githubv4"
)

Expand All @@ -15,6 +16,17 @@ func dataSourceGithubOrganizationTeams() *schema.Resource {
Optional: true,
Default: false,
},
"summary_only": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"results_per_page": {
Type: schema.TypeInt,
Optional: true,
Default: 100,
ValidateFunc: validation.IntBetween(0, 100),
},
"teams": {
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -70,13 +82,17 @@ func dataSourceGithubOrganizationTeamsRead(d *schema.ResourceData, meta interfac
client := meta.(*Owner).v4client
orgName := meta.(*Owner).name
rootTeamsOnly := d.Get("root_teams_only").(bool)
summaryOnly := d.Get("summary_only").(bool)
resultsPerPage := d.Get("results_per_page").(int)

var query TeamsQuery

variables := map[string]interface{}{
"first": githubv4.Int(100),
"first": githubv4.Int(resultsPerPage),
"login": githubv4.String(orgName),
"cursor": (*githubv4.String)(nil),
"rootTeamsOnly": githubv4.Boolean(rootTeamsOnly),
"summaryOnly": githubv4.Boolean(summaryOnly),
}

var teams []interface{}
Expand Down
82 changes: 82 additions & 0 deletions github/data_source_github_organization_teams_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,86 @@ func TestAccGithubOrganizationTeamsDataSource(t *testing.T) {

})

t.Run("queries summary only without error", func(t *testing.T) {

config := `
data "github_organization_teams" "all" {
summary_only = true
}
`

check := resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet("data.github_organization_teams.all", "teams.0.id"),
resource.TestCheckResourceAttrSet("data.github_organization_teams.all", "teams.0.node_id"),
resource.TestCheckNoResourceAttr("data.github_organization_teams.all", "teams.0.members"),
resource.TestCheckNoResourceAttr("data.github_organization_teams.all", "teams.0.repositories"),
)

testCase := func(t *testing.T, mode string) {
resource.Test(t, resource.TestCase{
PreCheck: func() { skipUnlessMode(t, mode) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: config,
Check: check,
},
},
})
}

t.Run("with an anonymous account", func(t *testing.T) {
t.Skip("anonymous account not supported for this operation")
})

t.Run("with an individual account", func(t *testing.T) {
t.Skip("individual account not supported for this operation")
})

t.Run("with an organization account", func(t *testing.T) {
testCase(t, organization)
})

})

t.Run("queries results_per_page only without error", func(t *testing.T) {

config := `
data "github_organization_teams" "all" {
results_per_page = 50
}
`

check := resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet("data.github_organization_teams.all", "teams.0.id"),
resource.TestCheckResourceAttrSet("data.github_organization_teams.all", "teams.0.node_id"),
)

testCase := func(t *testing.T, mode string) {
resource.Test(t, resource.TestCase{
PreCheck: func() { skipUnlessMode(t, mode) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: config,
Check: check,
},
},
})
}

t.Run("with an anonymous account", func(t *testing.T) {
t.Skip("anonymous account not supported for this operation")
})

t.Run("with an individual account", func(t *testing.T) {
t.Skip("individual account not supported for this operation")
})

t.Run("with an organization account", func(t *testing.T) {
testCase(t, organization)
})

})

}
4 changes: 2 additions & 2 deletions github/util_v4_teams.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ type TeamsQuery struct {
Nodes []struct {
Login githubv4.String
}
}
} `graphql:"members @skip(if: $summaryOnly)"`
Repositories struct {
Nodes []struct {
Name githubv4.String
}
}
} `graphql:"repositories @skip(if: $summaryOnly)"`
}
PageInfo PageInfo
} `graphql:"teams(first:$first, after:$cursor, rootTeamsOnly:$rootTeamsOnly)"`
Expand Down
11 changes: 7 additions & 4 deletions website/docs/d/organization_teams.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ data "github_organization_teams" "root_teams" {

## Attributes Reference

* `root_teams_only` - Only return teams that are at the organization's root, i.e. no nested teams. Defaults to `false`.
* `teams` - An Array of GitHub Teams. Each `team` block consists of the fields documented below.
* `teams` - (Required) An Array of GitHub Teams. Each `team` block consists of the fields documented below.
* `root_teams_only` - (Optional) Only return teams that are at the organization's root, i.e. no nested teams. Defaults to `false`.
* `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`.

___

The `team` block consists of:
Expand All @@ -39,5 +42,5 @@ The `team` block consists of:
* `name` - the team's full name.
* `description` - the team's description.
* `privacy` - the team's privacy type.
* `members` - List of team members.
* `repositories` - List of team repositories.
* `members` - List of team members. Not returned if `summary_only = true`
* `repositories` - List of team repositories. Not returned if `summary_only = true`

0 comments on commit a7e8fa3

Please sign in to comment.