Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions docs/tables/github_actions_repository_workflow_job.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
title: "Steampipe Table: github_actions_repository_workflow_job - Query GitHub Actions Repository Workflow Jobs using SQL"
description: "Allows users to query GitHub Actions Repository Workflow Jobs, specifically the details of each workflow job in a repository, providing insights into the status, conclusion, and other metadata of the jobs."
folder: "Actions"
---

# Table: github_actions_repository_workflow_job - Query GitHub Actions Repository Workflow Jobs using SQL

GitHub Actions is a CI/CD solution that allows you to automate how you build, test, and deploy your projects on any platform, including Linux, macOS, and Windows. It lets you run a series of commands in response to events on GitHub. With GitHub Actions, you can build end-to-end continuous integration (CI) and continuous deployment (CD) capabilities directly in your repository.

## Table Usage Guide

The `github_actions_repository_workflow_job` table provides insights into GitHub Actions Repository Workflow Jobs. As a software developer or DevOps engineer, explore details of each workflow job in a repository through this table, including its status, conclusion, and other metadata. Utilize it to monitor and analyze the performance and results of your CI/CD workflows, ensuring your software development process is efficient and effective.

To query this table using a [fine-grained access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token), the following permissions are required:
- Repository permissions:
- Actions (Read-only): Required to access all columns.
- Metadata (Read-only): Required to access general repository metadata.

**Important Notes**
- You must specify the `repository_full_name` column, along with either the `run_id` or the `id` column, in the `where` or `join` clause to query the table.

## Examples

### List workflow jobs
Analyze the settings to understand the operations and status of the workflow jobs in a specific GitHub repository. This can be beneficial in assessing the efficiency and effectiveness of workflows, identifying potential issues, and making informed decisions on workflow optimization.

```sql+postgres
select
*
from
github_actions_repository_workflow_job
where
repository_full_name = 'turbot/steampipe'
and run_id = 26404053809;
```

```sql+sqlite
select
*
from
github_actions_repository_workflow_job
where
repository_full_name = 'turbot/steampipe'
and run_id = 26404053809;
```

### List failed workflow jobs
Identify instances where workflow jobs have failed within the 'turbot/steampipe' repository. This can be useful for debugging and identifying problematic jobs.

```sql+postgres
select
id,
steps,
runner_id,
conclusion,
status,
run_attempt,
run_url,
head_sha,
head_branch
from
github_actions_repository_workflow_job
where
repository_full_name = 'turbot/steampipe'
and run_id = 26404053809
and conclusion = 'failure';
```

```sql+sqlite
select
id,
steps,
runner_id,
conclusion,
status,
run_attempt,
run_url,
head_sha,
head_branch
from
github_actions_repository_workflow_job
where
repository_full_name = 'turbot/steampipe'
and run_id = 26404053809
and conclusion = 'failure';
```
14 changes: 9 additions & 5 deletions docs/tables/github_actions_repository_workflow_run.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ where
repository_full_name = 'turbot/steampipe';
```

### List failure workflow runs
### List failed workflow runs
Identify instances where workflow runs have failed within the 'turbot/steampipe' repository. This can be useful for debugging and identifying problematic workflows.

```sql+postgres
Expand All @@ -60,7 +60,8 @@ select
from
github_actions_repository_workflow_run
where
repository_full_name = 'turbot/steampipe' and conclusion = 'failure';
repository_full_name = 'turbot/steampipe'
and conclusion = 'failure';
```

```sql+sqlite
Expand All @@ -77,7 +78,8 @@ select
from
github_actions_repository_workflow_run
where
repository_full_name = 'turbot/steampipe' and conclusion = 'failure';
repository_full_name = 'turbot/steampipe'
and conclusion = 'failure';
```

### List manual workflow runs
Expand All @@ -99,7 +101,8 @@ select
from
github_actions_repository_workflow_run
where
repository_full_name = 'turbot/steampipe' and event = 'workflow_dispatch';
repository_full_name = 'turbot/steampipe'
and event = 'workflow_dispatch';
```

```sql+sqlite
Expand All @@ -118,5 +121,6 @@ select
from
github_actions_repository_workflow_run
where
repository_full_name = 'turbot/steampipe' and event = 'workflow_dispatch';
repository_full_name = 'turbot/steampipe'
and event = 'workflow_dispatch';
```
1 change: 1 addition & 0 deletions github/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func Plugin(ctx context.Context) *plugin.Plugin {
"github_actions_repository_runner": tableGitHubActionsRepositoryRunner(),
"github_actions_repository_secret": tableGitHubActionsRepositorySecret(),
"github_actions_repository_variable": tableGitHubActionsRepositoryVariable(),
"github_actions_repository_workflow_job": tableGitHubActionsRepositoryWorkflowJob(),
"github_actions_repository_workflow_run": tableGitHubActionsRepositoryWorkflowRun(),
"github_audit_log": tableGitHubAuditLog(),
"github_blob": tableGitHubBlob(),
Expand Down
141 changes: 141 additions & 0 deletions github/table_github_actions_repository_workflow_job.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package github

import (
"context"

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

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

func tableGitHubActionsRepositoryWorkflowJob() *plugin.Table {
return &plugin.Table{
Name: "github_actions_repository_workflow_job",
Description: "WorkflowJob represents a repository action workflow job",
List: &plugin.ListConfig{
KeyColumns: []*plugin.KeyColumn{
{Name: "repository_full_name", Require: plugin.Required},
{Name: "run_id", Require: plugin.Required},
},
ShouldIgnoreError: isNotFoundError([]string{"404"}),
Hydrate: tableGitHubRepoWorkflowJobList,
},
Get: &plugin.GetConfig{
KeyColumns: []*plugin.KeyColumn{
{Name: "repository_full_name", Require: plugin.Required, Operators: []string{"="}},
{Name: "id", Require: plugin.Required, Operators: []string{"="}},
},
ShouldIgnoreError: isNotFoundError([]string{"404"}),
Hydrate: tableGitHubRepoWorkflowJobGet,
},
Columns: commonColumns([]*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 specifies the workflow job."},
{Name: "run_id", Type: proto.ColumnType_INT, Description: "The unique identifier of the workflow run."},
{Name: "id", Type: proto.ColumnType_INT, Description: "The unique identifier of the workflow job."},
{Name: "name", Type: proto.ColumnType_STRING, Description: "The name of the workflow job."},
{Name: "workflow_name", Type: proto.ColumnType_STRING, Description: "The workflow name of the workflow job."},
{Name: "node_id", Type: proto.ColumnType_STRING, Description: "The node id of the workflow job."},
{Name: "conclusion", Type: proto.ColumnType_STRING, Description: "The conclusion for workflow job."},
{Name: "status", Type: proto.ColumnType_STRING, Description: "The status of the workflow job."},
{Name: "run_url", Type: proto.ColumnType_STRING, Description: "The API address of the workflow run the job belongs to."},
{Name: "check_run_url", Type: proto.ColumnType_STRING, Description: "The API address of the check run associated with the workflow job."},
{Name: "head_branch", Type: proto.ColumnType_STRING, Description: "The head branch of the workflow job."},
{Name: "head_sha", Type: proto.ColumnType_STRING, Description: "The head sha of the workflow job.", Transform: transform.FromField("HeadSHA")},
{Name: "html_url", Type: proto.ColumnType_STRING, Description: "The address for the workflow job's GitHub web page.", Transform: transform.FromField("HTMLURL")},
{Name: "url", Type: proto.ColumnType_STRING, Description: "The address for the workflow job GitHub web page.", Transform: transform.FromField("URL")},

// Other columns
{Name: "steps", Type: proto.ColumnType_JSON, Description: "The list of step details for the workflow job."},
{Name: "labels", Type: proto.ColumnType_JSON, Description: "The list of labels for the workflow job."},
{Name: "created_at", Type: proto.ColumnType_TIMESTAMP, Transform: transform.FromField("CreatedAt").Transform(convertTimestamp), Description: "Time when the workflow job was created."},
{Name: "started_at", Type: proto.ColumnType_TIMESTAMP, Transform: transform.FromField("StartedAt").Transform(convertTimestamp), Description: "Time when the workflow job was started."},
{Name: "completed_at", Type: proto.ColumnType_TIMESTAMP, Transform: transform.FromField("CompletedAt").Transform(convertTimestamp), Description: "Time when the workflow job was completed."},
{Name: "run_attempt", Type: proto.ColumnType_INT, Description: "The attempt number of the workflow run."},
{Name: "runner_id", Type: proto.ColumnType_INT, Description: "The unique identifier of the workflow job runner."},
{Name: "runner_name", Type: proto.ColumnType_STRING, Description: "The name of the workflow job runner."},
{Name: "runner_group_id", Type: proto.ColumnType_INT, Description: "The unique identifier of the job runner group."},
{Name: "runner_group_name", Type: proto.ColumnType_STRING, Description: "The name of the workflow job runner group."},
}),
}
}

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

runId := d.EqualsQuals["run_id"].GetInt64Value()
orgName := d.EqualsQuals["repository_full_name"].GetStringValue()
owner, repo := parseRepoFullName(orgName)
opts := &github.ListWorkflowJobsOptions{
// The API defaults to "latest", which only returns jobs from the most recent
// run attempt. "all" includes jobs from previous attempts.
Filter: "all",
ListOptions: github.ListOptions{PerPage: 100},
}

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

for {
var (
workflowJobs *github.Jobs
resp *github.Response
err error
)
workflowJobs, resp, err = client.Actions.ListWorkflowJobs(ctx, owner, repo, runId, opts)
Comment thread
WallyGuzman marked this conversation as resolved.
if err != nil {
return nil, err
}

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

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

if resp.NextPage == 0 {
break
}

opts.Page = resp.NextPage
}

return nil, nil
}

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

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

owner, repo := parseRepoFullName(orgName)
Comment on lines +118 to +126

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add an empty check for jobId and orgName to avoid erroring on malformed or missing quals, similar to what we have in the github_actions_repository_workflow_run table?

For instance:

jobId := d.EqualsQuals["id"].GetInt64Value()
orgName := d.EqualsQuals["repository_full_name"].GetStringValue()

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

owner, repo := parseRepoFullName(orgName)

plugin.Logger(ctx).Trace("tableGitHubRepoWorkflowJobGet", "owner", owner, "repo", repo, "jobId", jobId)

client := connect(ctx, d)

var (
workflowJob *github.WorkflowJob
err error
)
workflowJob, _, err = client.Actions.GetWorkflowJobByID(ctx, owner, repo, jobId)
if err != nil {
return nil, err
}

return workflowJob, nil
}
6 changes: 3 additions & 3 deletions github/table_github_actions_repository_workflow_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ func tableGitHubActionsRepositoryWorkflowRun() *plugin.Table {
{Name: "repository_full_name", Type: proto.ColumnType_STRING, Transform: transform.FromQual("repository_full_name"), Description: "Full name of the repository that specifies the workflow run."},
{Name: "id", Type: proto.ColumnType_INT, Description: "The unque identifier of the workflow run."},
{Name: "event", Type: proto.ColumnType_STRING, Description: "The event for which workflow triggered off."},
{Name: "workflow_id", Type: proto.ColumnType_STRING, Description: "The workflow id of the worflow run."},
{Name: "node_id", Type: proto.ColumnType_STRING, Description: "The node id of the worflow run."},
{Name: "workflow_id", Type: proto.ColumnType_STRING, Description: "The workflow id of the workflow run."},
{Name: "node_id", Type: proto.ColumnType_STRING, Description: "The node id of the workflow run."},
{Name: "conclusion", Type: proto.ColumnType_STRING, Description: "The conclusion for workflow run."},
{Name: "status", Type: proto.ColumnType_STRING, Description: "The status of the worflow run."},
{Name: "status", Type: proto.ColumnType_STRING, Description: "The status of the workflow run."},
{Name: "run_number", Type: proto.ColumnType_INT, Description: "The number of time workflow has run."},
{Name: "artifacts_url", Type: proto.ColumnType_STRING, Description: "The address for artifact GitHub web page."},
{Name: "cancel_url", Type: proto.ColumnType_STRING, Description: "The address for workflow run cancel GitHub web page."},
Expand Down