Find runner groups that visible to repository using a single API call. (#1324)

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.
This commit is contained in:
Tingluo Huang
2022-04-23 21:54:40 -04:00
committed by GitHub
parent c3e280eadb
commit ebe7d060cb
2 changed files with 93 additions and 17 deletions

View File

@@ -18,30 +18,47 @@ func (c *Simulator) GetRunnerGroupsVisibleToRepository(ctx context.Context, org,
panic(fmt.Sprintf("BUG: owner should not be empty in this context. repo=%v", repo))
}
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 c.Client.GithubBaseURL == "https://github.com/" {
runnerGroups, err := c.Client.ListOrganizationRunnerGroupsForRepository(ctx, org, repo)
if err != nil {
return visible, err
}
if runnerGroup.GetVisibility() != "all" {
hasAccess, err := c.hasRepoAccessToOrganizationRunnerGroup(ctx, org, runnerGroup.GetID(), repo)
if err != nil {
return visible, err
}
for _, runnerGroup := range runnerGroups {
ref := NewRunnerGroupFromGitHub(runnerGroup)
if !hasAccess {
if !managed.Includes(ref) {
continue
}
visible.Add(ref)
}
} else {
runnerGroups, err := c.Client.ListOrganizationRunnerGroups(ctx, org)
if err != nil {
return visible, err
}
visible.Add(ref)
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