Skip to content

ci: pin star-history workflow actions to commit SHAs and scope its token - #56

Open
Chirag6722 wants to merge 1 commit into
Seeed-Projects:mainfrom
Chirag6722:fix/pin-star-history-action
Open

ci: pin star-history workflow actions to commit SHAs and scope its token#56
Chirag6722 wants to merge 1 commit into
Seeed-Projects:mainfrom
Chirag6722:fix/pin-star-history-action

Conversation

@Chirag6722

Copy link
Copy Markdown

Closes #55

What this changes

.github/workflows/star-history.yml ran narayann7/star-history-action@main — a mutable branch reference — while holding a workflow-wide contents: write token. Because that action is a composite action, its steps (npm ci, render-charts.sh, readme-embed.py) execute inside this repository's runner. Whatever sat on that upstream branch at 00:17 UTC each day ran with permission to push to main of this repo.

before after
actions/checkout @v4 (mutable tag) @08c6903… (v5.0.0)
narayann7/star-history-action @main (mutable branch) @a68d8f9… (v1.0.5)
workflow permissions contents: write contents: read, job-level contents: write
commit/push manual step and the action the action only
concurrency none group: star-history
SHA freshness Dependabot (github-actions, weekly)

Why the manual commit step is removed, not kept

star-history-action already commits and pushes by default (commit: true), and its push does git pull --rebase origin "$branch" first. The workflow's own step re-implemented that without the rebase:

git add assets/star-history/
git commit -m "Update star history chart" || exit 0
git push

Today it is a no-op — the action has already committed, so git commit finds nothing staged and || exit 0 swallows it. That is visible in the run history: every recent scheduled run landed a commit titled chore: update star history [skip ci], which is the action's default message, not this step's. So the step contributes nothing and its only possible effect is a non-fast-forward failure when something lands on main mid-run. The new concurrency group closes the other half of that race.

Why Dependabot is part of this

Pinning to a SHA without automated bumps trades a supply-chain risk for a staleness risk — the pin silently ages out of upstream security fixes. .github/dependabot.yml reads the # v1.0.5 trailing comments and opens a PR when a newer release ships, which is what makes SHA pinning maintainable.

Verification

  • actionlint (v1.7.12) passes on the new workflow — exit 0, no findings.
  • Both files parse as valid YAML; the permission split and both uses: pins were asserted programmatically after the edit.
  • Both pinned SHAs were resolved from their release tags via the GitHub API and confirmed to exist: a68d8f9d67ca20d55b682a264e69152dcf326e9c is the commit behind the annotated tag v1.0.5, and 08c6903cd8c0fde910a37f88322edcfb5dd907a8 is actions/checkout v5.0.0.
  • readme-embed.py at the pinned SHA exits 0 with "star-history markers not found in README; skipping update" when the marker comments are absent, so pinning does not change how this repo's hand-written <picture> block is treated.

Not verified by a live run: I could not dispatch the workflow from my fork — GitHub does not register workflows on a fresh fork without enabling them through the Actions UI, so workflow_dispatch returns 404 there. The behavioural change is confined to removing a step that provably does nothing today; a maintainer can confirm with one manual workflow_dispatch on this branch before merging.

🤖 Generated with Claude Code

The scheduled workflow ran narayann7/star-history-action@main, a mutable
branch reference, while holding a workflow-wide contents: write token. A
composite action's steps execute in this repository's runner, so whatever
sat on that branch at 00:17 UTC each day ran with permission to push to
main.

- Pin both actions to full commit SHAs (checkout v5.0.0, star-history
  v1.0.5) with the version in a trailing comment.
- Add .github/dependabot.yml for the github-actions ecosystem so the
  pinned SHAs still get updated.
- Default the workflow to contents: read and grant write only on the job
  that pushes.
- Drop the manual commit/push step: the action already commits and
  rebases before pushing, while this step pushed without a rebase and
  would fail on a non-fast-forward.
- Add a concurrency group so a manual run cannot race the scheduled one.

Closes Seeed-Projects#55

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

Supply-chain risk: star-history workflow runs an unpinned third-party action with contents: write

1 participant