diff --git a/github/actions_permissions_orgs.go b/github/actions_permissions_orgs.go index a2efaaf59d7..88bfd87812d 100644 --- a/github/actions_permissions_orgs.go +++ b/github/actions_permissions_orgs.go @@ -34,9 +34,12 @@ type ActionsEnabledOnOrgRepos struct { // // GitHub API docs: https://docs.github.com/rest/actions/permissions?apiVersion=2022-11-28 type ActionsAllowed struct { - GithubOwnedAllowed *bool `json:"github_owned_allowed,omitempty"` - VerifiedAllowed *bool `json:"verified_allowed,omitempty"` - PatternsAllowed []string `json:"patterns_allowed,omitempty"` + GithubOwnedAllowed *bool `json:"github_owned_allowed,omitempty"` + VerifiedAllowed *bool `json:"verified_allowed,omitempty"` + // PatternsAllowed uses `omitzero` to allow an empty array to be sent in the request body in order to + // configure the organization to allow no 3rd-party actions. It needs to still omit a `nil` value so + // that it's possible to patch the other values without changing the allowed actions. + PatternsAllowed []string `json:"patterns_allowed,omitzero"` } func (a ActionsAllowed) String() string { diff --git a/github/actions_permissions_orgs_test.go b/github/actions_permissions_orgs_test.go index dc949ae04c0..b8dddddba72 100644 --- a/github/actions_permissions_orgs_test.go +++ b/github/actions_permissions_orgs_test.go @@ -252,6 +252,40 @@ func TestActionsService_GetActionsAllowed(t *testing.T) { }) } +func TestActionsService_GetActionsAllowed_emptyPatterns(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/orgs/o/actions/permissions/selected-actions", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"github_owned_allowed":true, "verified_allowed":false, "patterns_allowed":[]}`) + }) + + ctx := t.Context() + org, _, err := client.Actions.GetActionsAllowed(ctx, "o") + if err != nil { + t.Errorf("Actions.GetActionsAllowed returned error: %v", err) + } + want := &ActionsAllowed{GithubOwnedAllowed: Ptr(true), VerifiedAllowed: Ptr(false), PatternsAllowed: []string{}} + if !cmp.Equal(org, want) { + t.Errorf("Actions.GetActionsAllowed returned %+v, want %+v", org, want) + } + + const methodName = "GetActionsAllowed" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Actions.GetActionsAllowed(ctx, "\n") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Actions.GetActionsAllowed(ctx, "o") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + func TestActionsService_UpdateActionsAllowed(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -290,6 +324,78 @@ func TestActionsService_UpdateActionsAllowed(t *testing.T) { }) } +func TestActionsService_UpdateActionsAllowed_emptyPatterns(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + input := &ActionsAllowed{GithubOwnedAllowed: Ptr(true), VerifiedAllowed: Ptr(false), PatternsAllowed: []string{}} + + mux.HandleFunc("/orgs/o/actions/permissions/selected-actions", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testJSONBody(t, r, input) + fmt.Fprint(w, `{"github_owned_allowed":true, "verified_allowed":false, "patterns_allowed":[]}`) + }) + + ctx := t.Context() + org, _, err := client.Actions.UpdateActionsAllowed(ctx, "o", *input) + if err != nil { + t.Errorf("Actions.UpdateActionsAllowed returned error: %v", err) + } + + want := &ActionsAllowed{GithubOwnedAllowed: Ptr(true), VerifiedAllowed: Ptr(false), PatternsAllowed: []string{}} + if !cmp.Equal(org, want) { + t.Errorf("Actions.UpdateActionsAllowed returned %+v, want %+v", org, want) + } +} + +func TestActionsService_UpdateActionsAllowed_nilPatterns(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + input := &ActionsAllowed{GithubOwnedAllowed: Ptr(true), VerifiedAllowed: Ptr(false), PatternsAllowed: nil} + + mux.HandleFunc("/orgs/o/actions/permissions/selected-actions", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testJSONBody(t, r, input) + fmt.Fprint(w, `{"github_owned_allowed":true, "verified_allowed":false, "patterns_allowed":["a/b"]}`) + }) + + ctx := t.Context() + org, _, err := client.Actions.UpdateActionsAllowed(ctx, "o", *input) + if err != nil { + t.Errorf("Actions.UpdateActionsAllowed returned error: %v", err) + } + + want := &ActionsAllowed{GithubOwnedAllowed: Ptr(true), VerifiedAllowed: Ptr(false), PatternsAllowed: []string{"a/b"}} + if !cmp.Equal(org, want) { + t.Errorf("Actions.UpdateActionsAllowed returned %+v, want %+v", org, want) + } +} + +func TestActionsService_UpdateActionsAllowed_omittedPatterns(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + input := &ActionsAllowed{GithubOwnedAllowed: Ptr(true), VerifiedAllowed: Ptr(false)} + + mux.HandleFunc("/orgs/o/actions/permissions/selected-actions", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + testJSONBody(t, r, input) + fmt.Fprint(w, `{"github_owned_allowed":true, "verified_allowed":false, "patterns_allowed":["a/b"]}`) + }) + + ctx := t.Context() + org, _, err := client.Actions.UpdateActionsAllowed(ctx, "o", *input) + if err != nil { + t.Errorf("Actions.UpdateActionsAllowed returned error: %v", err) + } + + want := &ActionsAllowed{GithubOwnedAllowed: Ptr(true), VerifiedAllowed: Ptr(false), PatternsAllowed: []string{"a/b"}} + if !cmp.Equal(org, want) { + t.Errorf("Actions.UpdateActionsAllowed returned %+v, want %+v", org, want) + } +} + func TestActionsService_GetDefaultWorkflowPermissionsInOrganization(t *testing.T) { t.Parallel() client, mux, _ := setup(t)