Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support workflow restrictions in actions_runner_groups #2559

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 20 additions & 11 deletions github/actions_runner_groups.go
Expand Up @@ -12,14 +12,17 @@ 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"`
WorkflowRestrictionsReadOnly *bool `json:"workflow_restrictions_read_only,omitempty"`
}

// RunnerGroups represents a collection of self-hosted runner groups configured for an organization.
Expand All @@ -38,13 +41,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 SelectedWorkflows slice.
RestrictedToWorkflows *bool `json:"restricted_to_workflows,omitempty"`
// List of workflows the runner group should be allowed to run. This setting will be ignored unless RestrictedToWorkflows 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