From 666abf77b2e340ef3b35a71c9ebd465b0ce456dc Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Thu, 5 Feb 2026 20:57:23 +0200 Subject: [PATCH 1/4] fix!: Pass `UpdateHostedRunnerRequest` to `UpdateHostedRunner` --- github/actions_hosted_runners.go | 37 +++++-------- github/actions_hosted_runners_test.go | 53 +++---------------- github/enterprise_actions_hosted_runners.go | 8 +-- .../enterprise_actions_hosted_runners_test.go | 53 +++---------------- 4 files changed, 28 insertions(+), 123 deletions(-) diff --git a/github/actions_hosted_runners.go b/github/actions_hosted_runners.go index 207b755fc30..aff81d14bd4 100644 --- a/github/actions_hosted_runners.go +++ b/github/actions_hosted_runners.go @@ -83,14 +83,13 @@ func (s *ActionsService) ListHostedRunners(ctx context.Context, org string, opts } // HostedRunnerImage represents the image of GitHub-hosted runners. -// To list all available images, use GET /actions/hosted-runners/images/github-owned or GET /actions/hosted-runners/images/partner. type HostedRunnerImage struct { ID string `json:"id"` Source string `json:"source"` Version string `json:"version"` } -// HostedRunnerRequest specifies body parameters to Hosted Runner configuration. +// HostedRunnerRequest specifies body parameters to create Hosted Runner configuration. type HostedRunnerRequest struct { Name string `json:"name,omitempty"` Image HostedRunnerImage `json:"image,omitempty"` @@ -101,6 +100,17 @@ type HostedRunnerRequest struct { ImageVersion string `json:"image_version,omitempty"` } +// UpdateHostedRunnerRequest specifies body parameters to update Hosted Runner configuration. +type UpdateHostedRunnerRequest struct { + Name *string `json:"name,omitempty"` + RunnerGroupID *int64 `json:"runner_group_id,omitempty"` + MaximumRunners *int64 `json:"maximum_runners,omitempty"` + EnableStaticIP *bool `json:"enable_static_ip,omitempty"` + Size *string `json:"size,omitempty"` + ImageID *string `json:"image_id,omitempty"` + ImageVersion *string `json:"image_version,omitempty"` +} + // validateCreateHostedRunnerRequest validates the provided HostedRunnerRequest to ensure // that all required fields are properly set and that no invalid fields are present for hosted runner create request. // @@ -317,33 +327,14 @@ func (s *ActionsService) GetHostedRunner(ctx context.Context, org string, runner return hostedRunner, resp, nil } -// validateUpdateHostedRunnerRequest validates the provided HostedRunnerRequest to ensure -// that no disallowed updates are made for a hosted runner update request. -// -// If any of these conditions are violated, an appropriate error message is returned. -// Otherwise, nil is returned, indicating the request is valid for an update. -func validateUpdateHostedRunnerRequest(request *HostedRunnerRequest) error { - if request.Size != "" { - return errors.New("size cannot be updated, API does not support updating size") - } - if request.Image != (HostedRunnerImage{}) { - return errors.New("image struct should not be set directly; use the ImageVersion to specify version details") - } - return nil -} - // UpdateHostedRunner updates a GitHub-hosted runner for an organization. // // GitHub API docs: https://docs.github.com/rest/actions/hosted-runners#update-a-github-hosted-runner-for-an-organization // //meta:operation PATCH /orgs/{org}/actions/hosted-runners/{hosted_runner_id} -func (s *ActionsService) UpdateHostedRunner(ctx context.Context, org string, runnerID int64, updateReq HostedRunnerRequest) (*HostedRunner, *Response, error) { - if err := validateUpdateHostedRunnerRequest(&updateReq); err != nil { - return nil, nil, fmt.Errorf("validation failed: %w", err) - } - +func (s *ActionsService) UpdateHostedRunner(ctx context.Context, org string, runnerID int64, request UpdateHostedRunnerRequest) (*HostedRunner, *Response, error) { u := fmt.Sprintf("orgs/%v/actions/hosted-runners/%v", org, runnerID) - req, err := s.client.NewRequest("PATCH", u, updateReq) + req, err := s.client.NewRequest("PATCH", u, request) if err != nil { return nil, nil, err } diff --git a/github/actions_hosted_runners_test.go b/github/actions_hosted_runners_test.go index 2f5f62ea27d..234c52a9d79 100644 --- a/github/actions_hosted_runners_test.go +++ b/github/actions_hosted_runners_test.go @@ -731,12 +731,12 @@ func TestActionsService_UpdateHostedRunner(t *testing.T) { }) ctx := t.Context() - validReq := HostedRunnerRequest{ - Name: "My larger runner", - RunnerGroupID: 1, - MaximumRunners: 50, - EnableStaticIP: false, - ImageVersion: "1.0.0", + validReq := UpdateHostedRunnerRequest{ + Name: Ptr("My larger runner"), + RunnerGroupID: Ptr(int64(1)), + MaximumRunners: Ptr(int64(50)), + EnableStaticIP: Ptr(false), + ImageVersion: Ptr("1.0.0"), } hostedRunner, _, err := client.Actions.UpdateHostedRunner(ctx, "o", 23, validReq) if err != nil { @@ -776,47 +776,6 @@ func TestActionsService_UpdateHostedRunner(t *testing.T) { t.Errorf("Actions.UpdateHostedRunner returned %+v, want %+v", hostedRunner, want) } - testCases := []struct { - name string - request HostedRunnerRequest - expectedError string - }{ - { - name: "Size Set in Update Request", - request: HostedRunnerRequest{ - Name: "My larger runner", - RunnerGroupID: 1, - MaximumRunners: 50, - EnableStaticIP: false, - ImageVersion: "1.0.0", - Size: "4-core", // Should cause validation error - }, - expectedError: "validation failed: size cannot be updated, API does not support updating size", - }, - { - name: "Image Set in Update Request", - request: HostedRunnerRequest{ - Name: "My larger runner", - RunnerGroupID: 1, - MaximumRunners: 50, - EnableStaticIP: false, - ImageVersion: "1.0.0", - Image: HostedRunnerImage{ // Should cause validation error - ID: "ubuntu-latest", - Source: "github", - Version: "latest", - }, - }, - expectedError: "validation failed: image struct should not be set directly; use the ImageVersion to specify version details", - }, - } - for _, tt := range testCases { - _, _, err := client.Enterprise.UpdateHostedRunner(ctx, "o", 23, tt.request) - if err == nil || err.Error() != tt.expectedError { - t.Errorf("expected error: %v, got: %v", tt.expectedError, err) - } - } - const methodName = "UpdateHostedRunner" testBadOptions(t, methodName, func() (err error) { _, _, err = client.Actions.UpdateHostedRunner(ctx, "\n", 23, validReq) diff --git a/github/enterprise_actions_hosted_runners.go b/github/enterprise_actions_hosted_runners.go index e82ba9b806f..8c28cd28e06 100644 --- a/github/enterprise_actions_hosted_runners.go +++ b/github/enterprise_actions_hosted_runners.go @@ -192,13 +192,9 @@ func (s *EnterpriseService) GetHostedRunner(ctx context.Context, enterprise stri // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/actions/hosted-runners#update-a-github-hosted-runner-for-an-enterprise // //meta:operation PATCH /enterprises/{enterprise}/actions/hosted-runners/{hosted_runner_id} -func (s *EnterpriseService) UpdateHostedRunner(ctx context.Context, enterprise string, runnerID int64, updateReq HostedRunnerRequest) (*HostedRunner, *Response, error) { - if err := validateUpdateHostedRunnerRequest(&updateReq); err != nil { - return nil, nil, fmt.Errorf("validation failed: %w", err) - } - +func (s *EnterpriseService) UpdateHostedRunner(ctx context.Context, enterprise string, runnerID int64, request UpdateHostedRunnerRequest) (*HostedRunner, *Response, error) { u := fmt.Sprintf("enterprises/%v/actions/hosted-runners/%v", enterprise, runnerID) - req, err := s.client.NewRequest("PATCH", u, updateReq) + req, err := s.client.NewRequest("PATCH", u, request) if err != nil { return nil, nil, err } diff --git a/github/enterprise_actions_hosted_runners_test.go b/github/enterprise_actions_hosted_runners_test.go index 740e41a5b6f..c6b87c9e8fb 100644 --- a/github/enterprise_actions_hosted_runners_test.go +++ b/github/enterprise_actions_hosted_runners_test.go @@ -725,12 +725,12 @@ func TestEnterpriseService_UpdateHostedRunner(t *testing.T) { // Test for a valid update without `Size` ctx := t.Context() - validReq := HostedRunnerRequest{ - Name: "My larger runner", - RunnerGroupID: 1, - MaximumRunners: 50, - EnableStaticIP: false, - ImageVersion: "1.0.0", + validReq := UpdateHostedRunnerRequest{ + Name: Ptr("My larger runner"), + RunnerGroupID: Ptr(int64(1)), + MaximumRunners: Ptr(int64(50)), + EnableStaticIP: Ptr(false), + ImageVersion: Ptr("1.0.0"), } hostedRunner, _, err := client.Enterprise.UpdateHostedRunner(ctx, "o", 23, validReq) if err != nil { @@ -770,47 +770,6 @@ func TestEnterpriseService_UpdateHostedRunner(t *testing.T) { t.Errorf("Enterprise.UpdateHostedRunner returned %+v, want %+v", hostedRunner, want) } - testCases := []struct { - name string - request HostedRunnerRequest - expectedError string - }{ - { - name: "Size Set in Update Request", - request: HostedRunnerRequest{ - Name: "My larger runner", - RunnerGroupID: 1, - MaximumRunners: 50, - EnableStaticIP: false, - ImageVersion: "1.0.0", - Size: "4-core", // Should cause validation error - }, - expectedError: "validation failed: size cannot be updated, API does not support updating size", - }, - { - name: "Image Set in Update Request", - request: HostedRunnerRequest{ - Name: "My larger runner", - RunnerGroupID: 1, - MaximumRunners: 50, - EnableStaticIP: false, - ImageVersion: "1.0.0", - Image: HostedRunnerImage{ // Should cause validation error - ID: "ubuntu-latest", - Source: "github", - Version: "latest", - }, - }, - expectedError: "validation failed: image struct should not be set directly; use the ImageVersion to specify version details", - }, - } - for _, tt := range testCases { - _, _, err := client.Enterprise.UpdateHostedRunner(ctx, "o", 23, tt.request) - if err == nil || err.Error() != tt.expectedError { - t.Errorf("expected error: %v, got: %v", tt.expectedError, err) - } - } - const methodName = "UpdateHostedRunner" testBadOptions(t, methodName, func() (err error) { _, _, err = client.Enterprise.UpdateHostedRunner(ctx, "\n", 23, validReq) From 2a1215b1a66f1f2c3b3c3f93345d7d4a8617d4cf Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Thu, 5 Feb 2026 21:21:54 +0200 Subject: [PATCH 2/4] go generate --- github/github-accessors.go | 56 ++++++++++++++++++++++++ github/github-accessors_test.go | 77 +++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) diff --git a/github/github-accessors.go b/github/github-accessors.go index 13734019d7f..783728ff359 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -30550,6 +30550,62 @@ func (u *UpdateEnterpriseRunnerGroupRequest) GetVisibility() string { return *u.Visibility } +// GetEnableStaticIP returns the EnableStaticIP field if it's non-nil, zero value otherwise. +func (u *UpdateHostedRunnerRequest) GetEnableStaticIP() bool { + if u == nil || u.EnableStaticIP == nil { + return false + } + return *u.EnableStaticIP +} + +// GetImageID returns the ImageID field if it's non-nil, zero value otherwise. +func (u *UpdateHostedRunnerRequest) GetImageID() string { + if u == nil || u.ImageID == nil { + return "" + } + return *u.ImageID +} + +// GetImageVersion returns the ImageVersion field if it's non-nil, zero value otherwise. +func (u *UpdateHostedRunnerRequest) GetImageVersion() string { + if u == nil || u.ImageVersion == nil { + return "" + } + return *u.ImageVersion +} + +// GetMaximumRunners returns the MaximumRunners field if it's non-nil, zero value otherwise. +func (u *UpdateHostedRunnerRequest) GetMaximumRunners() int64 { + if u == nil || u.MaximumRunners == nil { + return 0 + } + return *u.MaximumRunners +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (u *UpdateHostedRunnerRequest) GetName() string { + if u == nil || u.Name == nil { + return "" + } + return *u.Name +} + +// GetRunnerGroupID returns the RunnerGroupID field if it's non-nil, zero value otherwise. +func (u *UpdateHostedRunnerRequest) GetRunnerGroupID() int64 { + if u == nil || u.RunnerGroupID == nil { + return 0 + } + return *u.RunnerGroupID +} + +// GetSize returns the Size field if it's non-nil, zero value otherwise. +func (u *UpdateHostedRunnerRequest) GetSize() string { + if u == nil || u.Size == nil { + return "" + } + return *u.Size +} + // GetEncryptedValue returns the EncryptedValue field if it's non-nil, zero value otherwise. func (u *UpdateOrganizationPrivateRegistry) GetEncryptedValue() string { if u == nil || u.EncryptedValue == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 5e4aeaff606..6709b63d8bc 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -39398,6 +39398,83 @@ func TestUpdateEnterpriseRunnerGroupRequest_GetVisibility(tt *testing.T) { u.GetVisibility() } +func TestUpdateHostedRunnerRequest_GetEnableStaticIP(tt *testing.T) { + tt.Parallel() + var zeroValue bool + u := &UpdateHostedRunnerRequest{EnableStaticIP: &zeroValue} + u.GetEnableStaticIP() + u = &UpdateHostedRunnerRequest{} + u.GetEnableStaticIP() + u = nil + u.GetEnableStaticIP() +} + +func TestUpdateHostedRunnerRequest_GetImageID(tt *testing.T) { + tt.Parallel() + var zeroValue string + u := &UpdateHostedRunnerRequest{ImageID: &zeroValue} + u.GetImageID() + u = &UpdateHostedRunnerRequest{} + u.GetImageID() + u = nil + u.GetImageID() +} + +func TestUpdateHostedRunnerRequest_GetImageVersion(tt *testing.T) { + tt.Parallel() + var zeroValue string + u := &UpdateHostedRunnerRequest{ImageVersion: &zeroValue} + u.GetImageVersion() + u = &UpdateHostedRunnerRequest{} + u.GetImageVersion() + u = nil + u.GetImageVersion() +} + +func TestUpdateHostedRunnerRequest_GetMaximumRunners(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + u := &UpdateHostedRunnerRequest{MaximumRunners: &zeroValue} + u.GetMaximumRunners() + u = &UpdateHostedRunnerRequest{} + u.GetMaximumRunners() + u = nil + u.GetMaximumRunners() +} + +func TestUpdateHostedRunnerRequest_GetName(tt *testing.T) { + tt.Parallel() + var zeroValue string + u := &UpdateHostedRunnerRequest{Name: &zeroValue} + u.GetName() + u = &UpdateHostedRunnerRequest{} + u.GetName() + u = nil + u.GetName() +} + +func TestUpdateHostedRunnerRequest_GetRunnerGroupID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + u := &UpdateHostedRunnerRequest{RunnerGroupID: &zeroValue} + u.GetRunnerGroupID() + u = &UpdateHostedRunnerRequest{} + u.GetRunnerGroupID() + u = nil + u.GetRunnerGroupID() +} + +func TestUpdateHostedRunnerRequest_GetSize(tt *testing.T) { + tt.Parallel() + var zeroValue string + u := &UpdateHostedRunnerRequest{Size: &zeroValue} + u.GetSize() + u = &UpdateHostedRunnerRequest{} + u.GetSize() + u = nil + u.GetSize() +} + func TestUpdateOrganizationPrivateRegistry_GetEncryptedValue(tt *testing.T) { tt.Parallel() var zeroValue string From d8f9d077b2346e96251b347b443a994106eee223 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Fri, 6 Feb 2026 14:05:00 +0200 Subject: [PATCH 3/4] update CreateHostedRunner --- .golangci.yml | 9 +--- github/actions_hosted_runners.go | 49 +++++++++---------- github/actions_hosted_runners_test.go | 47 +++++------------- github/enterprise_actions_hosted_runners.go | 4 +- .../enterprise_actions_hosted_runners_test.go | 42 +++++----------- github/github-accessors.go | 32 ++++++++++++ github/github-accessors_test.go | 44 +++++++++++++++++ 7 files changed, 128 insertions(+), 99 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index f52016332d2..80bd856ccfb 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -146,7 +146,7 @@ linters: - "all" - "-QF1008" # allow embedded field in selector unparam: - check-exported: true + check-exported: true usetesting: context-background: true context-todo: true @@ -275,13 +275,6 @@ linters: - ErrorResponse.DocumentationURL # TODO: Common - GetCodeownersErrorsOptions.Ref # TODO: Repositories - GistListOptions.Since # TODO: Gists - - HostedRunnerRequest.EnableStaticIP # TODO: Actions - - HostedRunnerRequest.Image # TODO: Actions - - HostedRunnerRequest.ImageVersion # TODO: Actions - - HostedRunnerRequest.MaximumRunners # TODO: Actions - - HostedRunnerRequest.Name # TODO: Actions - - HostedRunnerRequest.RunnerGroupID # TODO: Actions - - HostedRunnerRequest.Size # TODO: Actions - IssueEvent.Action # TODO: Issues - IssueListByRepoOptions.Assignee # TODO: Issues - IssueListByRepoOptions.Assignee # TODO: Issues diff --git a/github/actions_hosted_runners.go b/github/actions_hosted_runners.go index aff81d14bd4..2c674c72fd0 100644 --- a/github/actions_hosted_runners.go +++ b/github/actions_hosted_runners.go @@ -84,20 +84,23 @@ func (s *ActionsService) ListHostedRunners(ctx context.Context, org string, opts // HostedRunnerImage represents the image of GitHub-hosted runners. type HostedRunnerImage struct { - ID string `json:"id"` - Source string `json:"source"` - Version string `json:"version"` + // The unique identifier of the runner image. + ID string `json:"id"` + // The source of the runner image. Can be one of: github, partner, custom. + Source string `json:"source"` + // The version of the runner image to deploy. This is relevant only for runners using custom images. + Version *string `json:"version"` } -// HostedRunnerRequest specifies body parameters to create Hosted Runner configuration. -type HostedRunnerRequest struct { - Name string `json:"name,omitempty"` - Image HostedRunnerImage `json:"image,omitempty"` - RunnerGroupID int64 `json:"runner_group_id,omitempty"` - Size string `json:"size,omitempty"` - MaximumRunners int64 `json:"maximum_runners,omitempty"` - EnableStaticIP bool `json:"enable_static_ip,omitempty"` - ImageVersion string `json:"image_version,omitempty"` +// CreateHostedRunnerRequest specifies body parameters to create Hosted Runner configuration. +type CreateHostedRunnerRequest struct { + Name string `json:"name"` + Image HostedRunnerImage `json:"image"` + Size string `json:"size"` + RunnerGroupID int64 `json:"runner_group_id"` + MaximumRunners *int64 `json:"maximum_runners,omitempty"` + EnableStaticIP *bool `json:"enable_static_ip,omitempty"` + ImageGen *bool `json:"image_gen,omitempty"` } // UpdateHostedRunnerRequest specifies body parameters to update Hosted Runner configuration. @@ -111,30 +114,24 @@ type UpdateHostedRunnerRequest struct { ImageVersion *string `json:"image_version,omitempty"` } -// validateCreateHostedRunnerRequest validates the provided HostedRunnerRequest to ensure +// validateCreateHostedRunnerRequest validates the provided CreateHostedRunnerRequest to ensure // that all required fields are properly set and that no invalid fields are present for hosted runner create request. // // If any of these conditions are violated, an appropriate error message is returned. // Otherwise, nil is returned, indicating the request is valid. -func validateCreateHostedRunnerRequest(request *HostedRunnerRequest) error { - if request == nil { - return errors.New("request is required for creating a hosted runner") - } - if request.Size == "" { - return errors.New("size is required for creating a hosted runner") +func validateCreateHostedRunnerRequest(request *CreateHostedRunnerRequest) error { + if request.Name == "" { + return errors.New("name is required for creating a hosted runner") } if request.Image == (HostedRunnerImage{}) { return errors.New("image is required for creating a hosted runner") } - if request.Name == "" { - return errors.New("name is required for creating a hosted runner") + if request.Size == "" { + return errors.New("size is required for creating a hosted runner") } if request.RunnerGroupID == 0 { return errors.New("runner group ID is required for creating a hosted runner") } - if request.ImageVersion != "" { - return errors.New("imageVersion should not be set directly; use the Image struct to specify image details") - } return nil } @@ -143,8 +140,8 @@ func validateCreateHostedRunnerRequest(request *HostedRunnerRequest) error { // GitHub API docs: https://docs.github.com/rest/actions/hosted-runners#create-a-github-hosted-runner-for-an-organization // //meta:operation POST /orgs/{org}/actions/hosted-runners -func (s *ActionsService) CreateHostedRunner(ctx context.Context, org string, request *HostedRunnerRequest) (*HostedRunner, *Response, error) { - if err := validateCreateHostedRunnerRequest(request); err != nil { +func (s *ActionsService) CreateHostedRunner(ctx context.Context, org string, request CreateHostedRunnerRequest) (*HostedRunner, *Response, error) { + if err := validateCreateHostedRunnerRequest(&request); err != nil { return nil, nil, fmt.Errorf("validation failed: %w", err) } diff --git a/github/actions_hosted_runners_test.go b/github/actions_hosted_runners_test.go index 234c52a9d79..44aa82541dc 100644 --- a/github/actions_hosted_runners_test.go +++ b/github/actions_hosted_runners_test.go @@ -192,17 +192,18 @@ func TestActionsService_CreateHostedRunner(t *testing.T) { ctx := t.Context() - validReq := &HostedRunnerRequest{ + validReq := CreateHostedRunnerRequest{ Name: "My Hosted runner", Image: HostedRunnerImage{ ID: "ubuntu-latest", Source: "github", - Version: "latest", + Version: Ptr("latest"), }, RunnerGroupID: 1, Size: "4-core", - MaximumRunners: 50, - EnableStaticIP: false, + MaximumRunners: Ptr(int64(50)), + EnableStaticIP: Ptr(false), + ImageGen: Ptr(true), } hostedRunner, _, err := client.Actions.CreateHostedRunner(ctx, "o", validReq) if err != nil { @@ -245,22 +246,17 @@ func TestActionsService_CreateHostedRunner(t *testing.T) { // Validation tests testCases := []struct { name string - request *HostedRunnerRequest + request CreateHostedRunnerRequest expectedError string }{ - { - name: "Missing Request", - request: nil, - expectedError: "validation failed: request is required for creating a hosted runner", - }, { name: "Missing Size", - request: &HostedRunnerRequest{ + request: CreateHostedRunnerRequest{ Name: "My Hosted runner", Image: HostedRunnerImage{ ID: "ubuntu-latest", Source: "github", - Version: "latest", + Version: Ptr("latest"), }, RunnerGroupID: 1, }, @@ -268,7 +264,7 @@ func TestActionsService_CreateHostedRunner(t *testing.T) { }, { name: "Missing Image", - request: &HostedRunnerRequest{ + request: CreateHostedRunnerRequest{ Name: "My Hosted runner", RunnerGroupID: 1, Size: "4-core", @@ -277,11 +273,11 @@ func TestActionsService_CreateHostedRunner(t *testing.T) { }, { name: "Missing Name", - request: &HostedRunnerRequest{ + request: CreateHostedRunnerRequest{ Image: HostedRunnerImage{ ID: "ubuntu-latest", Source: "github", - Version: "latest", + Version: Ptr("latest"), }, RunnerGroupID: 1, Size: "4-core", @@ -290,34 +286,17 @@ func TestActionsService_CreateHostedRunner(t *testing.T) { }, { name: "Missing RunnerGroupID", - request: &HostedRunnerRequest{ + request: CreateHostedRunnerRequest{ Name: "My Hosted runner", Image: HostedRunnerImage{ ID: "ubuntu-latest", Source: "github", - Version: "latest", + Version: Ptr("latest"), }, Size: "4-core", }, expectedError: "validation failed: runner group ID is required for creating a hosted runner", }, - { - name: "ImageVersion Set Instead of Image Struct", - request: &HostedRunnerRequest{ - Name: "My Hosted runner", - Image: HostedRunnerImage{ - ID: "ubuntu-latest", - Source: "github", - Version: "latest", - }, - RunnerGroupID: 1, - Size: "4-core", - ImageVersion: "1.0.0", - MaximumRunners: 50, - EnableStaticIP: false, - }, - expectedError: "validation failed: imageVersion should not be set directly; use the Image struct to specify image details", - }, } for _, tt := range testCases { diff --git a/github/enterprise_actions_hosted_runners.go b/github/enterprise_actions_hosted_runners.go index 8c28cd28e06..7465796445b 100644 --- a/github/enterprise_actions_hosted_runners.go +++ b/github/enterprise_actions_hosted_runners.go @@ -41,8 +41,8 @@ func (s *EnterpriseService) ListHostedRunners(ctx context.Context, enterprise st // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/actions/hosted-runners#create-a-github-hosted-runner-for-an-enterprise // //meta:operation POST /enterprises/{enterprise}/actions/hosted-runners -func (s *EnterpriseService) CreateHostedRunner(ctx context.Context, enterprise string, request *HostedRunnerRequest) (*HostedRunner, *Response, error) { - if err := validateCreateHostedRunnerRequest(request); err != nil { +func (s *EnterpriseService) CreateHostedRunner(ctx context.Context, enterprise string, request CreateHostedRunnerRequest) (*HostedRunner, *Response, error) { + if err := validateCreateHostedRunnerRequest(&request); err != nil { return nil, nil, fmt.Errorf("validation failed: %w", err) } diff --git a/github/enterprise_actions_hosted_runners_test.go b/github/enterprise_actions_hosted_runners_test.go index c6b87c9e8fb..0d03434f66c 100644 --- a/github/enterprise_actions_hosted_runners_test.go +++ b/github/enterprise_actions_hosted_runners_test.go @@ -191,17 +191,18 @@ func TestEnterpriseService_CreateHostedRunner(t *testing.T) { }) ctx := t.Context() - req := &HostedRunnerRequest{ + req := CreateHostedRunnerRequest{ Name: "My Hosted runner", Image: HostedRunnerImage{ ID: "ubuntu-latest", Source: "github", - Version: "latest", + Version: Ptr("latest"), }, RunnerGroupID: 1, Size: "4-core", - MaximumRunners: 50, - EnableStaticIP: false, + MaximumRunners: Ptr(int64(50)), + EnableStaticIP: Ptr(false), + ImageGen: Ptr(true), } hostedRunner, _, err := client.Enterprise.CreateHostedRunner(ctx, "o", req) if err != nil { @@ -244,17 +245,17 @@ func TestEnterpriseService_CreateHostedRunner(t *testing.T) { // Validation tests testCases := []struct { name string - request *HostedRunnerRequest + request CreateHostedRunnerRequest expectedError string }{ { name: "Missing Size", - request: &HostedRunnerRequest{ + request: CreateHostedRunnerRequest{ Name: "My Hosted runner", Image: HostedRunnerImage{ ID: "ubuntu-latest", Source: "github", - Version: "latest", + Version: Ptr("latest"), }, RunnerGroupID: 1, }, @@ -262,7 +263,7 @@ func TestEnterpriseService_CreateHostedRunner(t *testing.T) { }, { name: "Missing Image", - request: &HostedRunnerRequest{ + request: CreateHostedRunnerRequest{ Name: "My Hosted runner", RunnerGroupID: 1, Size: "4-core", @@ -271,11 +272,11 @@ func TestEnterpriseService_CreateHostedRunner(t *testing.T) { }, { name: "Missing Name", - request: &HostedRunnerRequest{ + request: CreateHostedRunnerRequest{ Image: HostedRunnerImage{ ID: "ubuntu-latest", Source: "github", - Version: "latest", + Version: Ptr("latest"), }, RunnerGroupID: 1, Size: "4-core", @@ -284,34 +285,17 @@ func TestEnterpriseService_CreateHostedRunner(t *testing.T) { }, { name: "Missing RunnerGroupID", - request: &HostedRunnerRequest{ + request: CreateHostedRunnerRequest{ Name: "My Hosted runner", Image: HostedRunnerImage{ ID: "ubuntu-latest", Source: "github", - Version: "latest", + Version: Ptr("latest"), }, Size: "4-core", }, expectedError: "validation failed: runner group ID is required for creating a hosted runner", }, - { - name: "ImageVersion Set Instead of Image Struct", - request: &HostedRunnerRequest{ - Name: "My Hosted runner", - Image: HostedRunnerImage{ - ID: "ubuntu-latest", - Source: "github", - Version: "latest", - }, - RunnerGroupID: 1, - Size: "4-core", - ImageVersion: "1.0.0", - MaximumRunners: 50, - EnableStaticIP: false, - }, - expectedError: "validation failed: imageVersion should not be set directly; use the Image struct to specify image details", - }, } for _, tt := range testCases { diff --git a/github/github-accessors.go b/github/github-accessors.go index 783728ff359..078bc7b7b40 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -6934,6 +6934,30 @@ func (c *CreateEvent) GetSender() *User { return c.Sender } +// GetEnableStaticIP returns the EnableStaticIP field if it's non-nil, zero value otherwise. +func (c *CreateHostedRunnerRequest) GetEnableStaticIP() bool { + if c == nil || c.EnableStaticIP == nil { + return false + } + return *c.EnableStaticIP +} + +// GetImageGen returns the ImageGen field if it's non-nil, zero value otherwise. +func (c *CreateHostedRunnerRequest) GetImageGen() bool { + if c == nil || c.ImageGen == nil { + return false + } + return *c.ImageGen +} + +// GetMaximumRunners returns the MaximumRunners field if it's non-nil, zero value otherwise. +func (c *CreateHostedRunnerRequest) GetMaximumRunners() int64 { + if c == nil || c.MaximumRunners == nil { + return 0 + } + return *c.MaximumRunners +} + // GetUsername returns the Username field if it's non-nil, zero value otherwise. func (c *CreateOrganizationPrivateRegistry) GetUsername() string { if c == nil || c.Username == nil { @@ -11606,6 +11630,14 @@ func (h *HostedRunner) GetStatus() string { return *h.Status } +// GetVersion returns the Version field if it's non-nil, zero value otherwise. +func (h *HostedRunnerImage) GetVersion() string { + if h == nil || h.Version == nil { + return "" + } + return *h.Version +} + // GetDisplayName returns the DisplayName field if it's non-nil, zero value otherwise. func (h *HostedRunnerImageDetail) GetDisplayName() string { if h == nil || h.DisplayName == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 6709b63d8bc..93efd460073 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -9071,6 +9071,39 @@ func TestCreateEvent_GetSender(tt *testing.T) { c.GetSender() } +func TestCreateHostedRunnerRequest_GetEnableStaticIP(tt *testing.T) { + tt.Parallel() + var zeroValue bool + c := &CreateHostedRunnerRequest{EnableStaticIP: &zeroValue} + c.GetEnableStaticIP() + c = &CreateHostedRunnerRequest{} + c.GetEnableStaticIP() + c = nil + c.GetEnableStaticIP() +} + +func TestCreateHostedRunnerRequest_GetImageGen(tt *testing.T) { + tt.Parallel() + var zeroValue bool + c := &CreateHostedRunnerRequest{ImageGen: &zeroValue} + c.GetImageGen() + c = &CreateHostedRunnerRequest{} + c.GetImageGen() + c = nil + c.GetImageGen() +} + +func TestCreateHostedRunnerRequest_GetMaximumRunners(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + c := &CreateHostedRunnerRequest{MaximumRunners: &zeroValue} + c.GetMaximumRunners() + c = &CreateHostedRunnerRequest{} + c.GetMaximumRunners() + c = nil + c.GetMaximumRunners() +} + func TestCreateOrganizationPrivateRegistry_GetUsername(tt *testing.T) { tt.Parallel() var zeroValue string @@ -15090,6 +15123,17 @@ func TestHostedRunner_GetStatus(tt *testing.T) { h.GetStatus() } +func TestHostedRunnerImage_GetVersion(tt *testing.T) { + tt.Parallel() + var zeroValue string + h := &HostedRunnerImage{Version: &zeroValue} + h.GetVersion() + h = &HostedRunnerImage{} + h.GetVersion() + h = nil + h.GetVersion() +} + func TestHostedRunnerImageDetail_GetDisplayName(tt *testing.T) { tt.Parallel() var zeroValue string From ae9b930ba2d8bbe76934d9a24c89472d551236ac Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Fri, 6 Feb 2026 14:35:03 +0200 Subject: [PATCH 4/4] add missing omitempty --- github/actions_hosted_runners.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/actions_hosted_runners.go b/github/actions_hosted_runners.go index 2c674c72fd0..eb805393ff3 100644 --- a/github/actions_hosted_runners.go +++ b/github/actions_hosted_runners.go @@ -89,7 +89,7 @@ type HostedRunnerImage struct { // The source of the runner image. Can be one of: github, partner, custom. Source string `json:"source"` // The version of the runner image to deploy. This is relevant only for runners using custom images. - Version *string `json:"version"` + Version *string `json:"version,omitempty"` } // CreateHostedRunnerRequest specifies body parameters to create Hosted Runner configuration.