Skip to content

chore(ci): generate release notes without Claude (ST-482) - #1496

Merged
Matus Tomlein (matus-tomlein) merged 1 commit into
masterfrom
chore/prepare-release-without-claude
Jul 30, 2026
Merged

chore(ci): generate release notes without Claude (ST-482)#1496
Matus Tomlein (matus-tomlein) merged 1 commit into
masterfrom
chore/prepare-release-without-claude

Conversation

@matus-tomlein

Copy link
Copy Markdown
Contributor

What

Replaces the Claude Code call in the Prepare release PR workflow with deterministic shell scripts, and removes ANTHROPIC_API_KEY from the job.

Addresses ST-482, a Wiz finding on this repo: "Publicly exposed CI workflow with access to secrets vulnerable to script injection". Claude Code should not run in publicly exposed repos.

How commits are classified

  1. Conventional-commit prefixfeat: → New features, fix: → Bug fixes, perf:/refactor: → Improvements. A ! before the colon or a BREAKING CHANGE marker promotes the commit to a Breaking changes section.
  2. Leading imperative verbFix|Resolve|Handle|… → Bug fixes, Add|Introduce|Support|… → New features, Improve|Update|Migrate|… → Improvements. This fallback exists because conventional-commit adoption in this repo is currently well under 25%; a prefix-only classifier would put the large majority of real changes into a single bucket, including obvious bug fixes.
  3. Anything left over → Enhancements.

Chore commits (ci/docs/test/build/style, plus release-automation subjects like Prepare for …) are skipped, matching both the previous prompt instructions and the existing release notes.

New scripts in .github/scripts/:

Script Role
classify-commits.sh Categorises commits, extracts PR/issue refs, filters chores
format-pr-body.sh Grouped markdown bullets, credits external contributors

Script injection hardening

Every workflow input is moved out of inline ${{ }} interpolation into env: vars referenced as "$VAR". Splicing an input directly into a run: block is the injection sink Wiz reported.

Worth noting for triage: the exploit path in the Wiz description ("attackers can exploit this by submitting crafted pull requests, e.g. with malicious titles") does not apply here. This workflow is workflow_dispatch-only — there is no pull_request or issue_comment trigger, so the only injectable input is release_branch, which requires write access to set and is regex-validated against ^release/X\.Y\.Z$ before use. The pattern is fixed regardless, but the CRITICAL rating rested on a vector this workflow did not have.

Verification

Past releases were regenerated from real git history and diffed against the shipped release notes. Remaining differences are cases where a human reworded a commit subject when writing the notes by hand — the scripts faithfully reproduce the commit subject instead. shellcheck is clean.

Follow-up

Once this is merged, the now-unused secret should be deleted:

gh secret delete ANTHROPIC_API_KEY --repo snowplow/snowplow-javascript-tracker

🤖 Generated with Claude Code

Wiz flagged the prepare-release workflow as a publicly exposed workflow
with access to secrets that is vulnerable to script injection (ST-482).
Claude Code should not run in public repos, so replace the two LLM calls
with deterministic shell scripts and remove ANTHROPIC_API_KEY from the job.

The PR body is now generated by scripts; changelogs remain owned by rush.

Commits are classified by:
1. Conventional-commit prefix (feat/fix/perf/refactor; "!" or a
   BREAKING CHANGE marker promotes to breaking).
2. A leading imperative verb, for the many commits in this repo that
   predate conventional commits (adoption is currently well under 25%,
   so a prefix-only classifier would put most changes in one bucket).
3. Anything left over becomes "Enhancements".

Chore commits (ci/docs/test/build/style, release automation) are skipped,
matching the previous prompt behaviour and the existing release notes.

Also move every workflow input out of inline ${{ }} interpolation and into
env: vars referenced as "$VAR". Splicing an input directly into a run:
block is the script-injection sink Wiz reported; these workflows are
workflow_dispatch-only, so the input is not attacker-controlled via pull
requests, but the pattern is fixed regardless.

Verified by regenerating past releases from real history and diffing
against the shipped release notes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 30, 2026 08:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@matus-tomlein
Matus Tomlein (matus-tomlein) merged commit 53f668a into master Jul 30, 2026
7 of 8 checks passed
@matus-tomlein
Matus Tomlein (matus-tomlein) deleted the chore/prepare-release-without-claude branch July 30, 2026 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants