Skip to content

ci: pin GitHub Actions references to full-length commit SHAs#1442

Merged
tamirdresher merged 1 commit into
bradygaster:devfrom
omercangumus:omercangumus/1441-pin-actions-sha
Jul 13, 2026
Merged

ci: pin GitHub Actions references to full-length commit SHAs#1442
tamirdresher merged 1 commit into
bradygaster:devfrom
omercangumus:omercangumus/1441-pin-actions-sha

Conversation

@omercangumus

@omercangumus omercangumus commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

What

Every uses: reference across .github/workflows/*.yml (and the local setup-squad-node composite 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/), so squad init/squad upgrade installs 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@tag pairs 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 every uses: line to:

uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7

matching the format from the issue's own acceptance criteria. Also pinned actions/setup-node@v4 inside .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-node references 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. Checked scripts/sync-templates.mjs.squad-templates/ is the canonical source, mirrored byte-for-byte into templates/, 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@v4 not v7, github-script@v7 not v9, setup-node@v4 not v6, upload-pages-artifact@v3 not v5, deploy-pages@v4 not v5), 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/workflows counterpart) 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

  • Verified all changed YAML files still parse with js-yaml (no actionlint binary installable in this environment).
  • npm run lint — passes.
  • Diffed every added line against the pattern uses: owner/repo@<40-hex-sha> #vX — matches everywhere, zero exceptions.
  • git diff --check — clean, no whitespace/CRLF noise.
  • Confirmed the 3 mirror directories stayed byte-identical to .squad-templates/ after the edit (diff -q, no output).

⚠️ Quick Check

  • Changeset added (.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

  • Branch created from dev
  • Branch is up to date with dev
  • Verified diff contains only intended changes (git diff --cached --stat)
  • PR is not in draft mode
  • Commit history is clean (single commit)

Build & Test

  • npm run build — N/A, no code changed, but passes regardless
  • npm test — N/A, no code changed (no test suite covers workflow YAML content)
  • npm run lint passes
  • npm run lint:eslint — N/A, no .ts/.js files changed

Changeset

  • Changeset added — governed template paths touched

Docs

  • N/A — internal CI hardening, no user-facing API change

Exports

  • N/A — no SDK changes

Breaking Changes

None. Pinning to a SHA that resolves to the exact same commit as the tag it replaces is behavior-neutral.

Waivers

None.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

🔴 Impact Analysis — PR #1442

Risk tier: 🔴 CRITICAL

📊 Summary

Metric Count
Files changed 62
Files added 1
Files modified 61
Files deleted 0
Modules touched 5

🎯 Risk Factors

  • 62 files changed (>50 → CRITICAL)
  • 5 modules touched (5-8 → HIGH)

📦 Modules Affected

ci-workflows (21 files)
  • .github/actions/setup-squad-node/action.yml
  • .github/workflows/squad-agents-ai-ci.yml
  • .github/workflows/squad-agents-ai-release.yml
  • .github/workflows/squad-ci.yml
  • .github/workflows/squad-docs-links.yml
  • .github/workflows/squad-docs.yml
  • .github/workflows/squad-heartbeat.yml
  • .github/workflows/squad-impact.yml
  • .github/workflows/squad-insider-publish.yml
  • .github/workflows/squad-issue-assign.yml
  • .github/workflows/squad-label-enforce.yml
  • .github/workflows/squad-npm-publish.yml
  • .github/workflows/squad-pr-nudge.yml
  • .github/workflows/squad-pr-readiness.yml
  • .github/workflows/squad-preview.yml
  • .github/workflows/squad-promote.yml
  • .github/workflows/squad-release.yml
  • .github/workflows/squad-repo-health.yml
  • .github/workflows/squad-scope-check.yml
  • .github/workflows/squad-triage.yml
  • .github/workflows/sync-squad-labels.yml
root (11 files)
  • .changeset/fix-1441-pin-actions-sha.md
  • templates/workflows/squad-ci.yml
  • templates/workflows/squad-docs.yml
  • templates/workflows/squad-heartbeat.yml
  • templates/workflows/squad-issue-assign.yml
  • templates/workflows/squad-label-enforce.yml
  • templates/workflows/squad-preview.yml
  • templates/workflows/squad-promote.yml
  • templates/workflows/squad-release.yml
  • templates/workflows/squad-triage.yml
  • templates/workflows/sync-squad-labels.yml
squad-cli (10 files)
  • packages/squad-cli/templates/workflows/squad-ci.yml
  • packages/squad-cli/templates/workflows/squad-docs.yml
  • packages/squad-cli/templates/workflows/squad-heartbeat.yml
  • packages/squad-cli/templates/workflows/squad-issue-assign.yml
  • packages/squad-cli/templates/workflows/squad-label-enforce.yml
  • packages/squad-cli/templates/workflows/squad-preview.yml
  • packages/squad-cli/templates/workflows/squad-promote.yml
  • packages/squad-cli/templates/workflows/squad-release.yml
  • packages/squad-cli/templates/workflows/squad-triage.yml
  • packages/squad-cli/templates/workflows/sync-squad-labels.yml
squad-sdk (10 files)
  • packages/squad-sdk/templates/workflows/squad-ci.yml
  • packages/squad-sdk/templates/workflows/squad-docs.yml
  • packages/squad-sdk/templates/workflows/squad-heartbeat.yml
  • packages/squad-sdk/templates/workflows/squad-issue-assign.yml
  • packages/squad-sdk/templates/workflows/squad-label-enforce.yml
  • packages/squad-sdk/templates/workflows/squad-preview.yml
  • packages/squad-sdk/templates/workflows/squad-promote.yml
  • packages/squad-sdk/templates/workflows/squad-release.yml
  • packages/squad-sdk/templates/workflows/squad-triage.yml
  • packages/squad-sdk/templates/workflows/sync-squad-labels.yml
templates (10 files)
  • .squad-templates/workflows/squad-ci.yml
  • .squad-templates/workflows/squad-docs.yml
  • .squad-templates/workflows/squad-heartbeat.yml
  • .squad-templates/workflows/squad-issue-assign.yml
  • .squad-templates/workflows/squad-label-enforce.yml
  • .squad-templates/workflows/squad-preview.yml
  • .squad-templates/workflows/squad-promote.yml
  • .squad-templates/workflows/squad-release.yml
  • .squad-templates/workflows/squad-triage.yml
  • .squad-templates/workflows/sync-squad-labels.yml

This report is generated automatically for every PR. See #733 for details.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

🛫 PR Readiness Check

ℹ️ This comment updates on each push. Last checked: commit 3b7e5cc

PR Scope: 🔧 Infrastructure

⚠️ 1 item(s) to address before review

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.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

🏗️ Architectural Review

⚠️ Architectural review: 1 warning(s).

Severity Category Finding Files
🟡 warning sweeping-refactor This PR touches 62 files (62 modified/added, 0 deleted). Large PRs are harder to review — consider splitting if possible.

Automated architectural review — informational only.

@omercangumus
omercangumus marked this pull request as ready for review July 3, 2026 12:15
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>
@omercangumus
omercangumus force-pushed the omercangumus/1441-pin-actions-sha branch from e391d81 to 3b7e5cc Compare July 3, 2026 12:34
@omercangumus

Copy link
Copy Markdown
Contributor Author

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 tamirdresher left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 tamirdresher left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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).

@omercangumus

Copy link
Copy Markdown
Contributor Author

Opened #1462 to track pinning squad-insider-release.yml once the waiver is lifted. Thanks for catching the lychee-action force-push — good timing.

@tamirdresher
tamirdresher merged commit 40e05a7 into bradygaster:dev Jul 13, 2026
8 checks passed
@omercangumus
omercangumus deleted the omercangumus/1441-pin-actions-sha branch July 13, 2026 10:39
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.

Pin GitHub Actions references to a full length commit SHA

2 participants