Where do your GitHub Actions minutes go? Reads real runs through the GitHub REST API (read-only) and reports:
- time per step (top sinks),
- job-time spent in re-run attempts,
- critical path per workflow, from the real
needsin the workflow files at each run's commit, - billed cost, using per-minute prices from
config.yaml(source and check date inside).
Not implemented: cache-miss analysis (the jobs API has no cache data; it would need step logs), Markdown/HTML report, PR comment, scheduled Action.
pip install -e .
export GITHUB_TOKEN=... # any token with read access; needed to avoid the 60 req/h limit
python -c "from workflow_doctor.cli import app; app()" fetch OWNER/REPO --runs 500
python -c "from workflow_doctor.cli import app; app()" report
python -c "from workflow_doctor.cli import app; app()" critical OWNER/REPOExample (actions/checkout, 500 runs fetched 2026-10-18; 1060 jobs):
jobs: 1060 billed cost: $16.39 (prices checked 2026-10-18)
re-run time: 7.5 min
138.9 min Dependabot / Run Dependabot
62.0 min Analyze (javascript) / Perform CodeQL Analysis
The cost is hypothetical for public repositories. The prices are from the GitHub docs page in config.yaml; that page gave no effective date.
- Job-to-YAML matching is by job key or
name:; reusable-workflow jobs and unmatched names are skipped. - Tests use a synthetic fixture shaped like the API, not a captured real response.
pip install pytest && python -m pytest -q