Route release.yml version through env indirection; pin dev/docs deps - #2
Route release.yml version through env indirection; pin dev/docs deps#2carochacs wants to merge 3 commits into
Conversation
Two LOW hardening items found during a security audit:
- release.yml interpolated ${{ steps.ver.outputs.version }} directly
into two run: shell steps — the classic GitHub Actions
shell-injection pattern. Not exploitable today (the value is
constrained by changelog_extract.py's \d+\.\d+\.\d+ regex), but
fragile if that regex or its input ever changes. Routed through an
env: VERSION var instead, matching the pattern already used in
plugin-validate.yml.
- requirements-dev.txt / requirements-docs.txt left jsonschema,
pytest, ruff, and mkdocs-material fully unpinned, so CI silently
picks up whatever's newest on a given day. Pinned to
minor-version-compatible ranges (~=X.Y). Verified: fresh install,
full pytest suite, ruff, tools/validate.py against both examples,
and tools/check_versions.py all still pass.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018J1NvPtPQZd3cEt6aAbGzG
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
| jsonschema~=4.26 | ||
| pytest~=9.1 | ||
| ruff~=0.16 |
There was a problem hiding this comment.
Ranges permit later minor releases
Two-component compatible-release constraints such as ~=4.26 and ~=9.1 permit all later releases within the same major version, so CI can still silently adopt newer minor versions despite the comments requiring deliberate minor-version upgrades; the same issue applies to mkdocs-material~=9.7 in requirements-docs.txt.
Prompt To Fix With AI
This is a comment left during a code review.
Path: requirements-dev.txt
Line: 10-12
Comment:
**Ranges permit later minor releases**
Two-component compatible-release constraints such as `~=4.26` and `~=9.1` permit all later releases within the same major version, so CI can still silently adopt newer minor versions despite the comments requiring deliberate minor-version upgrades; the same issue applies to `mkdocs-material~=9.7` in `requirements-docs.txt`.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Valid — confirmed directly against packaging.specifiers.SpecifierSet: ~=4.26 accepts 4.27.0, contradicting the comment's stated intent. The third component is load-bearing for PEP 440's compatible-release operator; only ~=X.Y.Z locks the minor version.
Fixed in 6797719: jsonschema~=4.26.0, pytest~=9.1.1, ruff~=0.16.1, mkdocs-material~=9.7.7 (the exact versions already verified installable), plus a comment explaining why the third digit matters so this doesn't regress. Re-verified the full check suite (pytest, ruff, tools/validate.py against both examples, tools/check_versions.py) still passes with the corrected pins, and confirmed via SpecifierSet that each now allows patch drift but rejects the next minor version.
Generated by Claude Code
Greptile review on this PR: PEP 440's compatible-release operator needs all three version components to lock a minor version. ~=4.26 (two components) is NOT equivalent to "4.26.x only" — it means >=4.26, ==4.* and happily permits 4.27, 4.99, anything in the 4.x line, same as leaving it unpinned in every way that actually matters here. Verified directly against packaging.specifiers.SpecifierSet: ~=4.26 accepts 4.27.0, ~=4.26.0 correctly rejects it. Rewrote all four pins with the third component (jsonschema~=4.26.0, pytest~=9.1.1, ruff~=0.16.1, mkdocs-material~=9.7.7), matching the exact versions already verified installable in the prior commit, and added a comment explaining why the third digit is load-bearing so this doesn't regress again. Verified: fresh pip install, full pytest suite (11 passed), ruff clean, tools/validate.py against both examples, tools/check_versions.py all still pass with the corrected pins. Confirmed via SpecifierSet that each pin now allows patch-level drift but rejects the next minor version. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018J1NvPtPQZd3cEt6aAbGzG
There was a problem hiding this comment.
carochacs has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
Review summary
The Greptile Issue 1 is valid and correctly resolved by commit 6797719.
Dependency pins — ~=X.Y → ~=X.Y.Z is the right fix. Under PEP 440's compatible-release clause, ~=4.26.0 means >=4.26.0, ==4.26.*: it locks the minor version and allows patch-only drift, while ~=4.26 admits any 4.*. Verified with packaging.specifiers.SpecifierSet:
jsonschema~=4.26.0rejects4.27.0pytest~=9.1.1rejects9.2.0ruff~=0.16.1rejects0.17.0mkdocs-material~=9.7.7rejects9.8.0
All four pinned versions exist on PyPI. The added comment explaining why the third component is load-bearing is a good guard against regression.
release.yml — routing the version output through env: VERSION and using quoted "${VERSION}" in the shell steps is correct and matches the plugin-validate.yml pattern. The if: conditions keep the ${{ steps.ver.outputs.version }} GitHub-expression form, which the runner evaluates (not the shell), so there's no injection surface there.
Verification (with the pinned versions installed) — pytest: 11 passed; ruff check tools/ tests/: clean; tools/validate.py examples/minimal-plugin examples/full-plugin: both ok; tools/check_versions.py: consistent.
Non-blocking observation (outside this PR's diff)
The lint job in .github/workflows/validate.yml still does python -m pip install --upgrade ruff — an unpinned install, so that job remains exposed to exactly the silent CI drift this PR eliminates for the validate and docs jobs (a future ruff release can newly flag existing code and fail the check). If full pinning is the goal, that step could install -r requirements-dev.txt instead. Not blocking — the PR's own changes are correct and mergeable as-is.
Big Pickle (free) | 𝕏
|
Review 4879002473 contained no open threads — the review body confirmed Greptile's Issue 1 (dependency ranges) was already correctly resolved by commit Verified: full suite passes (11 tests), Task list (1/4 completed)
|

What
Two LOW hardening items found during a security audit:
1. Unpinned shell interpolation in release.yml.
${{ steps.ver.outputs.version }}was interpolated directly into tworun:shell steps — the classic GitHub Actions shell-injection pattern. Not exploitable today (the value is constrained bychangelog_extract.py's\d+\.\d+\.\d+regex), but fragile if that regex or its input ever changes. Routed through anenv: VERSIONvar instead, matching the pattern already used inplugin-validate.yml.2. Unpinned dev/docs dependencies.
requirements-dev.txt/requirements-docs.txtleftjsonschema,pytest,ruff, andmkdocs-materialfully unpinned, so CI silently picks up whatever's newest on a given day — a breaking change upstream shows up as a CI failure unrelated to whatever PR triggered it. Pinned to minor-version-compatible ranges (~=X.Y).Verified: fresh
pip install -r requirements-dev.txt, fullpytestsuite (11 passed),ruff check tools/ tests/(clean),tools/validate.py examples/minimal-plugin examples/full-plugin(both ok), andtools/check_versions.py(consistent) all pass with the pinned versions.release.ymlYAML parses cleanly.Checklist
Generated by Claude Code
Greptile Summary
This PR routes the extracted release version through step environment variables and constrains development and documentation dependencies.
$VERSIONexpansion.Confidence Score: 4/5
The PR appears safe to merge, though its dependency ranges do not fully implement the intended minor-series pinning.
The workflow hardening preserves behavior, while the dependency constraints leave non-blocking future CI drift possible because two-component compatible-release specifiers admit later minor releases.
Files Needing Attention: requirements-dev.txt and requirements-docs.txt
Important Files Changed
Prompt To Fix All With AI
Reviews (1): Last reviewed commit: "Route release.yml version through env in..." | Re-trigger Greptile