mirror of
https://github.com/actions/actions-runner-controller.git
synced 2025-12-10 11:41:27 +00:00
The [ListRunnerGroup API](https://docs.github.com/en/rest/reference/actions#list-self-hosted-runner-groups-for-an-organization) now add a new query parameter `visible_to_repository`. We were doing `N+1` lookup when trying to find which runner group can be used for job from a certain repository. - List all runner groups - Loop through all groups to check repository access for each of them via [API](https://docs.github.com/en/rest/reference/actions#list-repository-access-to-a-self-hosted-runner-group-in-an-organization) The new query parameter `visible_to_repository` should allow us to get the runner groups with access in one call. Limitation: - The new query parameter is only supported in GitHub.com, which means anyone who uses ARC in GitHub Enterprise Server won't get this. - I am working on a PR to update `go-github` library to support the new parameter, but it will take a few weeks for a newer `go-github` to be released, so in the meantime, I am duplicating the implementation in ARC as well to support the new query parameter.
81 lines
1.7 KiB
Go
81 lines
1.7 KiB
Go
package simulator
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/actions-runner-controller/actions-runner-controller/github"
|
|
)
|
|
|
|
type Simulator struct {
|
|
Client *github.Client
|
|
}
|
|
|
|
func (c *Simulator) GetRunnerGroupsVisibleToRepository(ctx context.Context, org, repo string, managed *VisibleRunnerGroups) (*VisibleRunnerGroups, error) {
|
|
visible := NewVisibleRunnerGroups()
|
|
|
|
if org == "" {
|
|
panic(fmt.Sprintf("BUG: owner should not be empty in this context. repo=%v", repo))
|
|
}
|
|
|
|
if c.Client.GithubBaseURL == "https://github.com/" {
|
|
runnerGroups, err := c.Client.ListOrganizationRunnerGroupsForRepository(ctx, org, repo)
|
|
if err != nil {
|
|
return visible, err
|
|
}
|
|
|
|
for _, runnerGroup := range runnerGroups {
|
|
ref := NewRunnerGroupFromGitHub(runnerGroup)
|
|
|
|
if !managed.Includes(ref) {
|
|
continue
|
|
}
|
|
|
|
visible.Add(ref)
|
|
}
|
|
} else {
|
|
runnerGroups, err := c.Client.ListOrganizationRunnerGroups(ctx, org)
|
|
if err != nil {
|
|
return visible, err
|
|
}
|
|
|
|
for _, runnerGroup := range runnerGroups {
|
|
ref := NewRunnerGroupFromGitHub(runnerGroup)
|
|
|
|
if !managed.Includes(ref) {
|
|
continue
|
|
}
|
|
|
|
if runnerGroup.GetVisibility() != "all" {
|
|
hasAccess, err := c.hasRepoAccessToOrganizationRunnerGroup(ctx, org, runnerGroup.GetID(), repo)
|
|
if err != nil {
|
|
return visible, err
|
|
}
|
|
|
|
if !hasAccess {
|
|
continue
|
|
}
|
|
}
|
|
|
|
visible.Add(ref)
|
|
}
|
|
}
|
|
|
|
return visible, nil
|
|
}
|
|
|
|
func (c *Simulator) hasRepoAccessToOrganizationRunnerGroup(ctx context.Context, org string, runnerGroupId int64, repo string) (bool, error) {
|
|
repos, err := c.Client.ListRunnerGroupRepositoryAccesses(ctx, org, runnerGroupId)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
for _, githubRepo := range repos {
|
|
if githubRepo.GetFullName() == repo {
|
|
return true, nil
|
|
}
|
|
}
|
|
|
|
return false, nil
|
|
}
|