Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
58 changes: 55 additions & 3 deletions github/actions_runners.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,67 @@ func (s *ActionsService) ListRunnerApplicationDownloads(ctx context.Context, own
return rads, resp, nil
}

// GenerateJITConfigRequest specifies body parameters to GenerateJITConfig.
type GenerateJITConfigRequest struct {
Name string `json:"name"`
RunnerGroupID int `json:"runner_group_id"`
Labels []string `json:"labels"`
WorkFolder string `json:"work_folder,omitempty"`
}

// JITRunnerConfig represents encoded JIT configuration that can be used to bootstrap a self-hosted runner.
type JITRunnerConfig struct {
EncodedJITConfig *string `json:"encoded_jit_config,omitempty"`
}

// GenerateOrganizationJITConfig generate a just-in-time configuration for an organization.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-configuration-for-a-just-in-time-runner-for-an-organization
func (s *ActionsService) GenerateOrganizationJITConfig(ctx context.Context, owner string, request *GenerateJITConfigRequest) (*JITRunnerConfig, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/runners/generate-jitconfig", owner)
req, err := s.client.NewRequest("POST", u, request)
if err != nil {
return nil, nil, err
}

jitConfig := new(JITRunnerConfig)
resp, err := s.client.Do(ctx, req, jitConfig)
if err != nil {
return nil, resp, err
}

return jitConfig, resp, nil
}

// GenerateJITConfig generates a just-in-time configuration for a repository.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-configuration-for-a-just-in-time-runner-for-a-repository
func (s *ActionsService) GenerateJITConfig(ctx context.Context, owner, repo string, request *GenerateJITConfigRequest) (*JITRunnerConfig, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runners/generate-jitconfig", owner, repo)
req, err := s.client.NewRequest("POST", u, request)
if err != nil {
return nil, nil, err
}

jitConfig := new(JITRunnerConfig)
resp, err := s.client.Do(ctx, req, jitConfig)
if err != nil {
return nil, resp, err
}

return jitConfig, resp, nil
}

// CreateRegistrationToken creates a token that can be used to add a self-hosted runner.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/self-hosted-runners#create-a-registration-token-for-a-repository

// RegistrationToken represents a token that can be used to add a self-hosted runner to a repository.
type RegistrationToken struct {
Token *string `json:"token,omitempty"`
ExpiresAt *Timestamp `json:"expires_at,omitempty"`
}

// CreateRegistrationToken creates a token that can be used to add a self-hosted runner.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/self-hosted-runners#create-a-registration-token-for-a-repository
func (s *ActionsService) CreateRegistrationToken(ctx context.Context, owner, repo string) (*RegistrationToken, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runners/registration-token", owner, repo)

Expand Down
89 changes: 89 additions & 0 deletions github/actions_runners_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package github

import (
"context"
"encoding/json"
"fmt"
"net/http"
"testing"
Expand Down Expand Up @@ -56,6 +57,94 @@ func TestActionsService_ListRunnerApplicationDownloads(t *testing.T) {
})
}

func TestActionsService_GenerateOrganizationJITConfig(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

input := &GenerateJITConfigRequest{Name: "test", RunnerGroupID: 1, Labels: []string{"one", "two"}}

mux.HandleFunc("/orgs/o/actions/runners/generate-jitconfig", func(w http.ResponseWriter, r *http.Request) {
v := new(GenerateJITConfigRequest)
json.NewDecoder(r.Body).Decode(v)

testMethod(t, r, "POST")
if !cmp.Equal(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}

fmt.Fprint(w, `{"encoded_jit_config":"foo"}`)
})

ctx := context.Background()
jitConfig, _, err := client.Actions.GenerateOrganizationJITConfig(ctx, "o", input)
if err != nil {
t.Errorf("Actions.GenerateOrganizationJITConfig returned error: %v", err)
}

want := &JITRunnerConfig{EncodedJITConfig: String("foo")}
if !cmp.Equal(jitConfig, want) {
t.Errorf("Actions.GenerateOrganizationJITConfig returned %+v, want %+v", jitConfig, want)
}

const methodName = "GenerateOrganizationJITConfig"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Actions.GenerateOrganizationJITConfig(ctx, "\n", input)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.Actions.GenerateOrganizationJITConfig(ctx, "o", input)
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

func TestActionsService_GenerateJITConfig(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

input := &GenerateJITConfigRequest{Name: "test", RunnerGroupID: 1, Labels: []string{"one", "two"}}

mux.HandleFunc("/repos/o/r/actions/runners/generate-jitconfig", func(w http.ResponseWriter, r *http.Request) {
v := new(GenerateJITConfigRequest)
json.NewDecoder(r.Body).Decode(v)

testMethod(t, r, "POST")
if !cmp.Equal(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}

fmt.Fprint(w, `{"encoded_jit_config":"foo"}`)
})

ctx := context.Background()
jitConfig, _, err := client.Actions.GenerateJITConfig(ctx, "o", "r", input)
if err != nil {
t.Errorf("Actions.GenerateJITConfig returned error: %v", err)
}

want := &JITRunnerConfig{EncodedJITConfig: String("foo")}
if !cmp.Equal(jitConfig, want) {
t.Errorf("Actions.GenerateJITConfig returned %+v, want %+v", jitConfig, want)
}

const methodName = "GenerateJITConfig"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Actions.GenerateJITConfig(ctx, "\n", "\n", input)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.Actions.GenerateJITConfig(ctx, "o", "r", input)
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

func TestActionsService_CreateRegistrationToken(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()
Expand Down