ci-workflow-doctor
Part of shipsafe — offline deploy-safety skills. Every script is stdlib-only Python 3.8+; nothing leaves the machine.
python3 scripts/lint_workflows.py <repo_root> [--json] # finds .github/workflows itself
Checks:
- PR_TARGET_WITH_CHECKOUT (critical) —
pull_request_target+ checkout of the PR head runs untrusted fork code WITH repo secrets. This is the classic GitHub Actions exfiltration pattern; fix immediately. - MUTABLE_ACTION_REF (high) — third-party actions pinned to tags/branches can be force-pushed by a compromised maintainer. Pin to a 40-char commit SHA. Official
actions/*are exempt. - MISSING_CONCURRENCY (high) — deploy jobs without a concurrency group let two pushes deploy in parallel; the OLDER build can finish last and win. The fix block to suggest is in the script output.
- SECRET_IN_RUN (high) —
${{ secrets.X }}interpolated into run: scripts leaks via shell tracing; pass via env: instead. - NO_TIMEOUT / UNPINNED_RUNNER (low) — hygiene for deploy reliability.
Implementation note: parsing is line-structured and heuristic (zero dependencies, runs anywhere) — on exotic YAML, verify a finding against the file before asserting it.
Exit codes: 0 clean, 1 findings.
All paths below are relative to this skill's directory (ci-workflow-doctor/).