finops-plugin/skills/github-actions-finops/SKILL.md
GitHub Actions billing, workflow efficiency, and waste analysis at org or repo level. Use when investigating CI/CD costs, wasted runs, or optimizing triggers.
npx skillsauth add laurigates/claude-plugins github-actions-finopsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Analyze GitHub Actions usage, costs, and efficiency across organizations and repositories.
| 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 |
git remote get-url originfind .github/workflows -maxdepth 1 -name '*.yml' -o -name '*.yaml'gh workflow list --json id,name,stateExecute this GitHub Actions FinOps analysis:
Read the Context values above. Parse $OWNER and $REPO from the current repo URL (e.g., https://github.com/OWNER/REPO.git). Run gh api repos/$OWNER/$REPO --jq '.owner.type' to determine if the owner is an "Organization" or "User". If 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.
Query the Actions billing API:
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:
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}'
Fetch recent runs and group by workflow:
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:
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"'
Check each waste indicator:
Skipped runs:
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:
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):
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})'
Read each workflow file from .github/workflows/ and check for:
concurrency: groupspaths: filters on push/PR triggersif: github.event.sender.type != 'Bot')Print a summary with these sections:
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 |
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 |
| 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 |
| 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' |
tools
Scaffold a new ComfyUI custom-node repo (pyproject, CI, release-please, vitest+pytest, JS extension skeleton) in the picker/gesture vein. Use when bootstrapping or init-ing a comfyui node pack.
tools
Orchestrate a ComfyUI node pack from idea to registry: scaffold, create + seed the repo, open the gitops adoption PR. Use when releasing or spinning up a new comfyui node pack.
testing
macOS EndpointSecurity/EDR high CPU & battery drain. Use when Kandji ESF / XProtect pegs a core; trace the exec storm via powermetrics + eslogger.
development
odiff pixel-by-pixel image diffing. Use when comparing screenshots, detecting visual regressions, diffing before/after PNGs, asserting golden images.