Skip to content

Commit 4f74d0c

Browse files
authored
Add generate-jitconfig API for self-hosted runners (#2801)
1 parent b2ae94a commit 4f74d0c

File tree

4 files changed

+179
-0
lines changed

4 files changed

+179
-0
lines changed

github/actions_runners.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,60 @@ func (s *ActionsService) ListRunnerApplicationDownloads(ctx context.Context, own
4545
return rads, resp, nil
4646
}
4747

48+
// GenerateJITConfigRequest specifies body parameters to GenerateRepoJITConfig.
49+
type GenerateJITConfigRequest struct {
50+
Name string `json:"name"`
51+
RunnerGroupID int64 `json:"runner_group_id"`
52+
WorkFolder *string `json:"work_folder,omitempty"`
53+
54+
// Labels represents the names of the custom labels to add to the runner.
55+
// Minimum items: 1. Maximum items: 100.
56+
Labels []string `json:"labels"`
57+
}
58+
59+
// JITRunnerConfig represents encoded JIT configuration that can be used to bootstrap a self-hosted runner.
60+
type JITRunnerConfig struct {
61+
EncodedJITConfig *string `json:"encoded_jit_config,omitempty"`
62+
}
63+
64+
// GenerateOrgJITConfig generate a just-in-time configuration for an organization.
65+
//
66+
// 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
67+
func (s *ActionsService) GenerateOrgJITConfig(ctx context.Context, owner string, request *GenerateJITConfigRequest) (*JITRunnerConfig, *Response, error) {
68+
u := fmt.Sprintf("orgs/%v/actions/runners/generate-jitconfig", owner)
69+
req, err := s.client.NewRequest("POST", u, request)
70+
if err != nil {
71+
return nil, nil, err
72+
}
73+
74+
jitConfig := new(JITRunnerConfig)
75+
resp, err := s.client.Do(ctx, req, jitConfig)
76+
if err != nil {
77+
return nil, resp, err
78+
}
79+
80+
return jitConfig, resp, nil
81+
}
82+
83+
// GenerateRepoJITConfig generates a just-in-time configuration for a repository.
84+
//
85+
// 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
86+
func (s *ActionsService) GenerateRepoJITConfig(ctx context.Context, owner, repo string, request *GenerateJITConfigRequest) (*JITRunnerConfig, *Response, error) {
87+
u := fmt.Sprintf("repos/%v/%v/actions/runners/generate-jitconfig", owner, repo)
88+
req, err := s.client.NewRequest("POST", u, request)
89+
if err != nil {
90+
return nil, nil, err
91+
}
92+
93+
jitConfig := new(JITRunnerConfig)
94+
resp, err := s.client.Do(ctx, req, jitConfig)
95+
if err != nil {
96+
return nil, resp, err
97+
}
98+
99+
return jitConfig, resp, nil
100+
}
101+
48102
// RegistrationToken represents a token that can be used to add a self-hosted runner to a repository.
49103
type RegistrationToken struct {
50104
Token *string `json:"token,omitempty"`

github/actions_runners_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package github
77

88
import (
99
"context"
10+
"encoding/json"
1011
"fmt"
1112
"net/http"
1213
"testing"
@@ -56,6 +57,94 @@ func TestActionsService_ListRunnerApplicationDownloads(t *testing.T) {
5657
})
5758
}
5859

60+
func TestActionsService_GenerateOrgJITConfig(t *testing.T) {
61+
client, mux, _, teardown := setup()
62+
defer teardown()
63+
64+
input := &GenerateJITConfigRequest{Name: "test", RunnerGroupID: 1, Labels: []string{"one", "two"}}
65+
66+
mux.HandleFunc("/orgs/o/actions/runners/generate-jitconfig", func(w http.ResponseWriter, r *http.Request) {
67+
v := new(GenerateJITConfigRequest)
68+
json.NewDecoder(r.Body).Decode(v)
69+
70+
testMethod(t, r, "POST")
71+
if !cmp.Equal(v, input) {
72+
t.Errorf("Request body = %+v, want %+v", v, input)
73+
}
74+
75+
fmt.Fprint(w, `{"encoded_jit_config":"foo"}`)
76+
})
77+
78+
ctx := context.Background()
79+
jitConfig, _, err := client.Actions.GenerateOrgJITConfig(ctx, "o", input)
80+
if err != nil {
81+
t.Errorf("Actions.GenerateOrgJITConfig returned error: %v", err)
82+
}
83+
84+
want := &JITRunnerConfig{EncodedJITConfig: String("foo")}
85+
if !cmp.Equal(jitConfig, want) {
86+
t.Errorf("Actions.GenerateOrgJITConfig returned %+v, want %+v", jitConfig, want)
87+
}
88+
89+
const methodName = "GenerateOrgJITConfig"
90+
testBadOptions(t, methodName, func() (err error) {
91+
_, _, err = client.Actions.GenerateOrgJITConfig(ctx, "\n", input)
92+
return err
93+
})
94+
95+
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
96+
got, resp, err := client.Actions.GenerateOrgJITConfig(ctx, "o", input)
97+
if got != nil {
98+
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
99+
}
100+
return resp, err
101+
})
102+
}
103+
104+
func TestActionsService_GenerateRepoJITConfig(t *testing.T) {
105+
client, mux, _, teardown := setup()
106+
defer teardown()
107+
108+
input := &GenerateJITConfigRequest{Name: "test", RunnerGroupID: 1, Labels: []string{"one", "two"}}
109+
110+
mux.HandleFunc("/repos/o/r/actions/runners/generate-jitconfig", func(w http.ResponseWriter, r *http.Request) {
111+
v := new(GenerateJITConfigRequest)
112+
json.NewDecoder(r.Body).Decode(v)
113+
114+
testMethod(t, r, "POST")
115+
if !cmp.Equal(v, input) {
116+
t.Errorf("Request body = %+v, want %+v", v, input)
117+
}
118+
119+
fmt.Fprint(w, `{"encoded_jit_config":"foo"}`)
120+
})
121+
122+
ctx := context.Background()
123+
jitConfig, _, err := client.Actions.GenerateRepoJITConfig(ctx, "o", "r", input)
124+
if err != nil {
125+
t.Errorf("Actions.GenerateRepoJITConfig returned error: %v", err)
126+
}
127+
128+
want := &JITRunnerConfig{EncodedJITConfig: String("foo")}
129+
if !cmp.Equal(jitConfig, want) {
130+
t.Errorf("Actions.GenerateRepoJITConfig returned %+v, want %+v", jitConfig, want)
131+
}
132+
133+
const methodName = "GenerateRepoJITConfig"
134+
testBadOptions(t, methodName, func() (err error) {
135+
_, _, err = client.Actions.GenerateRepoJITConfig(ctx, "\n", "\n", input)
136+
return err
137+
})
138+
139+
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
140+
got, resp, err := client.Actions.GenerateRepoJITConfig(ctx, "o", "r", input)
141+
if got != nil {
142+
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
143+
}
144+
return resp, err
145+
})
146+
}
147+
59148
func TestActionsService_CreateRegistrationToken(t *testing.T) {
60149
client, mux, _, teardown := setup()
61150
defer teardown()

github/github-accessors.go

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

github/github-accessors_test.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)