Skip to content

Commit

Permalink
Add table github_actions_repository_runner closes #140 (#141)
Browse files Browse the repository at this point in the history
  • Loading branch information
ParthaI authored Feb 8, 2022
1 parent 043e75f commit cddfa68
Show file tree
Hide file tree
Showing 3 changed files with 221 additions and 33 deletions.
47 changes: 47 additions & 0 deletions docs/tables/github_actions_repository_runner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Table: github_actions_repository_runner

A runner is a server that runs your workflows when they're triggered. Each runner can run a single job at a time. Self-hosted runners offer more control of hardware, operating system, and software tools than GitHub-hosted runners provide.

The `github_actions_repository_runner` table can be used to query information about any self-hosted runner, and **you must specify which repository** in the where or join clause using the `repository_full_name` column.

## Examples

### List runners

```sql
select
*
from
github_actions_repository_runner
where
repository_full_name = 'turbot/steampipe';
```

### List runners with mac operating system

```sql
select
repository_full_name,
id,
name,
os
from
github_actions_repository_runner
where
repository_full_name = 'turbot/steampipe' and os = 'macos';
```

### List runners which are in use currently

```sql
select
repository_full_name,
id,
name,
os,
busy
from
github_actions_repository_runner
where
repository_full_name = 'turbot/steampipe' and busy;
```
67 changes: 34 additions & 33 deletions github/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,41 @@ func Plugin(ctx context.Context) *plugin.Plugin {
},
DefaultTransform: transform.FromGo(),
TableMap: map[string]*plugin.Table{
"github_actions_repository_runner": tableGitHubActionsRepositoryRunner(ctx),
"github_actions_repository_secret": tableGitHubActionsRepositorySecret(ctx),
"github_branch": tableGitHubBranch(ctx),
"github_branch_protection": tableGitHubBranchProtection(ctx),
"github_commit": tableGitHubCommit(ctx),
"github_community_profile": tableGitHubCommunityProfile(ctx),
"github_gist": tableGitHubGist(),
"github_gitignore": tableGitHubGitignore(),
"github_issue": tableGitHubIssue(),
"github_license": tableGitHubLicense(),
"github_my_gist": tableGitHubMyGist(),
"github_my_issue": tableGitHubMyIssue(),
"github_my_organization": tableGitHubMyOrganization(),
"github_my_repository": tableGitHubMyRepository(),
"github_my_star": tableGitHubMyStar(),
"github_my_team": tableGitHubMyTeam(),
"github_organization": tableGitHubOrganization(),
"github_pull_request": tableGitHubPullRequest(),
"github_rate_limit": tableGitHubRateLimit(ctx),
"github_release": tableGitHubRelease(ctx),
"github_repository": tableGitHubRepository(),
"github_search_code": tableGitHubSearchCode(ctx),
"github_search_commit": tableGitHubSearchCommit(ctx),
"github_search_issue": tableGitHubSearchIssue(ctx),
"github_search_label": tableGitHubSearchLable(ctx),
"github_search_pull_request": tableGitHubSearchPullRequest(ctx),
"github_search_repository": tableGitHubSearchRepository(ctx),
"github_search_topic": tableGitHubSearchTopic(ctx),
"github_search_user": tableGitHubSearchUser(ctx),
"github_stargazer": tableGitHubStargazer(ctx),
"github_tag": tableGitHubTag(ctx),
"github_traffic_view_daily": tableGitHubTrafficViewDaily(ctx),
"github_traffic_view_weekly": tableGitHubTrafficViewWeekly(ctx),
"github_user": tableGitHubUser(),
"github_workflow": tableGitHubWorkflow(ctx),
"github_branch": tableGitHubBranch(ctx),
"github_branch_protection": tableGitHubBranchProtection(ctx),
"github_commit": tableGitHubCommit(ctx),
"github_community_profile": tableGitHubCommunityProfile(ctx),
"github_gist": tableGitHubGist(),
"github_gitignore": tableGitHubGitignore(),
"github_issue": tableGitHubIssue(),
"github_license": tableGitHubLicense(),
"github_my_gist": tableGitHubMyGist(),
"github_my_issue": tableGitHubMyIssue(),
"github_my_organization": tableGitHubMyOrganization(),
"github_my_repository": tableGitHubMyRepository(),
"github_my_star": tableGitHubMyStar(),
"github_my_team": tableGitHubMyTeam(),
"github_organization": tableGitHubOrganization(),
"github_pull_request": tableGitHubPullRequest(),
"github_rate_limit": tableGitHubRateLimit(ctx),
"github_release": tableGitHubRelease(ctx),
"github_repository": tableGitHubRepository(),
"github_search_code": tableGitHubSearchCode(ctx),
"github_search_commit": tableGitHubSearchCommit(ctx),
"github_search_issue": tableGitHubSearchIssue(ctx),
"github_search_label": tableGitHubSearchLable(ctx),
"github_search_pull_request": tableGitHubSearchPullRequest(ctx),
"github_search_repository": tableGitHubSearchRepository(ctx),
"github_search_topic": tableGitHubSearchTopic(ctx),
"github_search_user": tableGitHubSearchUser(ctx),
"github_stargazer": tableGitHubStargazer(ctx),
"github_tag": tableGitHubTag(ctx),
"github_traffic_view_daily": tableGitHubTrafficViewDaily(ctx),
"github_traffic_view_weekly": tableGitHubTrafficViewWeekly(ctx),
"github_user": tableGitHubUser(),
"github_workflow": tableGitHubWorkflow(ctx),
},
}
return p
Expand Down
140 changes: 140 additions & 0 deletions github/table_github_actions_repository_runner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package github

import (
"context"

"github.com/google/go-github/v33/github"

"github.com/turbot/steampipe-plugin-sdk/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/plugin"
"github.com/turbot/steampipe-plugin-sdk/plugin/transform"
)

//// TABLE DEFINITION

func tableGitHubActionsRepositoryRunner(ctx context.Context) *plugin.Table {
return &plugin.Table{
Name: "github_actions_repository_runner",
Description: "The runner is the application that runs a job from a GitHub Actions workflow",
List: &plugin.ListConfig{
KeyColumns: plugin.SingleColumn("repository_full_name"),
ShouldIgnoreError: isNotFoundError([]string{"404"}),
Hydrate: tableGitHubRunnerList,
},
Get: &plugin.GetConfig{
KeyColumns: plugin.AllColumns([]string{"repository_full_name", "id"}),
ShouldIgnoreError: isNotFoundError([]string{"404"}),
Hydrate: tableGitHubRunnerGet,
},
Columns: []*plugin.Column{
// Top columns
{Name: "repository_full_name", Type: proto.ColumnType_STRING, Transform: transform.FromQual("repository_full_name"), Description: "Full name of the repository that contains the runners."},
{Name: "id", Type: proto.ColumnType_INT, Transform: transform.FromGo(), Description: "The unique identifier of the runner."},
{Name: "name", Type: proto.ColumnType_STRING, Description: "The name of the runner."},
{Name: "os", Type: proto.ColumnType_STRING, Transform: transform.FromField("OS"), Description: "The operating system of the runner."},
{Name: "status", Type: proto.ColumnType_STRING, Description: "The status of the runner."},
{Name: "busy", Type: proto.ColumnType_BOOL, Description: "Indicates wheather the runner is currently in use or not."},
{Name: "labels", Type: proto.ColumnType_JSON, Description: "Labels represents a collection of labels attached to each runner."},
},
}
}

//// LIST FUNCTION

func tableGitHubRunnerList(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
client := connect(ctx, d)

orgName := d.KeyColumnQuals["repository_full_name"].GetStringValue()
owner, repo := parseRepoFullName(orgName)

type ListPageResponse struct {
runners *github.Runners
resp *github.Response
}

opts := &github.ListOptions{PerPage: 100}

limit := d.QueryContext.Limit
if limit != nil {
if *limit < int64(opts.PerPage) {
opts.PerPage = int(*limit)
}
}

listPage := func(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
runners, resp, err := client.Actions.ListRunners(ctx, owner, repo, opts)
return ListPageResponse{
runners: runners,
resp: resp,
}, err
}

for {
listPageResponse, err := plugin.RetryHydrate(ctx, d, h, listPage, &plugin.RetryConfig{ShouldRetryError: shouldRetryError})
if err != nil {
return nil, err
}

listResponse := listPageResponse.(ListPageResponse)
runners := listResponse.runners
resp := listResponse.resp

for _, i := range runners.Runners {
if i != nil {
d.StreamListItem(ctx, i)
}

// Context can be cancelled due to manual cancellation or the limit has been hit
if d.QueryStatus.RowsRemaining(ctx) == 0 {
return nil, nil
}
}

if resp.NextPage == 0 {
break
}

opts.Page = resp.NextPage
}

return nil, nil
}

//// HYDRATE FUNCTIONS

func tableGitHubRunnerGet(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
runnerId := d.KeyColumnQuals["id"].GetInt64Value()
orgName := d.KeyColumnQuals["repository_full_name"].GetStringValue()

// Empty check for the parameter
if runnerId == 0 || orgName == "" {
return nil, nil
}

owner, repo := parseRepoFullName(orgName)
plugin.Logger(ctx).Trace("tableGitHubRunnerGet", "owner", owner, "repo", repo, "runnerId", runnerId)

client := connect(ctx, d)

type GetResponse struct {
runner *github.Runner
resp *github.Response
}

getDetails := func(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
detail, resp, err := client.Actions.GetRunner(ctx, owner, repo, runnerId)
return GetResponse{
runner: detail,
resp: resp,
}, err
}

getResponse, err := plugin.RetryHydrate(ctx, d, h, getDetails, &plugin.RetryConfig{ShouldRetryError: shouldRetryError})
if err != nil {
return nil, err
}

getResp := getResponse.(GetResponse)

return getResp.runner, nil
}

0 comments on commit cddfa68

Please sign in to comment.