-
Couldn't load subscription status.
- Fork 877
feat: support team organization role assignment #2322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
nickfloyd
merged 27 commits into
integrations:main
from
felixlut:github_team_organization_role_assignment
Oct 20, 2025
+342
−0
Merged
Changes from 11 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
2091fd0
add octokit sdk client
d612d52
add github_team_org_role_assignment resource
0942afc
add tests for github_team_org_role_assignment
dddd5f6
formatting
e304177
use go-github for listing all team role assignments for a role
1004bf1
implement proper import logic
df99246
add docs
1e94354
test adding .gitattributes to make vendor pr changes not slow down th…
73bacd9
test adding .gitattributes to make vendor pr changes not slow down th…
2b91eca
test adding .gitattributes to make vendor pr changes not slow down th…
826d49a
remove .gitattributes, seems like it had no effect
5442846
add break iteration over teams assigned to organization role
4653863
Merge remote-tracking branch 'origin/main' into github_team_organizat…
felixlut 02b0cca
org role team assignment no longer use go-sdk
felixlut a13f0b2
purge go-sdk completely
felixlut 4f55b6c
Merge branch 'main' into github_team_organization_role_assignment
felixlut 7ceddb7
support either role_name or role_id
felixlut 525de6a
update docs
felixlut 8135e6b
resources should follow convention from gh api (org role before team)
felixlut 805e6ca
update docs
felixlut 9caf4b4
finalize the renaming
felixlut 28c69ef
fix importer
felixlut 87ef13d
go back to only allowing github_slug and role_id
felixlut e9a1721
linting fix
felixlut 4d732e7
revert go.mod changes
felixlut 1dfba89
Merge branch 'main' into github_team_organization_role_assignment
nickfloyd 79c14f4
Merge branch 'main' into github_team_organization_role_assignment
nickfloyd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
197 changes: 197 additions & 0 deletions
197
github/resource_github_team_organization_role_assignment.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,197 @@ | ||
| package github | ||
|
|
||
| import ( | ||
| "context" | ||
| "log" | ||
| "strconv" | ||
|
|
||
| "github.com/google/go-github/v62/github" | ||
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
| abs "github.com/microsoft/kiota-abstractions-go" | ||
| ) | ||
|
|
||
| func resourceGithubTeamOrganizationRoleAssignment() *schema.Resource { | ||
| return &schema.Resource{ | ||
| Create: resourceGithubTeamOrganizationRoleAssignmentCreate, | ||
| Read: resourceGithubTeamOrganizationRoleAssignmentRead, | ||
| Delete: resourceGithubTeamOrganizationRoleAssignmentDelete, | ||
| Importer: &schema.ResourceImporter{ | ||
| State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { | ||
| teamIdString, roleID, err := parseTwoPartID(d.Id(), "team_id", "role_id") | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| teamSlug, err := getTeamSlug(teamIdString, meta) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| d.SetId(buildTwoPartID(teamSlug, roleID)) | ||
| return []*schema.ResourceData{d}, nil | ||
| }, | ||
| }, | ||
|
|
||
| Schema: map[string]*schema.Schema{ | ||
| "team_id": { | ||
| Type: schema.TypeString, | ||
| Required: true, | ||
| Description: "The GitHub team id or the GitHub team slug.", | ||
| ForceNew: true, | ||
| }, | ||
| "role_id": { | ||
| Type: schema.TypeString, | ||
| Required: true, | ||
| Description: "The GitHub Organization Role id.", | ||
| ForceNew: true, | ||
| }, | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| func newOctokitClientDefaultRequestConfig() *abs.RequestConfiguration[abs.DefaultQueryParameters] { | ||
| headers := abs.NewRequestHeaders() | ||
| _ = headers.TryAdd("Accept", "application/vnd.github.v3+json") | ||
| _ = headers.TryAdd("X-GitHub-Api-Version", "2022-11-28") | ||
|
|
||
| return &abs.RequestConfiguration[abs.DefaultQueryParameters]{ | ||
| QueryParameters: &abs.DefaultQueryParameters{}, | ||
| Headers: headers, | ||
| } | ||
| } | ||
|
|
||
| func resourceGithubTeamOrganizationRoleAssignmentCreate(d *schema.ResourceData, meta interface{}) error { | ||
| err := checkOrganization(meta) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| octokitClient := meta.(*Owner).octokitClient | ||
|
|
||
| orgName := meta.(*Owner).name | ||
| ctx := context.Background() | ||
|
|
||
| // The given team id could be an id or a slug | ||
| givenTeamId := d.Get("team_id").(string) | ||
| teamSlug, err := getTeamSlug(givenTeamId, meta) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| roleIDString := d.Get("role_id").(string) | ||
| roleID, err := strconv.ParseInt(roleIDString, 10, 32) | ||
|
|
||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| defaultRequestConfig := newOctokitClientDefaultRequestConfig() | ||
| err = octokitClient.Orgs().ByOrg(orgName).OrganizationRoles().Teams().ByTeam_slug(teamSlug).ByRole_id(int32(roleID)).Put(ctx, defaultRequestConfig) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| d.SetId(buildTwoPartID(teamSlug, roleIDString)) | ||
| return resourceGithubTeamOrganizationRoleAssignmentRead(d, meta) | ||
| } | ||
|
|
||
| func resourceGithubTeamOrganizationRoleAssignmentRead(d *schema.ResourceData, meta interface{}) error { | ||
| err := checkOrganization(meta) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| restClient := meta.(*Owner).v3client | ||
|
|
||
| ctx := context.Background() | ||
| orgName := meta.(*Owner).name | ||
|
|
||
| teamIdString, roleIDString, err := parseTwoPartID(d.Id(), "team_id", "role_id") | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // The given team id could be an id or a slug | ||
| teamSlug, err := getTeamSlug(teamIdString, meta) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| roleID, err := strconv.ParseInt(roleIDString, 10, 32) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // There is no api for checking a specific team role assignment, so instead we iterate over all teams assigned to the role | ||
| // go-github pagination (https://github.com/google/go-github?tab=readme-ov-file#pagination) | ||
felixlut marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| options := &github.ListOptions{ | ||
| PerPage: 100, | ||
| } | ||
| var foundTeam *github.Team | ||
| for { | ||
| teams, resp, err := restClient.Organizations.ListTeamsAssignedToOrgRole(ctx, orgName, roleID, options) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| for _, team := range teams { | ||
| if team.GetSlug() == teamSlug { | ||
| foundTeam = team | ||
| } | ||
|
|
||
| } | ||
|
|
||
| if resp.NextPage == 0 { | ||
| break | ||
| } | ||
| options.Page = resp.NextPage | ||
| } | ||
|
|
||
| if foundTeam == nil { | ||
| log.Printf("[WARN] Removing team organization role association %s from state because it no longer exists in GitHub", d.Id()) | ||
| d.SetId("") | ||
| return nil | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func resourceGithubTeamOrganizationRoleAssignmentDelete(d *schema.ResourceData, meta interface{}) error { | ||
| err := checkOrganization(meta) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| octokitClient := meta.(*Owner).octokitClient | ||
|
|
||
| orgName := meta.(*Owner).name | ||
| ctx := context.Background() | ||
|
|
||
| teamIdString, roleIDString, err := parseTwoPartID(d.Id(), "team_id", "role_id") | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // The given team id could be an id or a slug | ||
| teamSlug, err := getTeamSlug(teamIdString, meta) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| roleID, err := strconv.ParseInt(roleIDString, 10, 32) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| defaultRequestConfig := newOctokitClientDefaultRequestConfig() | ||
| err = octokitClient.Orgs().ByOrg(orgName).OrganizationRoles().Teams().ByTeam_slug(teamSlug).ByRole_id(int32(roleID)).Delete(ctx, defaultRequestConfig) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.