diff --git a/github/actions_runner_groups.go b/github/actions_runner_groups.go index 40da3fd5a0b..67309cd29cc 100644 --- a/github/actions_runner_groups.go +++ b/github/actions_runner_groups.go @@ -7,6 +7,7 @@ package github import ( "context" + "encoding/json" "fmt" ) @@ -59,6 +60,24 @@ type UpdateRunnerGroupRequest struct { RestrictedToWorkflows *bool `json:"restricted_to_workflows,omitempty"` SelectedWorkflows []string `json:"selected_workflows,omitempty"` NetworkConfigurationID *string `json:"network_configuration_id,omitempty"` + + // If true, the network configuration is removed by sending null. + // This takes precedence over NetworkConfigurationID. + RemoveNetworkConfiguration bool `json:"-"` +} + +// MarshalJSON implements the json.Marshaler interface. +func (r UpdateRunnerGroupRequest) MarshalJSON() ([]byte, error) { + type alias UpdateRunnerGroupRequest + if !r.RemoveNetworkConfiguration { + return json.Marshal(alias(r)) + } + return json.Marshal(&struct { + alias + NetworkConfigurationID *string `json:"network_configuration_id"` + }{ + alias: alias(r), + }) } // SetRepoAccessRunnerGroupRequest represents a request to replace the list of repositories diff --git a/github/actions_runner_groups_test.go b/github/actions_runner_groups_test.go index 820021d0bbf..203ad03ecec 100644 --- a/github/actions_runner_groups_test.go +++ b/github/actions_runner_groups_test.go @@ -6,6 +6,7 @@ package github import ( + "encoding/json" "fmt" "net/http" "testing" @@ -289,6 +290,93 @@ func TestActionsService_UpdateOrganizationRunnerGroup(t *testing.T) { }) } +func TestActionsService_UpdateOrganizationRunnerGroup_NetworkConfiguration(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + body UpdateRunnerGroupRequest + want string + }{ + { + name: "omitted", + body: UpdateRunnerGroupRequest{}, + want: `{}`, + }, + { + name: "set", + body: UpdateRunnerGroupRequest{NetworkConfigurationID: new("network-id")}, + want: `{"network_configuration_id":"network-id"}`, + }, + { + name: "empty string", + body: UpdateRunnerGroupRequest{NetworkConfigurationID: new("")}, + want: `{"network_configuration_id":""}`, + }, + { + name: "rename only", + body: UpdateRunnerGroupRequest{Name: new("renamed")}, + want: `{"name":"renamed"}`, + }, + { + name: "remove", + body: UpdateRunnerGroupRequest{RemoveNetworkConfiguration: true}, + want: `{"network_configuration_id":null}`, + }, + { + name: "remove overrides ID", + body: UpdateRunnerGroupRequest{ + NetworkConfigurationID: new("network-id"), + RemoveNetworkConfiguration: true, + }, + want: `{"network_configuration_id":null}`, + }, + { + name: "remove with other fields", + body: UpdateRunnerGroupRequest{ + Name: new("renamed"), + Visibility: new("selected"), + AllowsPublicRepositories: new(false), + RestrictedToWorkflows: new(true), + SelectedWorkflows: []string{"o/r/.github/workflows/build.yml@refs/heads/main"}, + RemoveNetworkConfiguration: true, + }, + want: `{"name":"renamed","visibility":"selected","allows_public_repositories":false,"restricted_to_workflows":true,"selected_workflows":["o/r/.github/workflows/build.yml@refs/heads/main"],"network_configuration_id":null}`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + before := Stringify(tt.body) + testJSONMarshalOnly(t, tt.body, tt.want) + testJSONMarshalOnly(t, &tt.body, tt.want) + if got := Stringify(tt.body); got != before { + t.Errorf("json.Marshal changed request to %v, want %v", got, before) + } + + var want map[string]json.RawMessage + if err := json.Unmarshal([]byte(tt.want), &want); err != nil { + t.Fatalf("json.Unmarshal returned error: %v", err) + } + + client, mux, _ := setup(t) + mux.HandleFunc("/orgs/o/actions/runner-groups/2", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + testJSONBody(t, r, want) + fmt.Fprint(w, `{"id":2}`) + }) + + if _, _, err := client.Actions.UpdateOrganizationRunnerGroup(t.Context(), "o", 2, tt.body); err != nil { + t.Fatalf("Actions.UpdateOrganizationRunnerGroup returned error: %v", err) + } + if got := Stringify(tt.body); got != before { + t.Errorf("Actions.UpdateOrganizationRunnerGroup changed request to %v, want %v", got, before) + } + }) + } +} + func TestActionsService_ListRepositoryAccessRunnerGroup(t *testing.T) { t.Parallel() client, mux, _ := setup(t) diff --git a/github/enterprise_actions_runner_groups.go b/github/enterprise_actions_runner_groups.go index 7cf75c33ae3..a42f789fd92 100644 --- a/github/enterprise_actions_runner_groups.go +++ b/github/enterprise_actions_runner_groups.go @@ -7,6 +7,7 @@ package github import ( "context" + "encoding/json" "fmt" ) @@ -65,6 +66,24 @@ type UpdateEnterpriseRunnerGroupRequest struct { RestrictedToWorkflows *bool `json:"restricted_to_workflows,omitempty"` SelectedWorkflows []string `json:"selected_workflows,omitempty"` NetworkConfigurationID *string `json:"network_configuration_id,omitempty"` + + // If true, the network configuration is removed by sending null. + // This takes precedence over NetworkConfigurationID. + RemoveNetworkConfiguration bool `json:"-"` +} + +// MarshalJSON implements the json.Marshaler interface. +func (r UpdateEnterpriseRunnerGroupRequest) MarshalJSON() ([]byte, error) { + type alias UpdateEnterpriseRunnerGroupRequest + if !r.RemoveNetworkConfiguration { + return json.Marshal(alias(r)) + } + return json.Marshal(&struct { + alias + NetworkConfigurationID *string `json:"network_configuration_id"` + }{ + alias: alias(r), + }) } // SetOrgAccessRunnerGroupRequest represents a request to replace the list of organizations diff --git a/github/enterprise_actions_runner_groups_test.go b/github/enterprise_actions_runner_groups_test.go index 92b8bfef510..16f0b30e850 100644 --- a/github/enterprise_actions_runner_groups_test.go +++ b/github/enterprise_actions_runner_groups_test.go @@ -6,6 +6,7 @@ package github import ( + "encoding/json" "fmt" "net/http" "testing" @@ -281,6 +282,93 @@ func TestEnterpriseService_UpdateEnterpriseRunnerGroup(t *testing.T) { }) } +func TestEnterpriseService_UpdateEnterpriseRunnerGroup_NetworkConfiguration(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + body UpdateEnterpriseRunnerGroupRequest + want string + }{ + { + name: "omitted", + body: UpdateEnterpriseRunnerGroupRequest{}, + want: `{}`, + }, + { + name: "set", + body: UpdateEnterpriseRunnerGroupRequest{NetworkConfigurationID: new("network-id")}, + want: `{"network_configuration_id":"network-id"}`, + }, + { + name: "empty string", + body: UpdateEnterpriseRunnerGroupRequest{NetworkConfigurationID: new("")}, + want: `{"network_configuration_id":""}`, + }, + { + name: "rename only", + body: UpdateEnterpriseRunnerGroupRequest{Name: new("renamed")}, + want: `{"name":"renamed"}`, + }, + { + name: "remove", + body: UpdateEnterpriseRunnerGroupRequest{RemoveNetworkConfiguration: true}, + want: `{"network_configuration_id":null}`, + }, + { + name: "remove overrides ID", + body: UpdateEnterpriseRunnerGroupRequest{ + NetworkConfigurationID: new("network-id"), + RemoveNetworkConfiguration: true, + }, + want: `{"network_configuration_id":null}`, + }, + { + name: "remove with other fields", + body: UpdateEnterpriseRunnerGroupRequest{ + Name: new("renamed"), + Visibility: new("selected"), + AllowsPublicRepositories: new(false), + RestrictedToWorkflows: new(true), + SelectedWorkflows: []string{"o/r/.github/workflows/build.yml@refs/heads/main"}, + RemoveNetworkConfiguration: true, + }, + want: `{"name":"renamed","visibility":"selected","allows_public_repositories":false,"restricted_to_workflows":true,"selected_workflows":["o/r/.github/workflows/build.yml@refs/heads/main"],"network_configuration_id":null}`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + before := Stringify(tt.body) + testJSONMarshalOnly(t, tt.body, tt.want) + testJSONMarshalOnly(t, &tt.body, tt.want) + if got := Stringify(tt.body); got != before { + t.Errorf("json.Marshal changed request to %v, want %v", got, before) + } + + var want map[string]json.RawMessage + if err := json.Unmarshal([]byte(tt.want), &want); err != nil { + t.Fatalf("json.Unmarshal returned error: %v", err) + } + + client, mux, _ := setup(t) + mux.HandleFunc("/enterprises/o/actions/runner-groups/2", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + testJSONBody(t, r, want) + fmt.Fprint(w, `{"id":2}`) + }) + + if _, _, err := client.Enterprise.UpdateEnterpriseRunnerGroup(t.Context(), "o", 2, tt.body); err != nil { + t.Fatalf("Enterprise.UpdateEnterpriseRunnerGroup returned error: %v", err) + } + if got := Stringify(tt.body); got != before { + t.Errorf("Enterprise.UpdateEnterpriseRunnerGroup changed request to %v, want %v", got, before) + } + }) + } +} + func TestEnterpriseService_ListOrganizationAccessRunnerGroup(t *testing.T) { t.Parallel() client, mux, _ := setup(t) diff --git a/github/github-accessors.go b/github/github-accessors.go index 50ac38eb513..7d36dd968f5 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -45094,6 +45094,14 @@ func (u *UpdateEnterpriseRunnerGroupRequest) GetNetworkConfigurationID() string return *u.NetworkConfigurationID } +// GetRemoveNetworkConfiguration returns the RemoveNetworkConfiguration field. +func (u *UpdateEnterpriseRunnerGroupRequest) GetRemoveNetworkConfiguration() bool { + if u == nil { + return false + } + return u.RemoveNetworkConfiguration +} + // GetRestrictedToWorkflows returns the RestrictedToWorkflows field if it's non-nil, zero value otherwise. func (u *UpdateEnterpriseRunnerGroupRequest) GetRestrictedToWorkflows() bool { if u == nil || u.RestrictedToWorkflows == nil { @@ -45750,6 +45758,14 @@ func (u *UpdateRunnerGroupRequest) GetNetworkConfigurationID() string { return *u.NetworkConfigurationID } +// GetRemoveNetworkConfiguration returns the RemoveNetworkConfiguration field. +func (u *UpdateRunnerGroupRequest) GetRemoveNetworkConfiguration() bool { + if u == nil { + return false + } + return u.RemoveNetworkConfiguration +} + // GetRestrictedToWorkflows returns the RestrictedToWorkflows field if it's non-nil, zero value otherwise. func (u *UpdateRunnerGroupRequest) GetRestrictedToWorkflows() bool { if u == nil || u.RestrictedToWorkflows == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 921473bf3bd..204b50a1ad7 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -56291,6 +56291,14 @@ func TestUpdateEnterpriseRunnerGroupRequest_GetNetworkConfigurationID(tt *testin u.GetNetworkConfigurationID() } +func TestUpdateEnterpriseRunnerGroupRequest_GetRemoveNetworkConfiguration(tt *testing.T) { + tt.Parallel() + u := &UpdateEnterpriseRunnerGroupRequest{} + u.GetRemoveNetworkConfiguration() + u = nil + u.GetRemoveNetworkConfiguration() +} + func TestUpdateEnterpriseRunnerGroupRequest_GetRestrictedToWorkflows(tt *testing.T) { tt.Parallel() var zeroValue bool @@ -57163,6 +57171,14 @@ func TestUpdateRunnerGroupRequest_GetNetworkConfigurationID(tt *testing.T) { u.GetNetworkConfigurationID() } +func TestUpdateRunnerGroupRequest_GetRemoveNetworkConfiguration(tt *testing.T) { + tt.Parallel() + u := &UpdateRunnerGroupRequest{} + u.GetRemoveNetworkConfiguration() + u = nil + u.GetRemoveNetworkConfiguration() +} + func TestUpdateRunnerGroupRequest_GetRestrictedToWorkflows(tt *testing.T) { tt.Parallel() var zeroValue bool