Skip to content

chore(ci): pin every action reference to a published release tag - #217

Open
memosr wants to merge 2 commits into
circlefin:mainfrom
memosr:chore/pin-ci-actions
Open

chore(ci): pin every action reference to a published release tag#217
memosr wants to merge 2 commits into
circlefin:mainfrom
memosr:chore/pin-ci-actions

Conversation

@memosr

@memosr memosr commented Jul 24, 2026

Copy link
Copy Markdown

Summary

Every uses: reference in the repo now pins to a full-length commit SHA that resolves to a published release tag.

Two parts:

  1. ci.yml was the only workflow with unpinned references. 11 uses: lines across 3 actions are now SHA-pinned.
  2. release-binaries.yaml had two stale pins, refreshed here rather than deferred, per review feedback.

ci.yml

11 uses: lines across 3 actions:

  • actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 (v1.17.0)
  • foundry-rs/foundry-toolchain@b00af27efadbc7b4ca8b82abbd903b17cc874d2a (v1.9.0)
  • taiki-e/install-action@7572810d7dd469b651bb7793945692cf78da5dd7 (v2.85.0)

release-binaries.yaml

  • actions-rust-lang/setup-rust-toolchain: v1.15.4 (150fca88) to v1.17.0 (166cdcfd), now byte-identical to the pin in ci.yml. This closes the gap where the release job installed its toolchain through a different action version than the one CI validated against.
  • taiki-e/install-action: a661f9d0 to v2.85.0 (7572810d). The old SHA carries no tag, is not an ancestor of the action's default branch, and dates to 2025-07-01, so the sccache install step was pinned to a point that could not be traced back to any release.

Verification

  • Every SHA was resolved via gh api repos/<owner>/<repo>/git/ref/tags/<tag>, dereferencing annotated tags where present, then independently re-fetched with gh api repos/<owner>/<repo>/commits/<sha>, which echoed back the same SHA. Nothing was hand-written.
  • grep -E 'uses: .*@(v[0-9]|main|master)' .github/workflows/*.yml returns no matches.
  • Audited every remaining pin in release-binaries.yaml: actions/checkout v6.0.3, actions/github-script v9.0.0, actions/upload-artifact v7.0.1, actions/download-artifact v8.0.1 and crazy-max/ghaction-import-gpg v7.0.0 all resolve cleanly to published tags. No other stale pin.
  • actionlint on both files reports no new findings.

Scope

uses: lines only, across two files. No indentation, ordering, or with: block changes.

Worth watching after merge: install-action moves roughly 13 months. The release job will not exercise it until the next tag build.

@memosr

memosr commented Jul 24, 2026

Copy link
Copy Markdown
Author

Worth noting this aligns with StepSecurity, which the repo already runs: pinning actions to full-length commit SHAs is one of its core recommendations. ci.yml was the only workflow not yet following it.

@osr21

osr21 commented Jul 24, 2026

Copy link
Copy Markdown

Independently verified all three SHAs against each tag ref via the GitHub API — all match:

Action Tag SHA in PR
actions-rust-lang/setup-rust-toolchain v1.17.0 166cdcfd
foundry-rs/foundry-toolchain v1.9.0 b00af27e
taiki-e/install-action v2.85.0 7572810d

On the toolchain version gap: I'd lean toward resolving it in this PR rather than a follow-up. release-binaries.yaml pins setup-rust-toolchain at v1.15.4 (150fca88); ci.yml now pins v1.17.0 (166cdcfd). The practical risk is a format check or lint that passes in CI against v1.17.0's rustfmt/clippy but behaves differently at release time under v1.15.4 (or vice versa). It's a small surface area, but it's exactly the kind of subtle drift that makes "it passed CI" an unreliable signal for the release job.

Aligning both files to v1.17.0 is two characters changed in release-binaries.yaml (150fca883cd4034361b621bd4e6a9d34e5143606166cdcfd11aee3cb47222f9ddb555ce30ddb9659). Deferring it means the gap persists until someone notices a divergence — and at that point the root cause will be harder to trace.

@memosr memosr changed the title chore(ci): pin unpinned actions in ci.yml to SHAs chore(ci): pin every action reference to a published release tag Jul 24, 2026
@memosr

memosr commented Jul 24, 2026

Copy link
Copy Markdown
Author

Good call, folded it in rather than deferring. release-binaries.yaml now pins setup-rust-toolchain to the same v1.17.0 SHA ci.yml uses (166cdcfd), so CI and the release job install the toolchain through the same action version.

While in that file I also repinned taiki-e/install-action: it sat at a661f9d0, a 2025-07-01 commit that carries no tag and is not an ancestor of the action's default branch, so the sccache install step could not be traced back to any release. Now v2.85.0 (7572810d).

Audited the remaining pins in that file as well, all resolve cleanly to published tags. Nothing else was stale.

@osr21

osr21 commented Jul 24, 2026

Copy link
Copy Markdown

Verified the updated branch end-to-end. Every uses: SHA in both files now resolves to a published tag:

New / changed pins (this PR)

Action Tag SHA
actions-rust-lang/setup-rust-toolchain v1.17.0 166cdcfd
taiki-e/install-action v2.85.0 7572810d
actions/github-script v9.0.0 3a2844b7

Pre-existing pins in release-binaries.yaml (audited as clean — independently confirmed)

Action Tag SHA
actions/checkout v6.0.3 df4cb1c0
actions/upload-artifact v7.0.1 043fb46d
actions/download-artifact v8.0.1 3e5f45b2
crazy-max/ghaction-import-gpg v7.0.0 2dc316de

On the old a661f9d0 SHA: compared it against taiki-e/install-action main via the GitHub compare API — status diverged, 2075 commits ahead and 1 behind. Definitively not an ancestor of the default branch, consistent with the description.

No unpinned uses: lines remain in either file. Both workflows are fully SHA-pinned and consistent with each other on setup-rust-toolchain.

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.

2 participants