Skip to content

depmedicdev-byte/ci-doctor

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

ci-doctor

Sponsor

npm ci license

Audit GitHub Actions workflows for waste, cost, and security gaps. CLI and a GitHub Action. Posts a comment on every PR with a table of findings and fix-it suggestions.

Try it without installing: paste a workflow into the in-browser audit. Same rules engine, runs entirely client-side, nothing leaves your tab. Want the dollar number? budget.html prices the same workflow.

demo

$ npx ci-doctor examples/bad-workflow

Found 7 finding(s)  [error 1  warn 4  info 2]

.github/workflows/ci.yml
  ERROR  7:15  deprecated-action
         actions/checkout@v3 is on a deprecated major. Latest stable: v4.
         | actions/checkout@v4
  WARN   8:15  missing-cache
         actions/setup-node has no cache option. Add 'with: cache: <ecosystem>' to skip dep re-downloads. Saves 30-90 seconds per run.
         | with:
         |   cache: npm   # or pip, gradle, maven, go, etc.
  WARN   2:5   missing-concurrency
         No top-level concurrency block. New pushes will not cancel in-flight runs of stale commits, doubling spend on rapid-push branches.
         | concurrency:
         |   group: ${{ github.workflow }}-${{ github.ref }}
         |   cancel-in-progress: true
  WARN   5:5   missing-timeout
         Job 'build' has no timeout-minutes. Default is 360 (6h). A hung job can drain your CI budget.
         | timeout-minutes: 15   # tune to your job; cap below the default 360.
  WARN   1:7   missing-permissions
         No top-level permissions block. GITHUB_TOKEN inherits the repo default, often write-all. Set least-privilege explicitly.
         | permissions:
         |   contents: read   # add other scopes only as jobs need them.
  INFO   2:5   wide-trigger
         on: push fires on every branch. Restrict to main or release branches unless you need every-branch runs.
  INFO   14:15 artifact-no-retention
         upload-artifact has no retention-days. CI artifacts pile up at the repo default (usually 90d). Set 7-14d unless you need long-term retention.

Above is real output from examples/bad-workflow/. Try it: git clone https://github.com/depmedicdev-byte/ci-doctor && cd ci-doctor && npx ci-doctor examples/bad-workflow.

Why

act runs your workflow locally. actionlint checks syntax. Neither tells you the workflow is burning money. ci-doctor focuses on the cost and security defaults you actually control.

Install

CLI

npm install -g ci-doctor
# or one-shot
npx ci-doctor

Node 18+.

GitHub Action

name: ci-doctor
on:
  pull_request:
permissions:
  contents: read
  pull-requests: write
jobs:
  audit:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@v4
      - uses: depmedicdev-byte/ci-doctor@v1
        with:
          fail-on: error
          comment: 'true'

It runs against every workflow under .github/workflows/, posts a single sticky comment on the PR, and updates that comment on subsequent runs.

Use

ci-doctor                          # scan .github/workflows in cwd
ci-doctor path/to/repo             # scan another repo
ci-doctor --file ci.yml            # one file
ci-doctor --json                   # machine output for CI
ci-doctor --markdown               # PR-comment table
ci-doctor --severity=warn          # only warn + error
ci-doctor --only=missing-cache     # one rule
ci-doctor --disable=fetch-depth-zero
ci-doctor --rules                  # list rules
ci-doctor --fix                    # auto-apply safe fixes in place (new in 0.2)
ci-doctor --fix --dry-run          # preview the patched yaml on stdout
ci-doctor --sarif                  # SARIF 2.1.0 for GitHub Code Scanning (new in 0.3)

Exit codes: 0 no error-level findings, 1 one or more errors, 2 internal error.

Auto-fix

ci-doctor --fix rewrites your workflows in place to fix the issues that have a single safe answer. It uses the document model (preserves comments and ordering of existing keys) and only adds:

Rule What --fix adds
missing-permissions top-level permissions: { contents: read }
missing-concurrency concurrency: { group: ..., cancel-in-progress: true }
missing-timeout timeout-minutes: 15 per job missing it
artifact-no-retention retention-days: 7 on each actions/upload-artifact

Rules with judgment calls (cache ecosystem, action major-version bumps, SHA pinning, runner cost) keep their warning so you decide. SHA pinning specifically is delegated to pin-actions.

Use --fix --dry-run first if you want to see the diff before writing.

GitHub Code Scanning (SARIF)

--sarif emits SARIF 2.1.0 you can upload with the official codeql-action/upload-sarif action. Findings appear as inline PR annotations and in the repo's Security tab.

name: ci-doctor
on:
  pull_request:
permissions:
  contents: read
  security-events: write
jobs:
  audit:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@v4
      - run: npx ci-doctor --sarif > ci-doctor.sarif || true
      - uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: ci-doctor.sarif

Severity maps error -> error, warn -> warning, info -> note.

Rules

Rule Severity Category
deprecated-action error maintenance
pinned-action-sha warn security
missing-cache warn cost
missing-concurrency warn cost
missing-timeout warn cost
expensive-runner warn cost
missing-permissions warn security
matrix-overcommit warn cost
stale-cache-key warn cost
wide-trigger info cost
artifact-no-retention info cost
fetch-depth-zero info cost
fail-fast-true info cost
always-run-on-pr info cost

ci-doctor --rules prints them with descriptions.

Action inputs

Input Default What it does
directory . Repo root. Action looks for .github/workflows under it.
fail-on error Threshold to fail the job: error, warn, info, never.
comment true Post a single sticky PR comment with the findings.
only (empty) Comma-separated rule ids to run exclusively.
disable (empty) Comma-separated rule ids to skip.
github-token ${{ github.token }} Token used to post the PR comment.

Pro

A paid Pro tier is in development:

  • Org-wide policy file: enforce a baseline across every repo.
  • Cost projection: estimate $ saved per finding using your runner mix.
  • Audit history page on GitHub Pages.
  • Private-repo support via license key.

License via Polar: $9/month or $39/year. Free CLI and Action stay free, MIT.

Companion

  • depmedic - surgical npm vulnerability triage from the same author.

Honesty

Built with AI assistance. Every change reviewed. Open an issue if anything breaks.

License

MIT.

About

Audit GitHub Actions workflows for waste, cost, and security gaps. 16 rules. Free, MIT, no telemetry.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors