Why it matters
release.yml runs on every push to main and cuts a version, tag and release without depending on Validate or Blender Smoke. #192 records that main cannot enforce required status checks. Together, a red PR merged to main gets published as a release.
The same job also holds broad write permissions while running a third-party action referenced by a movable tag, which is supply-chain exposure. This is hardening, not a known exploit.
Evidence
.github/workflows/release.yml:3-6: on: push: branches: [main] plus workflow_dispatch, with no workflow_run dependency on Validate or Smoke.
release.yml:8-10: workflow-wide permissions: contents: write, actions: write.
release.yml:~120: uses: …/release-doc-sync@v1, a mutable major tag, running with that write token. Other actions are pinned to tags (actions/checkout@v7), and none are pinned to commit SHAs. drift-check@v1.15 vs release-doc-sync@v1 is also inconsistent.
release.yml:~152: git add -A commits whatever the action wrote. The repo's own CLAUDE.md § Git Staging forbids bulk adds for exactly this reason.
Related: #192 (no required checks), #226 (release push race).
Suggested approach
- Trigger release from
workflow_run on successful Validate and Blender Smoke for the same head_sha. Alternatively, keep push and add a first step that polls the check-suite for the SHA and exits early unless everything is green.
- Move
permissions: to job level, with the minimum per job.
- Pin third-party actions (at least the non-
actions/* ones) to full commit SHAs with a # vX.Y comment. Dependabot github-actions already exists and will keep SHA pins current.
- Replace
git add -A with the explicit files the action owns: VERSION, CHANGELOG.md, CLAUDE.md, ROADMAP.md, .cursor-plugin/plugin.json.
Done when
Why it matters
release.ymlruns on every push tomainand cuts a version, tag and release without depending on Validate or Blender Smoke. #192 records thatmaincannot enforce required status checks. Together, a red PR merged tomaingets published as a release.The same job also holds broad write permissions while running a third-party action referenced by a movable tag, which is supply-chain exposure. This is hardening, not a known exploit.
Evidence
.github/workflows/release.yml:3-6:on: push: branches: [main]plusworkflow_dispatch, with noworkflow_rundependency on Validate or Smoke.release.yml:8-10: workflow-widepermissions: contents: write, actions: write.release.yml:~120:uses: …/release-doc-sync@v1, a mutable major tag, running with that write token. Other actions are pinned to tags (actions/checkout@v7), and none are pinned to commit SHAs.drift-check@v1.15vsrelease-doc-sync@v1is also inconsistent.release.yml:~152:git add -Acommits whatever the action wrote. The repo's ownCLAUDE.md§ Git Staging forbids bulk adds for exactly this reason.Related: #192 (no required checks), #226 (release push race).
Suggested approach
workflow_runon successful Validate and Blender Smoke for the samehead_sha. Alternatively, keeppushand add a first step that polls the check-suite for the SHA and exits early unless everything is green.permissions:to job level, with the minimum per job.actions/*ones) to full commit SHAs with a# vX.Ycomment. Dependabotgithub-actionsalready exists and will keep SHA pins current.git add -Awith the explicit files the action owns:VERSION,CHANGELOG.md,CLAUDE.md,ROADMAP.md,.cursor-plugin/plugin.json.Done when
mainwhose Validate or Smoke run fails produces no tag or release. Prove it once with a deliberately failing check.