Skip to content

Commit

Permalink
issue #2558: support workflow restrictions in actions_runner_groups
Browse files Browse the repository at this point in the history
  • Loading branch information
bob-bins committed Nov 8, 2022
1 parent 331265b commit 0461a6c
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 26 deletions.
30 changes: 19 additions & 11 deletions github/actions_runner_groups.go
Expand Up @@ -12,14 +12,16 @@ import (

// RunnerGroup represents a self-hosted runner group configured in an organization.
type RunnerGroup struct {
ID *int64 `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Visibility *string `json:"visibility,omitempty"`
Default *bool `json:"default,omitempty"`
SelectedRepositoriesURL *string `json:"selected_repositories_url,omitempty"`
RunnersURL *string `json:"runners_url,omitempty"`
Inherited *bool `json:"inherited,omitempty"`
AllowsPublicRepositories *bool `json:"allows_public_repositories,omitempty"`
ID *int64 `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Visibility *string `json:"visibility,omitempty"`
Default *bool `json:"default,omitempty"`
SelectedRepositoriesURL *string `json:"selected_repositories_url,omitempty"`
RunnersURL *string `json:"runners_url,omitempty"`
Inherited *bool `json:"inherited,omitempty"`
AllowsPublicRepositories *bool `json:"allows_public_repositories,omitempty"`
RestrictedToWorkflows *bool `json:"restricted_to_workflows,omitempty"`
SelectedWorkflows []string `json:"selected_workflows,omitempty"`
}

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

// UpdateRunnerGroupRequest represents a request to update a Runner group for an organization.
type UpdateRunnerGroupRequest struct {
Name *string `json:"name,omitempty"`
Visibility *string `json:"visibility,omitempty"`
AllowsPublicRepositories *bool `json:"allows_public_repositories,omitempty"`
Name *string `json:"name,omitempty"`
Visibility *string `json:"visibility,omitempty"`
AllowsPublicRepositories *bool `json:"allows_public_repositories,omitempty"`
RestrictedToWorkflows *bool `json:"restricted_to_workflows,omitempty"`
SelectedWorkflows []string `json:"selected_workflows,omitempty"`
}

// SetRepoAccessRunnerGroupRequest represents a request to replace the list of repositories
Expand Down
56 changes: 41 additions & 15 deletions github/actions_runner_groups_test.go
Expand Up @@ -21,7 +21,7 @@ func TestActionsService_ListOrganizationRunnerGroups(t *testing.T) {
mux.HandleFunc("/orgs/o/actions/runner-groups", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"per_page": "2", "page": "2"})
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}]}`)
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":[]}]}`)
})

opts := &ListOrgRunnerGroupOptions{ListOptions: ListOptions{Page: 2, PerPage: 2}}
Expand All @@ -34,9 +34,9 @@ func TestActionsService_ListOrganizationRunnerGroups(t *testing.T) {
want := &RunnerGroups{
TotalCount: 3,
RunnerGroups: []*RunnerGroup{
{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)},
{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)},
{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)},
{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"}},
{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{}},
{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{}},
},
}
if !cmp.Equal(groups, want) {
Expand Down Expand Up @@ -65,7 +65,7 @@ func TestActionsService_ListOrganizationRunnerGroupsVisibleToRepo(t *testing.T)
mux.HandleFunc("/orgs/o/actions/runner-groups", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"per_page": "2", "page": "2", "visible_to_repository": "github"})
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}]}`)
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":[]}]}`)
})

opts := &ListOrgRunnerGroupOptions{ListOptions: ListOptions{Page: 2, PerPage: 2}, VisibleToRepository: "github"}
Expand All @@ -78,9 +78,9 @@ func TestActionsService_ListOrganizationRunnerGroupsVisibleToRepo(t *testing.T)
want := &RunnerGroups{
TotalCount: 3,
RunnerGroups: []*RunnerGroup{
{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)},
{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)},
{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)},
{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{}},
{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{}},
{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{}},
},
}
if !cmp.Equal(groups, want) {
Expand Down Expand Up @@ -108,7 +108,7 @@ func TestActionsService_GetOrganizationRunnerGroup(t *testing.T) {

mux.HandleFunc("/orgs/o/actions/runner-groups/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
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}`)
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":[]}`)
})

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

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

mux.HandleFunc("/orgs/o/actions/runner-groups", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
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}`)
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":[]}`)
})

ctx := context.Background()
req := CreateRunnerGroupRequest{
Name: String("octo-runner-group"),
Visibility: String("selected"),
AllowsPublicRepositories: Bool(true),
RestrictedToWorkflows: Bool(false),
SelectedWorkflows: []string{},
}
group, _, err := client.Actions.CreateOrganizationRunnerGroup(ctx, "o", req)
if err != nil {
Expand All @@ -201,6 +205,8 @@ func TestActionsService_CreateOrganizationRunnerGroup(t *testing.T) {
RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners"),
Inherited: Bool(false),
AllowsPublicRepositories: Bool(true),
RestrictedToWorkflows: Bool(false),
SelectedWorkflows: []string{},
}

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

mux.HandleFunc("/orgs/o/actions/runner-groups/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
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}`)
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":[]}`)
})

ctx := context.Background()
req := UpdateRunnerGroupRequest{
Name: String("octo-runner-group"),
Visibility: String("selected"),
AllowsPublicRepositories: Bool(true),
RestrictedToWorkflows: Bool(false),
SelectedWorkflows: []string{},
}
group, _, err := client.Actions.UpdateOrganizationRunnerGroup(ctx, "o", 2, req)
if err != nil {
Expand All @@ -251,6 +259,8 @@ func TestActionsService_UpdateOrganizationRunnerGroup(t *testing.T) {
RunnersURL: String("https://api.github.com/orgs/octo-org/actions/runner_groups/2/runners"),
Inherited: Bool(false),
AllowsPublicRepositories: Bool(true),
RestrictedToWorkflows: Bool(false),
SelectedWorkflows: []string{},
}

if !cmp.Equal(group, want) {
Expand Down Expand Up @@ -533,6 +543,8 @@ func TestRunnerGroup_Marshal(t *testing.T) {
RunnersURL: String("r"),
Inherited: Bool(true),
AllowsPublicRepositories: Bool(true),
RestrictedToWorkflows: Bool(false),
SelectedWorkflows: []string{},
}

want := `{
Expand All @@ -543,7 +555,9 @@ func TestRunnerGroup_Marshal(t *testing.T) {
"selected_repositories_url": "s",
"runners_url": "r",
"inherited": true,
"allows_public_repositories": true
"allows_public_repositories": true,
"restricted_to_workflows": false,
"selected_workflows": []
}`

testJSONMarshal(t, u, want)
Expand All @@ -564,6 +578,8 @@ func TestRunnerGroups_Marshal(t *testing.T) {
RunnersURL: String("r"),
Inherited: Bool(true),
AllowsPublicRepositories: Bool(true),
RestrictedToWorkflows: Bool(false),
SelectedWorkflows: []string{},
},
},
}
Expand All @@ -578,7 +594,9 @@ func TestRunnerGroups_Marshal(t *testing.T) {
"selected_repositories_url": "s",
"runners_url": "r",
"inherited": true,
"allows_public_repositories": true
"allows_public_repositories": true,
"restricted_to_workflows": false,
"selected_workflows": []
}]
}`

Expand All @@ -594,14 +612,18 @@ func TestCreateRunnerGroupRequest_Marshal(t *testing.T) {
SelectedRepositoryIDs: []int64{1},
Runners: []int64{1},
AllowsPublicRepositories: Bool(true),
RestrictedToWorkflows: Bool(true),
SelectedWorkflows: []string{"a","b"},
}

want := `{
"name": "n",
"visibility": "v",
"selected_repository_ids": [1],
"runners": [1],
"allows_public_repositories": true
"allows_public_repositories": true,
"restricted_to_workflows": true,
"selected_workflows": ["a","b"]
}`

testJSONMarshal(t, u, want)
Expand All @@ -614,12 +636,16 @@ func TestUpdateRunnerGroupRequest_Marshal(t *testing.T) {
Name: String("n"),
Visibility: String("v"),
AllowsPublicRepositories: Bool(true),
RestrictedToWorkflows: Bool(false),
SelectedWorkflows: []string{},
}

want := `{
"name": "n",
"visibility": "v",
"allows_public_repositories": true
"allows_public_repositories": true,
"restricted_to_workflows": false,
"selected_workflows": []
}`

testJSONMarshal(t, u, want)
Expand Down

0 comments on commit 0461a6c

Please sign in to comment.