$ jobs: test: runs-on: ubuntu-latest timeout-minutes: 15 # <-- add this steps: ...
jobs: test: runs-on: ubuntu-latest timeout-minutes: 15 # <-- add this steps: ...
jobs: test: runs-on: ubuntu-latest timeout-minutes: 15 # <-- add this steps: ...
# top of every workflow that runs on PRs
concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} cancel-in-progress: true
# top of every workflow that runs on PRs
concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} cancel-in-progress: true
# top of every workflow that runs on PRs
concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} cancel-in-progress: true
- uses: actions/setup-node@v4 with: node-version: '20' cache: '-weight: 500;">npm' # or 'pnpm' or 'yarn'
- uses: actions/setup-node@v4 with: node-version: '20' cache: '-weight: 500;">npm' # or 'pnpm' or 'yarn'
- uses: actions/setup-node@v4 with: node-version: '20' cache: '-weight: 500;">npm' # or 'pnpm' or 'yarn' - missing-timeout (76 hits across 5 repos). No timeout-minutes: on jobs, so a hung step bills until GitHub's 6-hour default cap. Every repo has this.
- missing-concurrency (20 hits). Push 3 commits to a PR in 30 seconds, you get 3 stacked CI runs and GitHub bills all 3. concurrency: with cancel-in-progress: true kills the first 2 in milliseconds. Free 30-50% CI savings on PR-heavy repos.
- missing-cache (16 hits, mostly in eslint). actions/setup-node without cache: '-weight: 500;">npm' / 'pnpm' / 'yarn' means every job re-downloads node_modules. Slow and expensive. - All 5 repos were pulled via the GitHub public API, no auth.
- Each .github/workflows/*.yml was passed through ci-doctor 0.4.1 (14 rules) and gha-budget for per-job pricing.
- Cost = sum of all jobs at GitHub-hosted standard ubuntu-latest rates, assuming 8 min/job.
- Monthly = per-run * 30 runs/day * 30 days. Self-hosted and large-runner jobs are unpriced.
- This is the same engine that runs in the browser at /scan.html. The 20-repo version of this analysis lives at /benchmarks.html with per-repo deep dives.