Skip to content

Commit db32fc6

Browse files
authored
Support workflow restrictions in actions_runner_groups (#2559)
Fixes: #2558.
1 parent 3b3cbf1 commit db32fc6

File tree

4 files changed

+133
-26
lines changed

4 files changed

+133
-26
lines changed

github/actions_runner_groups.go

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ import (
1212

1313
// RunnerGroup represents a self-hosted runner group configured in an organization.
1414
type RunnerGroup struct {
15-
ID *int64 `json:"id,omitempty"`
16-
Name *string `json:"name,omitempty"`
17-
Visibility *string `json:"visibility,omitempty"`
18-
Default *bool `json:"default,omitempty"`
19-
SelectedRepositoriesURL *string `json:"selected_repositories_url,omitempty"`
20-
RunnersURL *string `json:"runners_url,omitempty"`
21-
Inherited *bool `json:"inherited,omitempty"`
22-
AllowsPublicRepositories *bool `json:"allows_public_repositories,omitempty"`
15+
ID *int64 `json:"id,omitempty"`
16+
Name *string `json:"name,omitempty"`
17+
Visibility *string `json:"visibility,omitempty"`
18+
Default *bool `json:"default,omitempty"`
19+
SelectedRepositoriesURL *string `json:"selected_repositories_url,omitempty"`
20+
RunnersURL *string `json:"runners_url,omitempty"`
21+
Inherited *bool `json:"inherited,omitempty"`
22+
AllowsPublicRepositories *bool `json:"allows_public_repositories,omitempty"`
23+
RestrictedToWorkflows *bool `json:"restricted_to_workflows,omitempty"`
24+
SelectedWorkflows []string `json:"selected_workflows,omitempty"`
25+
WorkflowRestrictionsReadOnly *bool `json:"workflow_restrictions_read_only,omitempty"`
2326
}
2427

2528
// RunnerGroups represents a collection of self-hosted runner groups configured for an organization.
@@ -38,13 +41,19 @@ type CreateRunnerGroupRequest struct {
3841
Runners []int64 `json:"runners,omitempty"`
3942
// If set to True, public repos can use this runner group
4043
AllowsPublicRepositories *bool `json:"allows_public_repositories,omitempty"`
44+
// If true, the runner group will be restricted to running only the workflows specified in the SelectedWorkflows slice.
45+
RestrictedToWorkflows *bool `json:"restricted_to_workflows,omitempty"`
46+
// List of workflows the runner group should be allowed to run. This setting will be ignored unless RestrictedToWorkflows is set to true.
47+
SelectedWorkflows []string `json:"selected_workflows,omitempty"`
4148
}
4249

4350
// UpdateRunnerGroupRequest represents a request to update a Runner group for an organization.
4451
type UpdateRunnerGroupRequest struct {
45-
Name *string `json:"name,omitempty"`
46-
Visibility *string `json:"visibility,omitempty"`
47-
AllowsPublicRepositories *bool `json:"allows_public_repositories,omitempty"`
52+
Name *string `json:"name,omitempty"`
53+
Visibility *string `json:"visibility,omitempty"`
54+
AllowsPublicRepositories *bool `json:"allows_public_repositories,omitempty"`
55+
RestrictedToWorkflows *bool `json:"restricted_to_workflows,omitempty"`
56+
SelectedWorkflows []string `json:"selected_workflows,omitempty"`
4857
}
4958

5059
// SetRepoAccessRunnerGroupRequest represents a request to replace the list of repositories

github/actions_runner_groups_test.go

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func TestActionsService_ListOrganizationRunnerGroups(t *testing.T) {
2121
mux.HandleFunc("/orgs/o/actions/runner-groups", func(w http.ResponseWriter, r *http.Request) {
2222
testMethod(t, r, "GET")
2323
testFormValues(t, r, values{"per_page": "2", "page": "2"})
24-
fmt.Fprint(w, `{"total_count":3,"runner_groups":[{"id":1,"name":"Default","visibility":"all","default":true,"runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/1/runners","inherited":false,"allows_public_repositories":true},{"id":2,"name":"octo-runner-group","visibility":"selected","default":false,"selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories","runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners","inherited":true,"allows_public_repositories":true},{"id":3,"name":"expensive-hardware","visibility":"private","default":false,"runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/3/runners","inherited":false,"allows_public_repositories":true}]}`)
24+
fmt.Fprint(w, `{"total_count":3,"runner_groups":[{"id":1,"name":"Default","visibility":"all","default":true,"runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/1/runners","inherited":false,"allows_public_repositories":true,"restricted_to_workflows":true,"selected_workflows":["a","b"]},{"id":2,"name":"octo-runner-group","visibility":"selected","default":false,"selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories","runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners","inherited":true,"allows_public_repositories":true,"restricted_to_workflows":false,"selected_workflows":[]},{"id":3,"name":"expensive-hardware","visibility":"private","default":false,"runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/3/runners","inherited":false,"allows_public_repositories":true,"restricted_to_workflows":false,"selected_workflows":[]}]}`)
2525
})
2626

2727
opts := &ListOrgRunnerGroupOptions{ListOptions: ListOptions{Page: 2, PerPage: 2}}
@@ -34,9 +34,9 @@ func TestActionsService_ListOrganizationRunnerGroups(t *testing.T) {
3434
want := &RunnerGroups{
3535
TotalCount: 3,
3636
RunnerGroups: []*RunnerGroup{
37-
{ID: Int64(1), Name: String("Default"), Visibility: String("all"), Default: Bool(true), RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/1/runners"), Inherited: Bool(false), AllowsPublicRepositories: Bool(true)},
38-
{ID: Int64(2), Name: String("octo-runner-group"), Visibility: String("selected"), Default: Bool(false), SelectedRepositoriesURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories"), RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners"), Inherited: Bool(true), AllowsPublicRepositories: Bool(true)},
39-
{ID: Int64(3), Name: String("expensive-hardware"), Visibility: String("private"), Default: Bool(false), RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/3/runners"), Inherited: Bool(false), AllowsPublicRepositories: Bool(true)},
37+
{ID: Int64(1), Name: String("Default"), Visibility: String("all"), Default: Bool(true), RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/1/runners"), Inherited: Bool(false), AllowsPublicRepositories: Bool(true), RestrictedToWorkflows: Bool(true), SelectedWorkflows: []string{"a", "b"}},
38+
{ID: Int64(2), Name: String("octo-runner-group"), Visibility: String("selected"), Default: Bool(false), SelectedRepositoriesURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories"), RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners"), Inherited: Bool(true), AllowsPublicRepositories: Bool(true), RestrictedToWorkflows: Bool(false), SelectedWorkflows: []string{}},
39+
{ID: Int64(3), Name: String("expensive-hardware"), Visibility: String("private"), Default: Bool(false), RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/3/runners"), Inherited: Bool(false), AllowsPublicRepositories: Bool(true), RestrictedToWorkflows: Bool(false), SelectedWorkflows: []string{}},
4040
},
4141
}
4242
if !cmp.Equal(groups, want) {
@@ -65,7 +65,7 @@ func TestActionsService_ListOrganizationRunnerGroupsVisibleToRepo(t *testing.T)
6565
mux.HandleFunc("/orgs/o/actions/runner-groups", func(w http.ResponseWriter, r *http.Request) {
6666
testMethod(t, r, "GET")
6767
testFormValues(t, r, values{"per_page": "2", "page": "2", "visible_to_repository": "github"})
68-
fmt.Fprint(w, `{"total_count":3,"runner_groups":[{"id":1,"name":"Default","visibility":"all","default":true,"runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/1/runners","inherited":false,"allows_public_repositories":true},{"id":2,"name":"octo-runner-group","visibility":"selected","default":false,"selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories","runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners","inherited":true,"allows_public_repositories":true},{"id":3,"name":"expensive-hardware","visibility":"private","default":false,"runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/3/runners","inherited":false,"allows_public_repositories":true}]}`)
68+
fmt.Fprint(w, `{"total_count":3,"runner_groups":[{"id":1,"name":"Default","visibility":"all","default":true,"runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/1/runners","inherited":false,"allows_public_repositories":true,"restricted_to_workflows":false,"selected_workflows":[]},{"id":2,"name":"octo-runner-group","visibility":"selected","default":false,"selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories","runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners","inherited":true,"allows_public_repositories":true,"restricted_to_workflows":false,"selected_workflows":[]},{"id":3,"name":"expensive-hardware","visibility":"private","default":false,"runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/3/runners","inherited":false,"allows_public_repositories":true,"restricted_to_workflows":false,"selected_workflows":[]}]}`)
6969
})
7070

7171
opts := &ListOrgRunnerGroupOptions{ListOptions: ListOptions{Page: 2, PerPage: 2}, VisibleToRepository: "github"}
@@ -78,9 +78,9 @@ func TestActionsService_ListOrganizationRunnerGroupsVisibleToRepo(t *testing.T)
7878
want := &RunnerGroups{
7979
TotalCount: 3,
8080
RunnerGroups: []*RunnerGroup{
81-
{ID: Int64(1), Name: String("Default"), Visibility: String("all"), Default: Bool(true), RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/1/runners"), Inherited: Bool(false), AllowsPublicRepositories: Bool(true)},
82-
{ID: Int64(2), Name: String("octo-runner-group"), Visibility: String("selected"), Default: Bool(false), SelectedRepositoriesURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories"), RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners"), Inherited: Bool(true), AllowsPublicRepositories: Bool(true)},
83-
{ID: Int64(3), Name: String("expensive-hardware"), Visibility: String("private"), Default: Bool(false), RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/3/runners"), Inherited: Bool(false), AllowsPublicRepositories: Bool(true)},
81+
{ID: Int64(1), Name: String("Default"), Visibility: String("all"), Default: Bool(true), RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/1/runners"), Inherited: Bool(false), AllowsPublicRepositories: Bool(true), RestrictedToWorkflows: Bool(false), SelectedWorkflows: []string{}},
82+
{ID: Int64(2), Name: String("octo-runner-group"), Visibility: String("selected"), Default: Bool(false), SelectedRepositoriesURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories"), RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners"), Inherited: Bool(true), AllowsPublicRepositories: Bool(true), RestrictedToWorkflows: Bool(false), SelectedWorkflows: []string{}},
83+
{ID: Int64(3), Name: String("expensive-hardware"), Visibility: String("private"), Default: Bool(false), RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/3/runners"), Inherited: Bool(false), AllowsPublicRepositories: Bool(true), RestrictedToWorkflows: Bool(false), SelectedWorkflows: []string{}},
8484
},
8585
}
8686
if !cmp.Equal(groups, want) {
@@ -108,7 +108,7 @@ func TestActionsService_GetOrganizationRunnerGroup(t *testing.T) {
108108

109109
mux.HandleFunc("/orgs/o/actions/runner-groups/2", func(w http.ResponseWriter, r *http.Request) {
110110
testMethod(t, r, "GET")
111-
fmt.Fprint(w, `{"id":2,"name":"octo-runner-group","visibility":"selected","default":false,"selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories","runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners","inherited":false,"allows_public_repositories":true}`)
111+
fmt.Fprint(w, `{"id":2,"name":"octo-runner-group","visibility":"selected","default":false,"selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories","runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners","inherited":false,"allows_public_repositories":true,"restricted_to_workflows":false,"selected_workflows":[]}`)
112112
})
113113

114114
ctx := context.Background()
@@ -126,6 +126,8 @@ func TestActionsService_GetOrganizationRunnerGroup(t *testing.T) {
126126
RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners"),
127127
Inherited: Bool(false),
128128
AllowsPublicRepositories: Bool(true),
129+
RestrictedToWorkflows: Bool(false),
130+
SelectedWorkflows: []string{},
129131
}
130132

131133
if !cmp.Equal(group, want) {
@@ -178,14 +180,16 @@ func TestActionsService_CreateOrganizationRunnerGroup(t *testing.T) {
178180

179181
mux.HandleFunc("/orgs/o/actions/runner-groups", func(w http.ResponseWriter, r *http.Request) {
180182
testMethod(t, r, "POST")
181-
fmt.Fprint(w, `{"id":2,"name":"octo-runner-group","visibility":"selected","default":false,"selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories","runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners","inherited":false,"allows_public_repositories":true}`)
183+
fmt.Fprint(w, `{"id":2,"name":"octo-runner-group","visibility":"selected","default":false,"selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories","runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners","inherited":false,"allows_public_repositories":true,"restricted_to_workflows":false,"selected_workflows":[]}`)
182184
})
183185

184186
ctx := context.Background()
185187
req := CreateRunnerGroupRequest{
186188
Name: String("octo-runner-group"),
187189
Visibility: String("selected"),
188190
AllowsPublicRepositories: Bool(true),
191+
RestrictedToWorkflows: Bool(false),
192+
SelectedWorkflows: []string{},
189193
}
190194
group, _, err := client.Actions.CreateOrganizationRunnerGroup(ctx, "o", req)
191195
if err != nil {
@@ -201,6 +205,8 @@ func TestActionsService_CreateOrganizationRunnerGroup(t *testing.T) {
201205
RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners"),
202206
Inherited: Bool(false),
203207
AllowsPublicRepositories: Bool(true),
208+
RestrictedToWorkflows: Bool(false),
209+
SelectedWorkflows: []string{},
204210
}
205211

206212
if !cmp.Equal(group, want) {
@@ -228,14 +234,16 @@ func TestActionsService_UpdateOrganizationRunnerGroup(t *testing.T) {
228234

229235
mux.HandleFunc("/orgs/o/actions/runner-groups/2", func(w http.ResponseWriter, r *http.Request) {
230236
testMethod(t, r, "PATCH")
231-
fmt.Fprint(w, `{"id":2,"name":"octo-runner-group","visibility":"selected","default":false,"selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories","runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners","inherited":false,"allows_public_repositories":true}`)
237+
fmt.Fprint(w, `{"id":2,"name":"octo-runner-group","visibility":"selected","default":false,"selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/repositories","runners_url":"https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners","inherited":false,"allows_public_repositories":true,"restricted_to_workflows":false,"selected_workflows":[]}`)
232238
})
233239

234240
ctx := context.Background()
235241
req := UpdateRunnerGroupRequest{
236242
Name: String("octo-runner-group"),
237243
Visibility: String("selected"),
238244
AllowsPublicRepositories: Bool(true),
245+
RestrictedToWorkflows: Bool(false),
246+
SelectedWorkflows: []string{},
239247
}
240248
group, _, err := client.Actions.UpdateOrganizationRunnerGroup(ctx, "o", 2, req)
241249
if err != nil {
@@ -251,6 +259,8 @@ func TestActionsService_UpdateOrganizationRunnerGroup(t *testing.T) {
251259
RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners"),
252260
Inherited: Bool(false),
253261
AllowsPublicRepositories: Bool(true),
262+
RestrictedToWorkflows: Bool(false),
263+
SelectedWorkflows: []string{},
254264
}
255265

256266
if !cmp.Equal(group, want) {
@@ -533,6 +543,8 @@ func TestRunnerGroup_Marshal(t *testing.T) {
533543
RunnersURL: String("r"),
534544
Inherited: Bool(true),
535545
AllowsPublicRepositories: Bool(true),
546+
RestrictedToWorkflows: Bool(false),
547+
SelectedWorkflows: []string{},
536548
}
537549

538550
want := `{
@@ -543,7 +555,9 @@ func TestRunnerGroup_Marshal(t *testing.T) {
543555
"selected_repositories_url": "s",
544556
"runners_url": "r",
545557
"inherited": true,
546-
"allows_public_repositories": true
558+
"allows_public_repositories": true,
559+
"restricted_to_workflows": false,
560+
"selected_workflows": []
547561
}`
548562

549563
testJSONMarshal(t, u, want)
@@ -564,6 +578,8 @@ func TestRunnerGroups_Marshal(t *testing.T) {
564578
RunnersURL: String("r"),
565579
Inherited: Bool(true),
566580
AllowsPublicRepositories: Bool(true),
581+
RestrictedToWorkflows: Bool(false),
582+
SelectedWorkflows: []string{},
567583
},
568584
},
569585
}
@@ -578,7 +594,9 @@ func TestRunnerGroups_Marshal(t *testing.T) {
578594
"selected_repositories_url": "s",
579595
"runners_url": "r",
580596
"inherited": true,
581-
"allows_public_repositories": true
597+
"allows_public_repositories": true,
598+
"restricted_to_workflows": false,
599+
"selected_workflows": []
582600
}]
583601
}`
584602

@@ -594,14 +612,18 @@ func TestCreateRunnerGroupRequest_Marshal(t *testing.T) {
594612
SelectedRepositoryIDs: []int64{1},
595613
Runners: []int64{1},
596614
AllowsPublicRepositories: Bool(true),
615+
RestrictedToWorkflows: Bool(true),
616+
SelectedWorkflows: []string{"a", "b"},
597617
}
598618

599619
want := `{
600620
"name": "n",
601621
"visibility": "v",
602622
"selected_repository_ids": [1],
603623
"runners": [1],
604-
"allows_public_repositories": true
624+
"allows_public_repositories": true,
625+
"restricted_to_workflows": true,
626+
"selected_workflows": ["a","b"]
605627
}`
606628

607629
testJSONMarshal(t, u, want)
@@ -614,12 +636,16 @@ func TestUpdateRunnerGroupRequest_Marshal(t *testing.T) {
614636
Name: String("n"),
615637
Visibility: String("v"),
616638
AllowsPublicRepositories: Bool(true),
639+
RestrictedToWorkflows: Bool(false),
640+
SelectedWorkflows: []string{},
617641
}
618642

619643
want := `{
620644
"name": "n",
621645
"visibility": "v",
622-
"allows_public_repositories": true
646+
"allows_public_repositories": true,
647+
"restricted_to_workflows": false,
648+
"selected_workflows": []
623649
}`
624650

625651
testJSONMarshal(t, u, want)

0 commit comments

Comments
 (0)