Conversation
Pass workflow_dispatch inputs to shell scripts through env instead of
${{ }} substitution, and validate the npm dist-tag alongside the version
in the first step so a malformed tag fails before install or publish.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
This PR hardens .github/workflows/release.yaml against command injection from workflow_dispatch inputs in the job that publishes to npm with provenance.
- Untrusted inputs moved out of scripts —
versionandtagnow reach scripts only throughenv(VERSIONat job level,TAG_INPUTat step level). No${{ }}expression remains inside anyrun:block, so a crafted value can no longer be executed by the shell. - Validation reordered to run first — the
versionstep now validates the format andexit 1s on mismatch before anything is installed, bumped or published, preserving thelatestpreid guard. - Dist-tag validation added — the resolved tag (explicit input, else preid, else
latest) must match^[a-z][a-z0-9._-]*$before it is written to$GITHUB_OUTPUTand passed topnpm publish --tag. - Boolean skip flags modernized —
skip_bump/skip_changeloguse typed!inputs.skip_*, andskip_git_checkbuildsNO_GIT_CHECKSfrom the typed boolean; behavior is equivalent to the oldgithub.event.inputs.* != 'true'string checks.
Verified independently: the anchored regexes reject newline, space and option-like payloads; inputs.<name> preserves boolean type for workflow_dispatch (per GitHub docs), so !inputs.skip_* is correct; and the $GITHUB_OUTPUT write is regex-gated, so no output-key injection. The remaining unquoted $NO_GIT_CHECKS is safe as documented in the PR description (empty expansion adds no argument).
DeepSeek Flash (default — pick a model for stronger reviews) | 𝕏

The release workflow substituted its
workflow_dispatchinputs (version,tag) directly into shell scripts, so a crafted value could run arbitrary commands in the job that publishes to npm with provenance (id-token: write). The version check didn't help, because it ran after the substituted line had already executed. Inputs now reach the scripts only as environment variables, and both the version and the dist-tag are validated in the first step, before anything is installed, bumped or published.Fixes
versionortaginputs no longer execute: no${{ }}expression remains inside anyrun:scriptx --registry=…) now fail the run immediately instead of reachingpnpm publisha-z,0-9,.,_or-Testing
act, with bump/changelog/publish commands replaced by argument printers. Valid inputs (stable, prerelease, explicit tag, every skip flag on/off) produce identical commands; payloads that executed on the original are rejected in the first step$NO_GIT_CHECKS, so an empty value adds no argument