Skip to content

Pin GitHub Actions to commit SHAs + enforce in CI#65

Merged
nrynss merged 2 commits into
mainfrom
packaging/sha-pin-actions
Jun 26, 2026
Merged

Pin GitHub Actions to commit SHAs + enforce in CI#65
nrynss merged 2 commits into
mainfrom
packaging/sha-pin-actions

Conversation

@nrynss

@nrynss nrynss commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

What

Pins every GitHub Action to a full 40-character commit SHA and adds a CI guard to keep it that way.

  • release.yml (dist-generated): pinned actions/checkout@v6, actions/upload-artifact@v7, actions/download-artifact@v8 to their commit SHAs (with # vX comments). dist does not SHA-pin natively.
  • ci.yml: new pin-check job — fails CI if any uses: across .github/workflows/ isn't a 40-char SHA (local ./ actions exempt). ci.yml + publish-crate.yml were already pinned.
  • dist-workspace.toml: documents that dist generate/dist init will revert release.yml to tag pins, and that pin-check will catch it.

Why

Mutable tags (@v6) can be silently repointed at malicious code if an action or maintainer account is compromised. A commit SHA is immutable — the only way to use an action as an immutable release. See GitHub's guidance.

Caveat (documented in dist-workspace.toml)

dist generate --check will now report release.yml as out of sync (it's intentionally hand-pinned). It is not run in CI, so nothing breaks — but if you regenerate the workflow, re-pin the actions; pin-check will flag it if you forget.

Validated

yq parses all workflows · pin-check logic run locally → all actions SHA-pinned ✓

🤖 Generated with Claude Code

nrynss and others added 2 commits June 26, 2026 12:50
dist emits mutable tag pins (actions/checkout@v6, ...) in the generated
release.yml. Pin all three actions to full commit SHAs for supply-chain
safety, and add a `pin-check` CI job that fails if any workflow action is
not SHA-pinned — which also catches a future `dist generate` reverting
them. The regeneration caveat is documented in dist-workspace.toml.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
`dist plan` validates that release.yml matches what dist would generate and
fails on the hand-pinned (commit-SHA) actions. allow-dirty = ["ci"] is dist's
supported escape hatch for hand-edited CI; the pin-check job still enforces
that the actions stay SHA-pinned.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@nrynss nrynss merged commit ab0d196 into main Jun 26, 2026
9 checks passed
@nrynss nrynss deleted the packaging/sha-pin-actions branch June 26, 2026 07:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant