Pin actions by commit sha and fail CI on mutable refs

Merged
MI
1d ago
+824-6

Summary

Pins every GitHub Action by commit sha, and adds a CI guard (scripts/check_immutable_refs.py + a Pinned refs workflow, plus a make lint_immutable_refs target) that fails on tag-only or :latest references. Every pin was resolved and then independently re-verified against upstream (tag -> sha, upstream history, advisories, 7-day supply-chain cooldown with security-release exceptions); the repo has no Dockerfiles, so no image pins or ca-certificates changes apply.

Changes

  • Every GitHub Action pinned as <sha> # <version>, since tags can be moved after review (how tag-rewrite supply-chain attacks land).
  • scripts/check_immutable_refs.py (+ tests), exposed as make lint_immutable_refs (the repo has no make ci) and run by a new "Pinned refs" workflow. It fails on untagged/:latest/tag-only images in Dockerfiles and workflow image: keys, and on any non-sha uses:. # pin-exempt: <reason> on the line above opts out.
  • actions/checkout v3/v4 (node20 or older, EOL) -> v6.1.0; inputs unchanged.
  • psf/black@stable (a moving branch) -> 26.10.1 by sha, with the matching version: "26.10.1" input so the formatter version is fixed too.

Testing

  • python3 scripts/check_immutable_refs.py exits 0
  • black --check and vulture are clean
  • New tests pass
  • make ci (not applicable: no such target)
  • make test: fails at collection with "Environment variable DEV_ENV not found" (no .env in the sandbox); pre-existing and unrelated

Generated by Claude Code