Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 23 additions & 20 deletions github/resource_github_actions_organization_permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package github

import (
"context"
"errors"
"log"

"github.com/google/go-github/v88/github"
Expand Down Expand Up @@ -120,19 +119,23 @@ func resourceGithubActionsOrganizationAllowedObject(d *schema.ResourceData) *git
}

func resourceGithubActionsEnabledRepositoriesObject(d *schema.ResourceData) ([]int64, error) {
var enabled []int64

config := d.Get("enabled_repositories_config").([]any)
if len(config) == 0 || config[0] == nil {
return []int64{}, nil
}

enabled := []int64{}
if len(config) > 0 {
data := config[0].(map[string]any)
data, ok := config[0].(map[string]any)
if !ok {
return []int64{}, nil
}
switch x := data["repository_ids"].(type) {
case *schema.Set:
for _, value := range x.List() {
enabled = append(enabled, int64(value.(int)))
}
}
} else {
return nil, errors.New("the enabled_repositories_config {} block must be specified if enabled_repositories == 'selected'")
}
return enabled, nil
}
Expand All @@ -150,14 +153,20 @@ func resourceGithubActionsOrganizationPermissionsCreateOrUpdate(d *schema.Resour
return err
}

allowedActions := d.Get("allowed_actions").(string)
enabledRepositories := d.Get("enabled_repositories").(string)

actionsPermissions := github.ActionsPermissions{
AllowedActions: &allowedActions,
EnabledRepositories: &enabledRepositories,
}

allowedActions := ""
if v, ok := d.GetOk("allowed_actions"); ok && enabledRepositories != "none" {
allowedActions = v.(string)
if allowedActions != "" {
actionsPermissions.AllowedActions = &allowedActions
}
}

if v, ok := d.GetOk("sha_pinning_required"); ok {
actionsPermissions.SHAPinningRequired = new(v.(bool))
}
Expand Down Expand Up @@ -270,18 +279,12 @@ func resourceGithubActionsOrganizationPermissionsRead(d *schema.ResourceData, me
for index := range allRepos {
repoList = append(repoList, *allRepos[index].ID)
}
if allRepos != nil {
if err = d.Set("enabled_repositories_config", []any{
map[string]any{
"repository_ids": repoList,
},
}); err != nil {
return err
}
} else {
if err = d.Set("enabled_repositories_config", []any{}); err != nil {
return err
}
if err = d.Set("enabled_repositories_config", []any{
map[string]any{
"repository_ids": repoList,
},
}); err != nil {
return err
}
}

Expand Down
109 changes: 109 additions & 0 deletions github/resource_github_actions_organization_permissions_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package github

import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"testing"

"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"
)
Expand Down Expand Up @@ -239,3 +243,108 @@ func TestAccGithubActionsOrganizationPermissions(t *testing.T) {
})
})
}

func TestGithubActionsOrganizationPermissionsOmitsAllowedActionsForNone(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodPut && r.URL.Path == "/orgs/test-org/actions/permissions":
var body map[string]any
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
t.Fatalf("decoding request body: %s", err)
}
if _, ok := body["allowed_actions"]; ok {
t.Fatalf("allowed_actions should be omitted when enabled_repositories is none, got %#v", body)
}
if got := body["enabled_repositories"]; got != "none" {
t.Fatalf("enabled_repositories = %#v, want none", got)
}
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"enabled_repositories":"none","sha_pinning_required":false}`))
case r.Method == http.MethodGet && r.URL.Path == "/orgs/test-org/actions/permissions":
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"enabled_repositories":"none","sha_pinning_required":false}`))
default:
t.Fatalf("unexpected request %s %s", r.Method, r.URL.String())
}
}))
defer server.Close()

resource := resourceGithubActionsOrganizationPermissions()
data := schema.TestResourceDataRaw(t, resource.Schema, map[string]any{
"enabled_repositories": "none",
})
meta := &Owner{
name: "test-org",
IsOrganization: true,
v3client: mustGitHubClient(t, server.URL+"/"),
}

if err := resourceGithubActionsOrganizationPermissionsCreateOrUpdate(data, meta); err != nil {
t.Fatalf("creating actions organization permissions: %s", err)
}
}

func TestGithubActionsEnabledRepositoriesObjectAllowsEmptyConfig(t *testing.T) {
resource := resourceGithubActionsOrganizationPermissions()
data := schema.TestResourceDataRaw(t, resource.Schema, map[string]any{
"enabled_repositories_config": []any{nil},
})

defer func() {
if r := recover(); r != nil {
t.Fatalf("empty enabled_repositories_config should not panic: %v", r)
}
}()

ids, err := resourceGithubActionsEnabledRepositoriesObject(data)
if err != nil {
t.Fatalf("empty enabled_repositories_config returned error: %s", err)
}
if len(ids) != 0 {
t.Fatalf("repository ids = %#v, want empty", ids)
}
}

func TestGithubActionsOrganizationPermissionsReadPreservesEmptySelectedRepositories(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && r.URL.Path == "/orgs/test-org/actions/permissions":
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"enabled_repositories":"selected","allowed_actions":"local_only","sha_pinning_required":false}`))
case r.Method == http.MethodGet && r.URL.Path == "/orgs/test-org/actions/permissions/repositories":
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"total_count":0,"repositories":[]}`))
default:
t.Fatalf("unexpected request %s %s", r.Method, r.URL.String())
}
}))
defer server.Close()

resource := resourceGithubActionsOrganizationPermissions()
data := schema.TestResourceDataRaw(t, resource.Schema, map[string]any{
"allowed_actions": "local_only",
"enabled_repositories": "selected",
"enabled_repositories_config": []any{
map[string]any{"repository_ids": []any{}},
},
})
data.SetId("test-org")
meta := &Owner{
name: "test-org",
IsOrganization: true,
v3client: mustGitHubClient(t, server.URL+"/"),
}

if err := resourceGithubActionsOrganizationPermissionsRead(data, meta); err != nil {
t.Fatalf("reading actions organization permissions: %s", err)
}

config := data.Get("enabled_repositories_config").([]any)
if len(config) != 1 {
t.Fatalf("enabled_repositories_config length = %d, want 1", len(config))
}
repositoryIDs := config[0].(map[string]any)["repository_ids"].(*schema.Set)
if repositoryIDs.Len() != 0 {
t.Fatalf("repository_ids length = %d, want 0", repositoryIDs.Len())
}
}