.github/workflows/publish.yml:22 pins a third-party action to a branch:
- name: Set up Quarto
uses: quarto-dev/quarto-actions/setup@HEAD
@HEAD resolves to whatever the tip of that repo's default branch is at the moment the job starts. Every run can execute different code, with no change on our side and nothing in the run log to indicate the action itself moved. Two consequences:
- Supply-chain exposure. Anything merged upstream — including a compromised commit — runs in our workflow immediately. This is the case GitHub's security hardening guide is specifically about.
- Non-reproducible builds. A publish that worked yesterday can fail today with no diff to point at.
The same file already pins quarto-dev/quarto-actions/render@v2, and preview.yml uses quarto-dev/quarto-actions/setup@v2 — so @HEAD here looks like a leftover from debugging rather than a deliberate choice. Worth checking git log on that line for whether a specific unreleased fix was being chased; if so, pin the commit that carries it rather than the branch.
Minimum fix: @v2, matching the sibling call sites.
Broader question this raises
This repo is a template, so every pin propagates into every book created from it. Right now all 16 third-party refs are tag-pinned:
actions/ai-inference@v2 actions/cache/restore@v6
actions/cache/save@v6 actions/checkout@v7
anthropics/claude-code-action@v1 insightsengineering/r-spellcheck-action@v3.0.3
marocchino/sticky-pull-request-comment@v3 quarto-dev/quarto-actions/render@v2
quarto-dev/quarto-actions/setup@HEAD quarto-dev/quarto-actions/setup@v2
r-lib/actions/setup-pandoc@v2 r-lib/actions/setup-r@v2
r-lib/actions/setup-r-dependencies@v2 rossjrw/pr-preview-action@v1
Several are floating major tags (@v2, @v7, @v1), which can move under us on any upstream release.
d-morrison/gha SHA-pins every third-party action with the version in a trailing comment, and lets Dependabot bump them — see its README, "Pinning third-party actions". Adopting the same convention here would be worth doing, since this repo's .github/dependabot.yml already covers github-actions and would keep the pins current.
Fixing @HEAD is the urgent part; the SHA-pinning sweep can be separate if it is easier to review that way.
Found while reviewing IndrajeetPatil/workflows against our own CI, which enforces SHA pinning across all 16 of its workflows.
.github/workflows/publish.yml:22pins a third-party action to a branch:@HEADresolves to whatever the tip of that repo's default branch is at the moment the job starts. Every run can execute different code, with no change on our side and nothing in the run log to indicate the action itself moved. Two consequences:The same file already pins
quarto-dev/quarto-actions/render@v2, andpreview.ymlusesquarto-dev/quarto-actions/setup@v2— so@HEADhere looks like a leftover from debugging rather than a deliberate choice. Worth checkinggit logon that line for whether a specific unreleased fix was being chased; if so, pin the commit that carries it rather than the branch.Minimum fix:
@v2, matching the sibling call sites.Broader question this raises
This repo is a template, so every pin propagates into every book created from it. Right now all 16 third-party refs are tag-pinned:
Several are floating major tags (
@v2,@v7,@v1), which can move under us on any upstream release.d-morrison/ghaSHA-pins every third-party action with the version in a trailing comment, and lets Dependabot bump them — see its README, "Pinning third-party actions". Adopting the same convention here would be worth doing, since this repo's.github/dependabot.ymlalready coversgithub-actionsand would keep the pins current.Fixing
@HEADis the urgent part; the SHA-pinning sweep can be separate if it is easier to review that way.Found while reviewing
IndrajeetPatil/workflowsagainst our own CI, which enforces SHA pinning across all 16 of its workflows.