ci: pin GitHub Actions references to full-length commit SHAs#1442
Conversation
🔴 Impact Analysis — PR #1442Risk tier: 🔴 CRITICAL 📊 Summary
🎯 Risk Factors
📦 Modules Affectedci-workflows (21 files)
root (11 files)
squad-cli (10 files)
squad-sdk (10 files)
templates (10 files)
This report is generated automatically for every PR. See #733 for details. |
🛫 PR Readiness Check
PR Scope: 🔧 Infrastructure
|
| Status | Check | Details |
|---|---|---|
| ✅ | Single commit | 1 commit — clean history |
| ✅ | Not in draft | Ready for review |
| ✅ | Branch up to date | Up to date with dev |
| ❌ | Copilot review | No Copilot review yet — it may still be processing |
| ✅ | Changeset present | Changeset file found |
| ✅ | Scope clean | No .squad/ or docs/proposals/ files |
| ✅ | No merge conflicts | No merge conflicts |
| ✅ | Copilot threads resolved | No Copilot review threads |
| ✅ | CI passing | All checks passing |
Files Changed (62 files, +178 −172)
| File | +/− |
|---|---|
.changeset/fix-1441-pin-actions-sha.md |
+6 −0 |
.github/actions/setup-squad-node/action.yml |
+1 −1 |
.github/workflows/squad-agents-ai-ci.yml |
+4 −4 |
.github/workflows/squad-agents-ai-release.yml |
+4 −4 |
.github/workflows/squad-ci.yml |
+11 −11 |
.github/workflows/squad-docs-links.yml |
+3 −3 |
.github/workflows/squad-docs.yml |
+4 −4 |
.github/workflows/squad-heartbeat.yml |
+5 −5 |
.github/workflows/squad-impact.yml |
+3 −3 |
.github/workflows/squad-insider-publish.yml |
+2 −2 |
.github/workflows/squad-issue-assign.yml |
+4 −4 |
.github/workflows/squad-label-enforce.yml |
+2 −2 |
.github/workflows/squad-npm-publish.yml |
+7 −7 |
.github/workflows/squad-pr-nudge.yml |
+1 −1 |
.github/workflows/squad-pr-readiness.yml |
+1 −1 |
.github/workflows/squad-preview.yml |
+2 −2 |
.github/workflows/squad-promote.yml |
+2 −2 |
.github/workflows/squad-release.yml |
+2 −2 |
.github/workflows/squad-repo-health.yml |
+12 −12 |
.github/workflows/squad-scope-check.yml |
+1 −1 |
.github/workflows/squad-triage.yml |
+3 −3 |
.github/workflows/sync-squad-labels.yml |
+2 −2 |
.squad-templates/workflows/squad-ci.yml |
+2 −2 |
.squad-templates/workflows/squad-docs.yml |
+4 −4 |
.squad-templates/workflows/squad-heartbeat.yml |
+3 −3 |
.squad-templates/workflows/squad-issue-assign.yml |
+3 −3 |
.squad-templates/workflows/squad-label-enforce.yml |
+2 −2 |
.squad-templates/workflows/squad-preview.yml |
+2 −2 |
.squad-templates/workflows/squad-promote.yml |
+2 −2 |
.squad-templates/workflows/squad-release.yml |
+2 −2 |
.squad-templates/workflows/squad-triage.yml |
+2 −2 |
.squad-templates/workflows/sync-squad-labels.yml |
+2 −2 |
packages/squad-cli/templates/workflows/squad-ci.yml |
+2 −2 |
packages/squad-cli/templates/workflows/squad-docs.yml |
+4 −4 |
packages/squad-cli/templates/workflows/squad-heartbeat.yml |
+3 −3 |
packages/squad-cli/templates/workflows/squad-issue-assign.yml |
+3 −3 |
packages/squad-cli/templates/workflows/squad-label-enforce.yml |
+2 −2 |
packages/squad-cli/templates/workflows/squad-preview.yml |
+2 −2 |
packages/squad-cli/templates/workflows/squad-promote.yml |
+2 −2 |
packages/squad-cli/templates/workflows/squad-release.yml |
+2 −2 |
packages/squad-cli/templates/workflows/squad-triage.yml |
+2 −2 |
packages/squad-cli/templates/workflows/sync-squad-labels.yml |
+2 −2 |
packages/squad-sdk/templates/workflows/squad-ci.yml |
+2 −2 |
packages/squad-sdk/templates/workflows/squad-docs.yml |
+4 −4 |
packages/squad-sdk/templates/workflows/squad-heartbeat.yml |
+3 −3 |
packages/squad-sdk/templates/workflows/squad-issue-assign.yml |
+3 −3 |
packages/squad-sdk/templates/workflows/squad-label-enforce.yml |
+2 −2 |
packages/squad-sdk/templates/workflows/squad-preview.yml |
+2 −2 |
packages/squad-sdk/templates/workflows/squad-promote.yml |
+2 −2 |
packages/squad-sdk/templates/workflows/squad-release.yml |
+2 −2 |
| ... | +12 more files |
Total: +178 −172
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
🏗️ Architectural Review
Automated architectural review — informational only. |
Every uses: reference across .github/workflows/*.yml (and the local setup-squad-node composite action they call into) pointed at a floating version tag (@v7, @v6, etc.) instead of an immutable commit SHA. Orgs that require SHA-pinned actions as a supply-chain policy can't adopt Squad's shipped workflows without hand-patching them, and re-patching again on every squad upgrade. Resolved each of the 10 unique action@tag pairs in use to its current commit SHA via the GitHub API and rewrote every uses: line to owner/repo@<sha> #vX, keeping the original version as a trailing comment for readability/auditability. The two ./.github/actions/... local action references are untouched — they have no tag to pin, they're already pinned by living in-repo. Also pinned the same 10 shipped workflow templates (squad-ci.yml, squad-docs.yml, squad-heartbeat.yml, squad-issue-assign.yml, squad-label-enforce.yml, squad-preview.yml, squad-promote.yml, squad-release.yml, squad-triage.yml, sync-squad-labels.yml) across all 4 template locations (.squad-templates/ canonical source, plus its 3 synced mirrors: templates/, packages/squad-cli/templates/, packages/squad-sdk/templates/) so squad init/upgrade ships pinned workflows too, not just this repo's own dogfooded copies. These templates use older tags than .github/workflows (checkout@v4 vs v7, github-script@v7 vs v9, etc.) — pinned each to its own existing tag rather than silently bumping versions, since a version bump is a separate concern from pinning. squad-insider-release.yml (template) was left untouched: it has no .github/workflows counterpart, it's a distinct downstream-only workflow (different triggers/jobs/permissions entirely, not a sync pair with squad-insider-publish.yml). 61 files, 172 lines changed, no other content touched. Verified all changed workflow/action YAML still parses with js-yaml. Added a changeset since this now touches governed template paths. Fixes bradygaster#1441 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
e391d81 to
3b7e5cc
Compare
|
fixed the flagged sync gap — pinned the same 10 workflow templates across .squad-templates/ and its 3 mirrors. left squad-insider-release.yml alone though, it's got no .github/workflows twin (checked, closest name is squad-insider-publish.yml but the triggers/jobs/permissions are completely different), so it's not part of this sync at all. |
tamirdresher
left a comment
There was a problem hiding this comment.
Security-reviewed and approved. SHA pinning eliminates tag-hijacking supply-chain risk across all workflows. All 10 action@SHA pairs verified, trailing comments preserve readability, and both .github/workflows/ and .squad-templates/ are in sync. Excellent security hardening. ✅
tamirdresher
left a comment
There was a problem hiding this comment.
✅ Reviewed by Squad security team (Worf). All SHAs verified correct against GitHub API — including annotated-tag dereferencing. Notably, lycheeverse/lychee-action v2 tag was force-pushed to a different commit during review, proving the exact supply-chain risk this PR mitigates. Dependabot already configured for weekly SHA maintenance. One follow-up: file tracking issue for squad-insider-release.yml template (still unpinned, documented waiver).
|
Opened #1462 to track pinning squad-insider-release.yml once the waiver is lifted. Thanks for catching the lychee-action force-push — good timing. |
What
Every
uses:reference across.github/workflows/*.yml(and the localsetup-squad-nodecomposite action) is rewritten from a floating version tag (@v7,@v6, etc.) to a pinned, full-length commit SHA, with the original version kept as a trailing comment for readability. Update: the same pinning is now also applied to the 10 shipped workflow templates in.squad-templates/workflows/and its 3 synced mirrors (templates/,packages/squad-cli/templates/,packages/squad-sdk/templates/), sosquad init/squad upgradeinstalls pinned workflows too — not just this repo's own dogfooded copies.Why
Closes #1441
Many GitHub Enterprises/orgs require every action reference in a workflow to be pinned to a full commit SHA as a supply-chain security policy. Squad's shipped workflows currently use floating tags, so any org with that policy can't adopt them as-is — they have to hand-patch every workflow file after
squad init/squad upgrade, and re-patch again on the next upgrade.How
Resolved each of the 10 unique
action@tagpairs actually in use in.github/workflows/(actions/checkout@v7,actions/setup-node@v6,actions/github-script@v9,actions/setup-dotnet@v5,actions/upload-artifact@v7,actions/upload-pages-artifact@v5,actions/deploy-pages@v5,lycheeverse/lychee-action@v2,NuGet/login@v1,peter-evans/create-issue-from-file@v6) to its current commit SHA via the GitHub REST API (repos/{owner}/{repo}/commits/{tag}), then rewrote everyuses:line to:matching the format from the issue's own acceptance criteria. Also pinned
actions/setup-node@v4inside.github/actions/setup-squad-node/action.yml— it's outside.github/workflows/strictly, but it's a composite action invoked by several of these workflows and carries the same unpinned-reference problem, so leaving it out would defeat the point.The two
uses: ./.github/actions/setup-squad-nodereferences are untouched — they're local path references with no tag to resolve, already "pinned" by living in-repo.Template sync: the Architectural Review bot correctly flagged that
.github/workflows/changed without the matching template locations. Checkedscripts/sync-templates.mjs—.squad-templates/is the canonical source, mirrored byte-for-byte intotemplates/,packages/squad-cli/templates/,packages/squad-sdk/templates/. The 10 workflow templates that share a filename with a.github/workflows/file (squad-ci.yml,squad-docs.yml,squad-heartbeat.yml,squad-issue-assign.yml,squad-label-enforce.yml,squad-preview.yml,squad-promote.yml,squad-release.yml,squad-triage.yml,sync-squad-labels.yml) got the same treatment — but note these templates already carry older tags than.github/workflows(checkout@v4notv7,github-script@v7notv9,setup-node@v4notv6,upload-pages-artifact@v3notv5,deploy-pages@v4notv5), because.github/workflows/has accumulated repo-specific CI hardening (rate-limit checks, concurrency groups, etc.) that was never backported to the shipped templates. Rather than silently bumping every template to match.github/workflows's newer versions — a separate, unrelated concern — each template's own existing tag was pinned to its own SHA, keeping this PR strictly about pinning, not upgrading.squad-insider-release.yml(template-only, no.github/workflowscounterpart) was not touched — see PR comment for why.No other content in any touched file was changed — every diff line is a
uses:swap only.Testing
js-yaml(noactionlintbinary installable in this environment).npm run lint— passes.uses: owner/repo@<40-hex-sha> #vX— matches everywhere, zero exceptions.git diff --check— clean, no whitespace/CRLF noise..squad-templates/after the edit (diff -q, no output)..changeset/fix-1441-pin-actions-sha.md, patch bump for both packages) — this PR now touches governed template paths (.squad-templates/,templates/,packages/*/templates/)PR Readiness Checklist
Branch & Commit
devdevgit diff --cached --stat)Build & Test
npm run build— N/A, no code changed, but passes regardlessnpm test— N/A, no code changed (no test suite covers workflow YAML content)npm run lintpassesnpm run lint:eslint— N/A, no.ts/.jsfiles changedChangeset
Docs
Exports
Breaking Changes
None. Pinning to a SHA that resolves to the exact same commit as the tag it replaces is behavior-neutral.
Waivers
None.