home / skills / laurigates / claude-plugins / github-actions-finops

github-actions-finops skill

/finops-plugin/skills/github-actions-finops

This skill analyzes GitHub Actions usage and costs across orgs and repos to identify waste and optimize workflow efficiency.

npx playbooks add skill laurigates/claude-plugins --skill github-actions-finops

Review the files below or copy the command above to add this skill to your agents.

Files (1)
skill.md
6.7 KB
---
model: haiku
name: github-actions-finops
description: |
  Analyze GitHub Actions billing, workflow efficiency, and waste patterns.
  Use when investigating CI/CD costs, identifying wasted runs, or optimizing
  workflow triggers. Covers org-level billing, per-repo workflow analysis,
  and waste pattern detection.
allowed-tools: Bash(gh api *), Bash(gh repo *), Bash(gh workflow *), Bash(gh run *), Read, Grep, Glob, TodoWrite
created: 2025-01-30
modified: 2026-02-11
reviewed: 2025-01-30
---

# GitHub Actions FinOps

Analyze GitHub Actions usage, costs, and efficiency across organizations and repositories.

## When to Use This Skill

| Use this skill when... | Use X instead when... |
|------------------------|----------------------|
| Analyzing CI/CD costs and billing | Debugging a specific failed workflow -- use gh-workflow-monitoring |
| Identifying wasted workflow runs | Setting up new workflows -- use github-actions-workflows |
| Investigating workflow trigger patterns | Managing cache keys -- use github-actions-cache-optimization |
| Comparing efficiency across repos | Monitoring a single run -- use gh-workflow-monitoring |

## Context

- Current repo: !`gh repo view --json nameWithOwner --jq '.nameWithOwner' 2>/dev/null`
- Repo owner: !`gh repo view --json owner --jq '.owner.login' 2>/dev/null`
- Owner type: !`gh repo view --json owner --jq '.owner.__typename' 2>/dev/null`
- Workflow files: !`find .github/workflows -maxdepth 1 \( -name '*.yml' -o -name '*.yaml' \) 2>/dev/null`
- Active workflows: !`gh workflow list --json id,name,state 2>/dev/null`

## Execution

Execute this GitHub Actions FinOps analysis:

### Step 1: Determine scope

Read the Context values above. Set `$OWNER` and `$REPO` from the current repo. If owner type is "Organization", set `$GITHUB_ORG` to the repo owner for org-level billing queries.

If no repo context is available, ask the user for the target organization or repository.

### Step 2: Fetch org-level billing (if org and admin access)

Query the Actions billing API:

```bash
gh api /orgs/$GITHUB_ORG/settings/billing/actions \
  --jq '{included_minutes, total_minutes_used, total_paid_minutes_used}'
```

If this returns a permissions error, note that admin access is required and skip to Step 3.

Optionally also check packages and storage billing:

```bash
gh api /orgs/$GITHUB_ORG/settings/billing/packages \
  --jq '{included_gigabytes_bandwidth, total_gigabytes_bandwidth_used}'

gh api /orgs/$GITHUB_ORG/settings/billing/shared-storage \
  --jq '{days_left_in_billing_cycle, estimated_paid_storage_for_month}'
```

### Step 3: Analyze workflow runs

Fetch recent runs and group by workflow:

```bash
gh api "/repos/$OWNER/$REPO/actions/runs?per_page=100" \
  --jq '.workflow_runs | group_by(.name) |
        map({workflow: .[0].name, runs: length,
             conclusions: (group_by(.conclusion) | map({(.[0].conclusion // "unknown"): length}) | add)}) |
        sort_by(-.runs)'
```

Calculate run durations:

```bash
gh api "/repos/$OWNER/$REPO/actions/runs?per_page=20&status=completed" \
  --jq '.workflow_runs | group_by(.name) |
        map({name: .[0].name, count: length,
             total_seconds: (map(.run_started_at as $start | .updated_at as $end |
                            (($end | fromdateiso8601) - ($start | fromdateiso8601))) | add)}) |
        sort_by(-.count) | .[] | "\(.name): \(.count) runs, ~\(.total_seconds/60|floor)min total"'
```

### Step 4: Detect waste patterns

Check each waste indicator:

**Skipped runs:**

```bash
gh api "/repos/$OWNER/$REPO/actions/runs?per_page=100" \
  --jq '[.workflow_runs[] | select(.conclusion == "skipped")] |
        group_by(.name) | map({workflow: .[0].name, skipped: length}) |
        sort_by(-.skipped)'
```

**Bot-triggered runs:**

```bash
gh api "/repos/$OWNER/$REPO/actions/runs?per_page=100" \
  --jq '[.workflow_runs[] | select(.triggering_actor.type == "Bot")] | length'
```

**High-frequency workflows (candidates for path filters):**

```bash
gh api "/repos/$OWNER/$REPO/actions/runs?per_page=100" \
  --jq '.workflow_runs | group_by(.name) | map(select(length > 50)) |
        map({workflow: .[0].name, runs: length})'
```

### Step 5: Analyze workflow files

Read each workflow file from `.github/workflows/` and check for:

1. Missing `concurrency:` groups
2. Missing `paths:` filters on push/PR triggers
3. Missing bot-trigger guards (`if: github.event.sender.type != 'Bot'`)

### Step 6: Report findings

Print a summary with these sections:

1. **Billing summary** (if available): minutes used, paid minutes, days left in cycle
2. **Workflow run counts**: table of workflows with run counts and conclusion breakdown
3. **Waste indicators**: skipped runs, bot triggers, high-frequency workflows, missing concurrency groups
4. **Recommendations**: specific fixes for each waste pattern detected

Use these thresholds for flagging:

| Metric | Red Flag Threshold |
|--------|-------------------|
| Skipped runs | >10% of total runs |
| Bot triggers | Bot-to-bot chains detected |
| Long durations | >10min average |
| High frequency | >50 runs/month without path filters |
| Duplicate runs | Same commit triggers multiple runs |

### Step 7: Suggest fixes

For each waste pattern found, recommend the specific fix:

| Pattern | Fix |
|---------|-----|
| Bot-triggered waste | Add `if: github.event.sender.type != 'Bot'` to jobs |
| Missing concurrency | Add `concurrency: { group: ${{ github.workflow }}-${{ github.ref }}, cancel-in-progress: true }` |
| No path filters | Add `paths:` with relevant source directories |
| Duplicate runs | Add concurrency groups with `cancel-in-progress: true` |

## API Reference

| Endpoint | Purpose | Admin Required |
|----------|---------|----------------|
| `/orgs/{org}/settings/billing/actions` | Minutes usage | Yes |
| `/orgs/{org}/settings/billing/packages` | Package bandwidth | Yes |
| `/orgs/{org}/settings/billing/shared-storage` | Storage billing | Yes |
| `/orgs/{org}/actions/cache/usage` | Org cache stats | No |
| `/repos/{owner}/{repo}/actions/runs` | Workflow runs | No |
| `/repos/{owner}/{repo}/actions/workflows` | Workflow definitions | No |

## Agentic Optimizations

| Context | Command |
|---------|---------|
| Org billing | `gh api /orgs/$ORG/settings/billing/actions --jq '{included_minutes, total_minutes_used}'` |
| List repos | `gh repo list $ORG --json nameWithOwner --limit 100` |
| Workflow runs | `gh api "/repos/$O/$R/actions/runs?per_page=100" --jq '.workflow_runs' --jq 'length'` |
| Skipped count | `gh api "..." --jq '[.workflow_runs[] | select(.conclusion == "skipped")] | length'` |
| Bot triggers | `gh api "..." --jq '[.workflow_runs[] | select(.triggering_actor.type == "Bot")] | length'` |

## See Also

- **github-actions-cache-optimization** - Cache-specific analysis and cleanup
- **gh-workflow-monitoring** - Watching individual workflow runs

Overview

This skill analyzes GitHub Actions billing, workflow efficiency, and waste patterns to help reduce CI/CD costs and noisy runs. It inspects org-level billing (when admin access is available), aggregates per-repo workflow run metrics, and surfaces actionable waste indicators. The output is a concise summary with prioritized recommendations to cut minutes and duplicate work.

How this skill works

The skill collects billing data for organizations and fetches recent workflow runs from repositories using the GitHub API. It groups runs by workflow, computes counts and total run time, and applies thresholds to flag skipped runs, bot-triggered runs, high-frequency workflows, and long averages. It also scans workflow files for missing concurrency, absent path filters, and lack of bot-guard conditions, then maps each finding to concrete fixes.

When to use it

  • Investigating unexpected or rising GitHub Actions costs across an org or repo
  • Identifying wasted or redundant workflow runs that consume minutes
  • Prioritizing workflows for optimization by run count and duration
  • Auditing workflows for missing concurrency or path filter controls
  • Preparing cost-saving recommendations for engineering managers

Best practices

  • Run org-level billing checks only with admin access; otherwise focus on repo-level analysis
  • Prioritize workflows by total run minutes (count × average duration) before individual optimizations
  • Enforce concurrency groups to cancel duplicate runs for the same ref
  • Add path filters to high-frequency workflows so builds run only on relevant changes
  • Guard jobs from bot-triggered cascades with if: github.event.sender.type != 'Bot'

Example use cases

  • Scan a repository to find workflows that together consume the largest share of minutes
  • Detect workflows that run frequently but are mostly skipped or triggered by bots
  • Compare run efficiency across several repos to find candidates for caching or pruning
  • Produce a recommendations report listing fixes: concurrency, path filters, bot guards
  • Validate workflows for missing concurrency or missing push/PR path filters

FAQ

Do I need admin access to run the full analysis?

Org-level billing requires admin access. If unavailable, the skill still analyzes repo-level runs and workflow files.

What thresholds are used to flag waste?

Default flags include skipped runs >10% of runs, average durations >10 minutes, and high-frequency workflows >50 runs/month without path filters.