feat(ci): add PyPI release workflow for splunk-ao-adk#52
Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
- Replace mutable action refs (v4, v5, release/v1) with full commit SHAs to match the supply-chain convention established in ci-tests.yaml - Add upfront PEP 440 version format validation to reject bump keywords (patch, major, etc.) and malformed inputs before any file is modified Co-authored-by: Cursor <cursoragent@cursor.com>
|
Applied the same changesets from PR #48 to this workflow: SHA pinning — All action references ( Version input validation — Added an upfront |
- Fix regex to correctly accept rc, .dev, and .post PEP 440 forms - Add permissions: contents: read to the build job 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 — Workflow is correct and follows established repo conventions (SHA-pinned actions, env-var version input, OIDC publish); remaining items are robustness/design improvements, not blocking bugs.
General Comments
- 🟡 minor (design): This workflow injects the version into
pyproject.toml/__init__.pyat build time without committing back or creating a git tag (acknowledged as intentional in the PR description). However, the package already ships a[tool.semantic_release]config insplunk-ao-adk/pyproject.tomlwithtag_format = "splunk-ao-adk-v{version}", which implies a tag-based release flow. The consequence of the manual approach: after a release there is no git tag or commit recording which source revision produced a given PyPI version, so release provenance is weak and it's possible to publish from an arbitrary/uncommitted branch state. Worth confirming this is the desired model vs. cutting a tag (even justgit tag+ push) so released versions are traceable.
Follow-ups
Suggested follow-up work that could be tracked as Shortcut stories:
.github/workflows/release-splunk-ao-adk.yaml:47-51: TheGet current versionstep re-greps the file that was just written from the validated input. If the assertion-based hardening above is adopted, this step can setversion=${INPUT_VERSION}directly into$GITHUB_OUTPUT, removing the round-trip through the file entirely..github/workflows/release-splunk-ao-adk.yaml:18-19: The build job has notimeout-minutes, unlikeci-tests-splunk-ao-adk.yamlwhich caps each job at 30 minutes. Consider adding a timeout to both jobs to bail out on hangs (e.g. duringpip install build/python -m buildor the publish upload)..github/workflows/release-splunk-ao-adk.yaml:3-9: Noconcurrencygroup is defined. Two manual dispatches in quick succession (or for the same version) could race. Aconcurrencygroup keyed on the workflow name would serialize releases; the sibling CI workflow already uses this pattern.
| sed -i "s/^version = \".*\"/version = \"${INPUT_VERSION}\"/" pyproject.toml | ||
| sed -i "s/__version__ = \".*\"/__version__ = \"${INPUT_VERSION}\"/" src/splunk_ao_adk/__init__.py | ||
|
|
||
| - name: Get current version | ||
| id: get-version | ||
| run: | | ||
| VERSION=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/') | ||
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" |
There was a problem hiding this comment.
🟡 minor (bug): The sed substitution is not verified to have actually matched. If the version = "..." line format in pyproject.toml ever drifts (e.g. no surrounding spaces, or version moved under a different table), sed silently no-ops, and the subsequent Get current version step greps the unchanged file. The result: the build/artifact/publish would proceed with the stale version rather than the requested one, with no error — a silent wrong-version release. Since the version is already validated, you can both simplify and harden by deriving the output directly from the validated input and asserting the file was patched.
| sed -i "s/^version = \".*\"/version = \"${INPUT_VERSION}\"/" pyproject.toml | |
| sed -i "s/__version__ = \".*\"/__version__ = \"${INPUT_VERSION}\"/" src/splunk_ao_adk/__init__.py | |
| - name: Get current version | |
| id: get-version | |
| run: | | |
| VERSION=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/') | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| sed -i "s/^version = \".*\"/version = \"${INPUT_VERSION}\"/" pyproject.toml | |
| sed -i "s/__version__ = \".*\"/__version__ = \"${INPUT_VERSION}\"/" src/splunk_ao_adk/__init__.py | |
| if ! grep -q "^version = \"${INPUT_VERSION}\"" pyproject.toml; then | |
| echo "::error::Failed to set version in pyproject.toml — version line format may have changed." | |
| exit 1 | |
| fi | |
| if ! grep -q "__version__ = \"${INPUT_VERSION}\"" src/splunk_ao_adk/__init__.py; then | |
| echo "::error::Failed to set __version__ in src/splunk_ao_adk/__init__.py." | |
| exit 1 | |
| fi |
🤖 Generated by Astra
There was a problem hiding this comment.
Good catch — added grep -q assertions after each sed call to verify the substitution actually landed. If the version line format in pyproject.toml or the version file ever drifts, the step now fails loudly with a ::error:: annotation rather than silently continuing with the stale version. Applied to all three PyPI release workflows in PR #59.
Summary
Adds
.github/workflows/release-splunk-ao-adk.yaml— aworkflow_dispatchpipeline that builds and publishes thesplunk-ao-adkpackage to PyPI.How it works
0.1.0)splunk-ao-adk/pyproject.tomlandsplunk-ao-adk/src/splunk_ao_adk/__init__.pylocally with the supplied version (no commit back)python -m build(hatchling backend)Notes
release-splunk-ao-adk.yaml, environment:pypi)Made with Cursor