gha-doctor — psf/requests F · 27/100

generated 2026-08-01 01:34 UTC · gha-doctor 0.32.0

Run durations — 90 decisive runs success failure 0 2.5 5 7.5 10 min Jul 9 Jul 17 Jul 24 Aug 1 Type Check · 0.5 min · success · 2026-07-09 15:10 UTC Tests · 4.6 min · success · 2026-07-09 15:12 UTC Lint code · 0.4 min · success · 2026-07-09 15:12 UTC GitHub Actions Security Analysis with zizmor 🌈 · 0.3 min · success · 2026-07-09 15:12 UTC Type Check · 0.4 min · success · 2026-07-09 15:12 UTC CodeQL · 1.1 min · success · 2026-07-09 15:12 UTC CodeQL · 1.2 min · success · 2026-07-12 23:14 UTC github_actions in /. - Update #1459021737 · 4.1 min · success · 2026-07-13 16:52 UTC pre_commit in /. - Update #1459026798 · 1.0 min · success · 2026-07-13 16:54 UTC CodeQL · 1.1 min · success · 2026-07-19 23:15 UTC github_actions in /. - Update #1468556551 · 4.6 min · success · 2026-07-20 16:52 UTC pre_commit in /. - Update #1468561744 · 0.8 min · success · 2026-07-20 16:54 UTC Lint code · 0.4 min · success · 2026-07-20 16:55 UTC Tests · 4.5 min · success · 2026-07-20 16:55 UTC Type Check · 0.4 min · success · 2026-07-20 16:55 UTC Type Check · 0.4 min · success · 2026-07-20 16:55 UTC CodeQL · 1.1 min · success · 2026-07-20 16:55 UTC GitHub Actions Security Analysis with zizmor 🌈 · 0.3 min · success · 2026-07-20 16:55 UTC Tests · 4.6 min · success · 2026-07-20 16:55 UTC Lint code · 0.4 min · success · 2026-07-20 16:55 UTC Type Check · 0.5 min · success · 2026-07-20 16:56 UTC Lint code · 0.3 min · success · 2026-07-20 16:56 UTC Lint code · 0.3 min · success · 2026-07-20 16:56 UTC CodeQL · 1.0 min · success · 2026-07-20 16:56 UTC GitHub Actions Security Analysis with zizmor 🌈 · 0.3 min · success · 2026-07-20 16:56 UTC Type Check · 0.4 min · success · 2026-07-20 16:56 UTC Type Check · 0.4 min · success · 2026-07-20 17:55 UTC CodeQL · 1.0 min · success · 2026-07-20 17:55 UTC GitHub Actions Security Analysis with zizmor 🌈 · 0.3 min · success · 2026-07-20 17:55 UTC Lint code · 0.4 min · success · 2026-07-20 17:55 UTC Tests · 3.8 min · success · 2026-07-20 17:55 UTC Tests · 3.9 min · success · 2026-07-20 17:56 UTC Type Check · 0.5 min · success · 2026-07-20 18:41 UTC Lint code · 0.4 min · success · 2026-07-20 18:41 UTC Tests · 4.4 min · success · 2026-07-20 18:41 UTC CodeQL · 1.1 min · success · 2026-07-20 18:41 UTC GitHub Actions Security Analysis with zizmor 🌈 · 0.3 min · success · 2026-07-20 18:41 UTC CodeQL · 1.2 min · success · 2026-07-26 23:16 UTC github_actions in /. - Update #1487419578 · 1.1 min · success · 2026-07-27 16:52 UTC Lint code · 0.7 min · success · 2026-07-27 16:53 UTC Type Check · 0.4 min · success · 2026-07-27 16:53 UTC Tests · 4.6 min · success · 2026-07-27 16:53 UTC CodeQL · 0.9 min · success · 2026-07-27 16:53 UTC GitHub Actions Security Analysis with zizmor 🌈 · 0.6 min · success · 2026-07-27 16:53 UTC Lint code · 0.5 min · success · 2026-07-27 16:53 UTC Type Check · 0.4 min · success · 2026-07-27 16:53 UTC Tests · 4.9 min · success · 2026-07-27 16:53 UTC pre_commit in /. - Update #1487428555 · 0.9 min · success · 2026-07-27 16:54 UTC Tests · 4.8 min · success · 2026-07-27 16:55 UTC Type Check · 0.3 min · success · 2026-07-27 16:55 UTC Lint code · 0.4 min · success · 2026-07-27 16:55 UTC Type Check · 0.3 min · success · 2026-07-27 16:55 UTC Lint code · 0.5 min · success · 2026-07-27 16:55 UTC Tests · 5.1 min · success · 2026-07-27 16:55 UTC CodeQL · 1.1 min · success · 2026-07-27 16:55 UTC GitHub Actions Security Analysis with zizmor 🌈 · 0.5 min · success · 2026-07-27 16:55 UTC Type Check · 0.5 min · success · 2026-07-27 17:18 UTC GitHub Actions Security Analysis with zizmor 🌈 · 0.3 min · success · 2026-07-27 17:18 UTC Tests · 4.9 min · success · 2026-07-27 17:18 UTC Lint code · 0.4 min · success · 2026-07-27 17:18 UTC CodeQL · 1.1 min · success · 2026-07-27 17:18 UTC GitHub Actions Security Analysis with zizmor 🌈 · 0.4 min · success · 2026-07-27 17:25 UTC Type Check · 0.4 min · success · 2026-07-27 17:25 UTC CodeQL · 1.1 min · success · 2026-07-27 17:25 UTC Lint code · 0.5 min · success · 2026-07-27 17:25 UTC Tests · 3.7 min · success · 2026-07-27 18:06 UTC Lock Threads · 0.1 min · failure · 2026-07-10 00:24 UTC Lock Threads · 0.1 min · failure · 2026-07-11 00:19 UTC Lock Threads · 0.1 min · failure · 2026-07-12 00:19 UTC Lock Threads · 0.1 min · failure · 2026-07-13 00:19 UTC Lock Threads · 0.1 min · failure · 2026-07-14 00:17 UTC Lock Threads · 0.1 min · failure · 2026-07-15 00:16 UTC Lock Threads · 0.1 min · failure · 2026-07-16 00:19 UTC Lock Threads · 0.1 min · failure · 2026-07-17 00:20 UTC Lock Threads · 0.1 min · failure · 2026-07-18 00:18 UTC Lock Threads · 0.1 min · failure · 2026-07-19 00:19 UTC Lock Threads · 0.1 min · failure · 2026-07-20 00:20 UTC Tests · 4.9 min · failure · 2026-07-20 17:55 UTC Lock Threads · 0.1 min · failure · 2026-07-21 00:20 UTC Lock Threads · 0.1 min · failure · 2026-07-22 00:18 UTC Lock Threads · 0.1 min · failure · 2026-07-23 00:20 UTC Lock Threads · 0.2 min · failure · 2026-07-24 00:18 UTC Lock Threads · 0.1 min · failure · 2026-07-25 00:21 UTC Lock Threads · 0.1 min · failure · 2026-07-26 00:21 UTC Lock Threads · 0.1 min · failure · 2026-07-27 00:21 UTC Lock Threads · 0.2 min · failure · 2026-07-28 00:19 UTC Lock Threads · 0.1 min · failure · 2026-07-29 00:18 UTC Lock Threads · 0.1 min · failure · 2026-07-30 00:19 UTC Lock Threads · 0.1 min · failure · 2026-07-31 00:21 UTC Lock Threads · 0.1 min · failure · 2026-08-01 00:20 UTC wall-clock duration per run; skipped/cancelled runs excluded
Workflow durations — typical (p50) vs bad day (p95), decisive runs only 0 1.25 2.5 3.75 5 min Lock ThreadsLock Threads Lock Threads · p95 0.1 min (23 runs) Lock Threads · p50 0.1 min (23 runs) 0.1 / 0.2 Type CheckType Check Type Check · p95 0.5 min (14 runs) Type Check · p50 0.4 min (14 runs) 0.4 / 0.5 TestsTests Tests · p95 4.9 min (13 runs) Tests · p50 4.6 min (13 runs) 4.6 / 4.9 Lint codeLint code Lint code · p95 0.5 min (13 runs) Lint code · p50 0.4 min (13 runs) 0.4 / 0.5 CodeQLCodeQL CodeQL · p95 1.2 min (12 runs) CodeQL · p50 1.1 min (12 runs) 1.1 / 1.2 GitHub Actions Security Analysis with zizmor 🌈GitHub Actions Security Analy… GitHub Actions Security Analysis with zizmor 🌈 · p95 0.5 min (9 runs) GitHub Actions Security Analysis with zizmor 🌈 · p50 0.3 min (9 runs) 0.4 / 0.5

Workflow checkup (8 files)

ruleseveritylocationmessage
D002warning.github/workflows/close-issues.yml:11job close_qa has no timeout-minutes (default is 360): one hung step can burn 6 hours of runner time
D002warning.github/workflows/close-issues.yml:25job close_feature_request has no timeout-minutes (default is 360): one hung step can burn 6 hours of runner time
D001warning.github/workflows/codeql-analysis.yml:9pull_request workflow has no concurrency group: pushing new commits leaves superseded runs burning minutes
D014info.github/workflows/codeql-analysis.yml:15cron 0 23 * * 0 fires at minute 0 — the peak-load window where GitHub delays and sometimes skips scheduled runs
D002warning.github/workflows/codeql-analysis.yml:21job analyze has no timeout-minutes (default is 360): one hung step can burn 6 hours of runner time
D001warning.github/workflows/lint.yml:3pull_request workflow has no concurrency group: pushing new commits leaves superseded runs burning minutes
D013warning.github/workflows/lint.yml:3triggers on both push (all branches) and pull_request: every commit to a PR from this repo runs CI twice
D003warning.github/workflows/lint.yml:18actions/setup-python without cache: input re-downloads dependencies on every run
D014info.github/workflows/lock-issues.yml:5cron 0 0 * * * fires at minute 0 — the peak-load window where GitHub delays and sometimes skips scheduled runs
D002warning.github/workflows/lock-issues.yml:12job action has no timeout-minutes (default is 360): one hung step can burn 6 hours of runner time
D002warning.github/workflows/publish.yml:18job build has no timeout-minutes (default is 360): one hung step can burn 6 hours of runner time
D003warning.github/workflows/publish.yml:31actions/setup-python without cache: input re-downloads dependencies on every run
D002warning.github/workflows/publish.yml:52job publish has no timeout-minutes (default is 360): one hung step can burn 6 hours of runner time
D002warning.github/workflows/publish.yml:74job publish-test-pypi has no timeout-minutes (default is 360): one hung step can burn 6 hours of runner time
D001warning.github/workflows/run-tests.yml:3pull_request workflow has no concurrency group: pushing new commits leaves superseded runs burning minutes
D013warning.github/workflows/run-tests.yml:3triggers on both push (all branches) and pull_request: every commit to a PR from this repo runs CI twice
D011warning.github/workflows/run-tests.yml:15job build matrix expands to 24 jobs per trigger
D002warning.github/workflows/run-tests.yml:41job no_chardet has no timeout-minutes (default is 360): one hung step can burn 6 hours of runner time
D003warning.github/workflows/run-tests.yml:52actions/setup-python without cache: input re-downloads dependencies on every run
D002warning.github/workflows/run-tests.yml:63job urllib3 has no timeout-minutes (default is 360): one hung step can burn 6 hours of runner time
D003warning.github/workflows/run-tests.yml:74actions/setup-python without cache: input re-downloads dependencies on every run
D001warning.github/workflows/typecheck.yml:3pull_request workflow has no concurrency group: pushing new commits leaves superseded runs burning minutes
D013warning.github/workflows/typecheck.yml:3triggers on both push (all branches) and pull_request: every commit to a PR from this repo runs CI twice
D003warning.github/workflows/typecheck.yml:22actions/setup-python without cache: input re-downloads dependencies on every run
D001warning.github/workflows/zizmor.yml:5pull_request workflow has no concurrency group: pushing new commits leaves superseded runs burning minutes
D002warning.github/workflows/zizmor.yml:13job zizmor has no timeout-minutes (default is 360): one hung step can burn 6 hours of runner time

Run history: psf/requests (last 120 runs)

workflowrunssuccessp50p95
Lock Threads230%0.1m0.1m
Type Check20100%0.4m0.5m
Tests1992%4.6m4.9m
Lint code19100%0.4m0.5m
CodeQL18100%1.1m1.2m
GitHub Actions Security Analysis with zizmor 🌈15100%0.3m0.5m
pre_commit in /. - Update #14685617441100%0.8m0.8m
github_actions in /. - Update #14685565511100%4.6m4.6m
pre_commit in /. - Update #14874285551100%0.9m0.9m
github_actions in /. - Update #14874195781100%1.1m1.1m
pre_commit in /. - Update #14590267981100%1.0m1.0m
github_actions in /. - Update #14590217371100%4.1m4.1m

Flaky jobs (failed and passed on the same commit):

jobworkflowflaky commitswasted minutes
build (3.12, windows-latest)Tests114
build (3.14, windows-latest)Tests14
build (3.10, windows-latest)Tests14

Flaky tests (seen failing in 4 of 4 flaky-failure logs; the same commit also passed):

testframeworkfailscommitsjob
tests/test_requests.py::TestRequests::test_pyopenssl_redirectpytest42build

Matrix balance (a matrix finishes when its slowest shard does; billable minutes unchanged — this is PR feedback latency):

jobworkflowshardswall p50even-split p50waiting on straggler
buildTests234.5m2.6m1.9m

Worst: build — slowest shard (3.15-dev, windows-latest) 4.5m vs fastest (3.12, ubuntu-22.04) 1.6m (median of 12 runs).

Wasted compute: 1055 of 4490 minutes (failed runs 9 + retries 1045).

Estimated cost (GitHub-hosted rates; free for public repos on standard runners): $44.93 for the sample (5616 billable min), of which $10.60 went to failures/retries and $9.01 to per-job minute round-up.

Cache: 0 caches, 0 MB (0% of the 10 GB limit); 0 MB stale (unused 7+ days), 0 MB pinned to PR refs.

Artifacts: 18 total; 0 MB not yet expired in the 18 most recent. Top producer: dist (10 uploads, 2 MB, kept 5d).

Cache hit rate (12 sampled job logs): 100% — 1 restores: 1 hits, 0 partial, 0 misses.

Top wins

  1. Cut failures and retries~$14.18/mo — 9 failed-run min + 1045 retried-attempt min bought nothing ($10.60 of the sampled spend); worst flake: "build (3.12, windows-latest)" in "Tests"; most-seen flaky test: "tests/test_requests.py::TestRequests::test_pyopenssl_redirect" (pytest, failed in 4 sampled logs)
  2. Consolidate tiny jobs~$12.05/mo — per-job round-up billed 1126 min the jobs never used (20% of spend) — merge short jobs or shrink the matrix
  3. Stop double-running PR pushes — 3 workflows trigger on both unscoped push and pull_request — every PR commit runs twice; scope push to your default branch (see: gha-doctor --explain D013)
  4. Cache dependencies — 5 setup steps download the same dependencies every run (gha-doctor --fix handles this (D003))
  5. Cancel superseded runs — 5 workflows have no concurrency group — runs for already-replaced commits keep burning minutes (gha-doctor --fix handles this (D001))

dollar wins projected to 30 days from the 22.4-day run sample; private-repo rates, public repos run free.

Health score: F (27/100)

Basis: static checks + run history.

ComponentDeductedMaxDetail
workflow hygiene−303024 warning(s), 2 info finding(s) across 8 file(s)
success rate−16.72573% of 90 decisive runs succeeded (skipped/cancelled not counted)
queue time−0.15average 3 s waiting for a runner
flakiness−15153 jobs failed AND passed on the same commit
wasted minutes−11.71523% of sampled compute minutes went to failed runs or retries
cache hit rate−010100% of 1 sampled restores hit