Skip to content

Commit 3063ca4

Browse files
authored
[MAINT] Fix test of Org Repo Roles (#3193)
* Fix missing Set of Computed field in Org Repo Role Signed-off-by: Timo Sand <[email protected]> * Ensure tests are configured correctly Signed-off-by: Timo Sand <[email protected]> * Add validation of `permissions` values Signed-off-by: Timo Sand <[email protected]> * Update to use new SDK methods Signed-off-by: Timo Sand <[email protected]> * Update DS to use new SDK methods Signed-off-by: Timo Sand <[email protected]> * Remove unnecessary `d.Set("role_id")` Signed-off-by: Timo Sand <[email protected]> --------- Signed-off-by: Timo Sand <[email protected]>
1 parent d3260bf commit 3063ca4

4 files changed

Lines changed: 98 additions & 51 deletions

github/data_source_github_organization_repository_role.go

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ package github
22

33
import (
44
"context"
5-
"fmt"
65
"strconv"
76

8-
"github.com/google/go-github/v82/github"
97
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
108
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
119
)
@@ -53,28 +51,11 @@ func dataSourceGithubOrganizationRepositoryRoleRead(ctx context.Context, d *sche
5351

5452
roleId := int64(d.Get("role_id").(int))
5553

56-
// TODO: Use this code when go-github is at v68+
57-
// role, _, err := client.Organizations.GetCustomRepoRole(ctx, orgName, roleId)
58-
// if err != nil {
59-
// return diag.FromErr(err)
60-
// }
61-
62-
roles, _, err := client.Organizations.ListCustomRepoRoles(ctx, orgName)
54+
role, _, err := client.Organizations.GetCustomRepoRole(ctx, orgName, roleId)
6355
if err != nil {
6456
return diag.FromErr(err)
6557
}
6658

67-
var role *github.CustomRepoRoles
68-
for _, r := range roles.CustomRepoRoles {
69-
if r.GetID() == roleId {
70-
role = r
71-
break
72-
}
73-
}
74-
if role == nil {
75-
return diag.FromErr(fmt.Errorf("custom organization repo role with ID %d not found", roleId))
76-
}
77-
7859
r := map[string]any{
7960
"role_id": role.GetID(),
8061
"name": role.GetName(),

github/data_source_github_organization_repository_role_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
func TestAccGithubOrganizationRepositoryRoleDataSource(t *testing.T) {
1212
t.Run("queries an organization repository role", func(t *testing.T) {
1313
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
14-
roleName := fmt.Sprintf(`tf-acc-test-%s`, randomID)
14+
roleName := fmt.Sprintf(`%s%s`, testResourcePrefix, randomID)
1515

1616
config := fmt.Sprintf(`
1717
resource "github_organization_repository_role" "test" {

github/resource_github_organization_repository_role.go

Lines changed: 94 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ package github
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
6-
"log"
7+
"net/http"
8+
"slices"
79
"strconv"
810

911
"github.com/google/go-github/v82/github"
12+
"github.com/hashicorp/terraform-plugin-log/tflog"
1013
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1114
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1215
)
@@ -53,6 +56,8 @@ func resourceGithubOrganizationRepositoryRole() *schema.Resource {
5356
MinItems: 1,
5457
},
5558
},
59+
60+
CustomizeDiff: resourceGithubOrganizationRepositoryRoleCustomizeDiff,
5661
}
5762
}
5863

@@ -81,6 +86,10 @@ func resourceGithubOrganizationRepositoryRoleCreate(ctx context.Context, d *sche
8186
return diag.FromErr(fmt.Errorf("error creating GitHub organization repository role (%s/%s): %w", orgName, d.Get("name").(string), err))
8287
}
8388

89+
if err = d.Set("role_id", role.GetID()); err != nil {
90+
return diag.FromErr(err)
91+
}
92+
8493
d.SetId(fmt.Sprint(role.GetID()))
8594
return nil
8695
}
@@ -99,36 +108,20 @@ func resourceGithubOrganizationRepositoryRoleRead(ctx context.Context, d *schema
99108
return diag.FromErr(err)
100109
}
101110

102-
// TODO: Use this code when go-github is v68+
103-
// role, _, err := client.Organizations.GetCustomRepoRole(ctx, orgName, roleId)
104-
// if err != nil {
105-
// if ghErr, ok := err.(*github.ErrorResponse); ok {
106-
// if ghErr.Response.StatusCode == http.StatusNotFound {
107-
// log.Printf("[WARN] GitHub organization repository role (%s/%d) not found, removing from state", orgName, roleId)
108-
// d.SetId("")
109-
// return nil
110-
// }
111-
// }
112-
// return err
113-
// }
114-
115-
roles, _, err := client.Organizations.ListCustomRepoRoles(ctx, orgName)
111+
role, _, err := client.Organizations.GetCustomRepoRole(ctx, orgName, roleId)
116112
if err != nil {
117-
return diag.FromErr(err)
118-
}
119-
120-
var role *github.CustomRepoRoles
121-
for _, r := range roles.CustomRepoRoles {
122-
if r.GetID() == roleId {
123-
role = r
124-
break
113+
var ghErr *github.ErrorResponse
114+
if errors.As(err, &ghErr) {
115+
if ghErr.Response.StatusCode == http.StatusNotFound {
116+
tflog.Warn(ctx, "GitHub organization repository role not found, removing from state", map[string]any{
117+
"orgName": orgName,
118+
"roleId": roleId,
119+
})
120+
d.SetId("")
121+
return nil
122+
}
125123
}
126-
}
127-
128-
if role == nil {
129-
log.Printf("[WARN] GitHub organization repository role (%s/%d) not found, removing from state", orgName, roleId)
130-
d.SetId("")
131-
return nil
124+
return diag.FromErr(err)
132125
}
133126

134127
if err = d.Set("role_id", role.GetID()); err != nil {
@@ -206,3 +199,75 @@ func resourceGithubOrganizationRepositoryRoleDelete(ctx context.Context, d *sche
206199

207200
return nil
208201
}
202+
203+
// Snapshot of the response to https://docs.github.com/en/enterprise-cloud@latest/rest/orgs/custom-roles?apiVersion=2022-11-28#list-repository-fine-grained-permissions-for-an-organization
204+
// The endpoint isn't covered in the SDK yet.
205+
var validRolePermissions = []string{
206+
"add_assignee",
207+
"add_label",
208+
"bypass_branch_protection",
209+
"close_discussion",
210+
"close_issue",
211+
"close_pull_request",
212+
"convert_issues_to_discussions",
213+
"create_discussion_category",
214+
"create_solo_merge_queue_entry",
215+
"create_tag",
216+
"delete_alerts_code_scanning",
217+
"delete_discussion",
218+
"delete_discussion_comment",
219+
"delete_issue",
220+
"delete_tag",
221+
"edit_category_on_discussion",
222+
"edit_discussion_category",
223+
"edit_discussion_comment",
224+
"edit_repo_custom_properties_values",
225+
"edit_repo_metadata",
226+
"edit_repo_protections",
227+
"jump_merge_queue",
228+
"manage_deploy_keys",
229+
"manage_settings_merge_types",
230+
"manage_settings_pages",
231+
"manage_settings_projects",
232+
"manage_settings_wiki",
233+
"manage_webhooks",
234+
"mark_as_duplicate",
235+
"push_protected_branch",
236+
"read_code_quality",
237+
"read_code_scanning",
238+
"reopen_discussion",
239+
"reopen_issue",
240+
"reopen_pull_request",
241+
"request_pr_review",
242+
"resolve_dependabot_alerts",
243+
"resolve_secret_scanning_alerts",
244+
"set_interaction_limits",
245+
"set_issue_type",
246+
"set_milestone",
247+
"set_social_preview",
248+
"toggle_discussion_answer",
249+
"toggle_discussion_comment_minimize",
250+
"view_dependabot_alerts",
251+
"view_secret_scanning_alerts",
252+
"write_code_quality",
253+
"write_code_scanning",
254+
"write_repository_actions_environments",
255+
"write_repository_actions_runners",
256+
"write_repository_actions_secrets",
257+
"write_repository_actions_settings",
258+
"write_repository_actions_variables",
259+
}
260+
261+
func resourceGithubOrganizationRepositoryRoleCustomizeDiff(ctx context.Context, d *schema.ResourceDiff, m any) error {
262+
tflog.Debug(ctx, "Customizing diff for GitHub organization repository role", map[string]any{"permissionsChanged": d.HasChange("permissions")})
263+
if d.HasChange("permissions") {
264+
newPermissions := d.Get("permissions").(*schema.Set).List()
265+
tflog.Debug(ctx, "Validating permissions values", map[string]any{"newPermissions": newPermissions})
266+
for _, permission := range newPermissions {
267+
if !slices.Contains(validRolePermissions, permission.(string)) {
268+
return fmt.Errorf("invalid permission: %+v", permission)
269+
}
270+
}
271+
}
272+
return nil
273+
}

github/resource_github_organization_repository_role_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func TestAccGithubOrganizationRepositoryRole(t *testing.T) {
1313
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
1414
name := fmt.Sprintf("tf-acc-org-repo-role-%s", randomID)
1515
description := "This is a test org repo role."
16-
baseRole := "write"
16+
baseRole := "read"
1717
permission0 := "reopen_issue"
1818
permission1 := "reopen_pull_request"
1919

@@ -59,6 +59,7 @@ func TestAccGithubOrganizationRepositoryRole(t *testing.T) {
5959
config := fmt.Sprintf(`
6060
resource "github_organization_repository_role" "test" {
6161
name = "%s"
62+
base_role = "read"
6263
permissions = [
6364
"%s"
6465
]

0 commit comments

Comments
 (0)