diff --git a/github/resource_github_actions_organization_permissions.go b/github/resource_github_actions_organization_permissions.go index 9bff636de0..5babe8cf8b 100644 --- a/github/resource_github_actions_organization_permissions.go +++ b/github/resource_github_actions_organization_permissions.go @@ -3,6 +3,7 @@ package github import ( "context" "errors" + "fmt" "log" "github.com/google/go-github/v88/github" @@ -10,6 +11,12 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) +type actionsAllowedRequest struct { + GithubOwnedAllowed *bool `json:"github_owned_allowed,omitempty"` + VerifiedAllowed *bool `json:"verified_allowed,omitempty"` + PatternsAllowed []string `json:"patterns_allowed"` +} + func resourceGithubActionsOrganizationPermissions() *schema.Resource { return &schema.Resource{ Create: resourceGithubActionsOrganizationPermissionsCreateOrUpdate, @@ -86,8 +93,8 @@ func resourceGithubActionsOrganizationPermissions() *schema.Resource { } } -func resourceGithubActionsOrganizationAllowedObject(d *schema.ResourceData) *github.ActionsAllowed { - allowed := &github.ActionsAllowed{} +func resourceGithubActionsOrganizationAllowedRequest(d *schema.ResourceData) *actionsAllowedRequest { + allowed := &actionsAllowedRequest{} config := d.Get("allowed_actions_config").([]any) if len(config) > 0 { @@ -119,6 +126,18 @@ func resourceGithubActionsOrganizationAllowedObject(d *schema.ResourceData) *git return allowed } +func updateOrganizationActionsAllowed(ctx context.Context, client *github.Client, orgName string, actionsAllowed *actionsAllowedRequest) error { + u := fmt.Sprintf("orgs/%v/actions/permissions/selected-actions", orgName) + req, err := client.NewRequest(ctx, "PUT", u, actionsAllowed) + if err != nil { + return err + } + + respActionsAllowed := &github.ActionsAllowed{} + _, err = client.Do(req, respActionsAllowed) + return err +} + func resourceGithubActionsEnabledRepositoriesObject(d *schema.ResourceData) ([]int64, error) { var enabled []int64 @@ -170,13 +189,10 @@ func resourceGithubActionsOrganizationPermissionsCreateOrUpdate(d *schema.Resour } if allowedActions == "selected" { - actionsAllowedData := resourceGithubActionsOrganizationAllowedObject(d) + actionsAllowedData := resourceGithubActionsOrganizationAllowedRequest(d) if actionsAllowedData != nil { log.Printf("[DEBUG] Allowed actions config is set") - _, _, err = client.Actions.UpdateActionsAllowed(ctx, - orgName, - *actionsAllowedData) - if err != nil { + if err = updateOrganizationActionsAllowed(ctx, client, orgName, actionsAllowedData); err != nil { return err } } else { diff --git a/github/resource_github_actions_organization_permissions_test.go b/github/resource_github_actions_organization_permissions_test.go index 8aa3b9516e..714ce63409 100644 --- a/github/resource_github_actions_organization_permissions_test.go +++ b/github/resource_github_actions_organization_permissions_test.go @@ -1,9 +1,14 @@ package github import ( + "encoding/json" "fmt" + "net/http" + "net/http/httptest" "testing" + gogithub "github.com/google/go-github/v88/github" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -239,3 +244,79 @@ func TestAccGithubActionsOrganizationPermissions(t *testing.T) { }) }) } + +func TestGithubActionsOrganizationPermissionsSendsEmptyPatternsAllowed(t *testing.T) { + resource := resourceGithubActionsOrganizationPermissions() + var selectedActionsPayload map[string]any + + mux := http.NewServeMux() + mux.HandleFunc("/orgs/test-org/actions/permissions", func(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodPut: + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(`{"enabled_repositories":"all","allowed_actions":"selected","sha_pinning_required":true}`)) + case http.MethodGet: + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(`{"enabled_repositories":"all","allowed_actions":"selected","sha_pinning_required":true}`)) + default: + t.Fatalf("unexpected method %s for %s", r.Method, r.URL.Path) + } + }) + mux.HandleFunc("/orgs/test-org/actions/permissions/selected-actions", func(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodPut: + if err := json.NewDecoder(r.Body).Decode(&selectedActionsPayload); err != nil { + t.Fatalf("decode selected actions payload: %v", err) + } + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(`{"github_owned_allowed":true,"patterns_allowed":[],"verified_allowed":true}`)) + case http.MethodGet: + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(`{"github_owned_allowed":true,"patterns_allowed":[],"verified_allowed":true}`)) + default: + t.Fatalf("unexpected method %s for %s", r.Method, r.URL.Path) + } + }) + + server := httptest.NewServer(mux) + defer server.Close() + + baseURL := server.URL + "/" + client, err := gogithub.NewClient(gogithub.WithURLs(&baseURL, &baseURL)) + if err != nil { + t.Fatalf("create GitHub client: %v", err) + } + + d := schema.TestResourceDataRaw(t, resource.Schema, map[string]any{ + "allowed_actions": "selected", + "enabled_repositories": "all", + "allowed_actions_config": []any{ + map[string]any{ + "github_owned_allowed": true, + "patterns_allowed": []any{}, + "verified_allowed": true, + }, + }, + "sha_pinning_required": true, + }) + + err = resourceGithubActionsOrganizationPermissionsCreateOrUpdate(d, &Owner{ + name: "test-org", + v3client: client, + IsOrganization: true, + }) + if err != nil { + t.Fatalf("create/update actions organization permissions: %v", err) + } + + patterns, ok := selectedActionsPayload["patterns_allowed"] + if !ok { + t.Fatalf("selected actions payload omitted patterns_allowed: %#v", selectedActionsPayload) + } + if got := len(patterns.([]any)); got != 0 { + t.Fatalf("patterns_allowed length = %d, want 0", got) + } + if got := selectedActionsPayload["verified_allowed"]; got != true { + t.Fatalf("verified_allowed = %v, want true", got) + } +}