fix(ci): harden version validation and verify sed substitutions in release pipelines#59
Conversation
…lease pipelines Two security/reliability improvements applied to all three PyPI release workflows (splunk-ao, splunk-ao-adk, splunk-ao-a2a): 1. Switch grep -Eq to bash [[ =~ ]] for version validation grep -E matches on a per-line basis, so a multi-line input like "0.1.0\n<payload>" passes the check even though it is not a valid version. bash [[ =~ ]] anchors ^ and $ to the entire string, making multi-line inputs impossible to sneak through. 2. Verify each sed substitution actually matched If the version line format in pyproject.toml or the __version__ file ever drifts, sed silently no-ops and the build proceeds with the stale version. Added grep -q assertions after each sed call so a mismatch fails loudly instead of producing a silent wrong-version release. Co-authored-by: Cursor <cursoragent@cursor.com>
fercor-cisco
left a comment
There was a problem hiding this comment.
🤖 This review was generated by the Astra agent (claude-opus-4-8). It may contain mistakes.
Verdict: approve — Both hardening fixes are correct, consistently applied across all three workflows, and introduce no regressions.
Follow-ups
Suggested follow-up work that could be tracked as Shortcut stories:
.github/workflows/release-splunk-ao-adk.yaml:45-45: Thesrc/splunk_ao_adk/__init__.pyandsrc/splunk_ao_a2a/_version.pypaths referenced by the adk/a2a release workflows do not exist in this repository'ssrc/tree (onlysrc/splunk_ao/andsrc/galileo/are present). If these packages are expected to be built from this repo, thesedstep (and now the newgrepverification) will fail at runtime. Worth confirming these workflows target the correct repo/paths. Pre-existing and out of scope for this PR.
| exit 1 | ||
| fi | ||
| sed -i "s/__version__ = \".*\"/__version__ = \"${INPUT_VERSION}\"/" src/splunk_ao/__init__.py | ||
| if ! grep -q "__version__ = \"${INPUT_VERSION}\"" src/splunk_ao/__init__.py; then |
There was a problem hiding this comment.
🔵 nit (other): The pyproject.toml verification is anchored (^version = ...) but the __version__ verification is not. Anchoring it too would make the check more precise and consistent — it guards against accidentally matching an unrelated occurrence (e.g. in a comment or docstring) while the real assignment line was missed by sed. Low priority since sed would update any matching line anyway.
| if ! grep -q "__version__ = \"${INPUT_VERSION}\"" src/splunk_ao/__init__.py; then | |
| if ! grep -q "^__version__ = \"${INPUT_VERSION}\"" src/splunk_ao/__init__.py; then |
🤖 Generated by Astra
fercor-cisco
left a comment
There was a problem hiding this comment.
Approved; see the minor suggestion above.
Summary
Addresses two issues raised in PR reviews of the release pipeline workflows (#52 and #56), applied consistently across all three PyPI release workflows (
splunk-ao,splunk-ao-adk,splunk-ao-a2a).Changes
1. Fix: multi-line input bypass in version validation
Issue:
grep -Eq '^...$'matches on a per-line basis, so a multi-line string like0.1.0\n<payload>passes the check — the first line matches and the rest is ignored. A maintainer dispatching the workflow via the REST API orgh workflow runcan inject newlines into theversioninput, which then flows unsanitized into thesedreplacement string.Fix: Replaced
grep -Eqwith bash[[ =~ ]], whose^/$anchors apply to the entire string, not individual lines. Multi-line inputs are unconditionally rejected.2. Fix: silent
sedno-op on version format driftIssue: If the
version = "..."line format inpyproject.tomlor__version__ = "..."in the version file ever drifts (e.g. extra spaces, moved table),sedsilently exits 0 with no replacements. The build then proceeds with the stale version — a silent wrong-version release.Fix: Added
grep -qassertions after eachsedcall to verify the expected line is now present. Failure exits loudly with a::error::annotation.Files changed
.github/workflows/release-splunk-ao.yaml.github/workflows/release-splunk-ao-adk.yaml.github/workflows/release-splunk-ao-a2a.yamlRelated