Skip to content

feat(ci): add PyPI release workflow for splunk-ao-adk#52

Merged
adityamehra merged 3 commits into
mainfrom
feat/release-splunk-ao-adk-pypi
Jun 29, 2026
Merged

feat(ci): add PyPI release workflow for splunk-ao-adk#52
adityamehra merged 3 commits into
mainfrom
feat/release-splunk-ao-adk-pypi

Conversation

@adityamehra

Copy link
Copy Markdown
Member

Summary

Adds .github/workflows/release-splunk-ao-adk.yaml — a workflow_dispatch pipeline that builds and publishes the splunk-ao-adk package to PyPI.

How it works

  1. Trigger manually from the Actions tab with a required version (e.g. 0.1.0)
  2. Patches splunk-ao-adk/pyproject.toml and splunk-ao-adk/src/splunk_ao_adk/__init__.py locally with the supplied version (no commit back)
  3. Builds with python -m build (hatchling backend)
  4. Publishes to PyPI via OIDC Trusted Publisher — no stored API token needed

Notes

  • Version input is required to prevent accidental releases
  • Matches the pending Trusted Publisher on pypi.org (workflow: release-splunk-ao-adk.yaml, environment: pypi)
  • No PR trigger — use the Test PyPI workflow for pre-release validation

Made with Cursor

adityamehra and others added 2 commits June 25, 2026 14:37
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>
@adityamehra

Copy link
Copy Markdown
Member Author

Applied the same changesets from PR #48 to this workflow:

SHA pinning — All action references (actions/checkout, actions/setup-python, actions/upload-artifact, actions/download-artifact, pypa/gh-action-pypi-publish) are now pinned to full commit SHAs, matching the supply-chain convention established in ci-tests.yaml.

Version input validation — Added an upfront grep -Eq check that rejects anything that is not an explicit PEP 440 version number (e.g. 0.1.0, 1.2.3b1). Bump keywords like patch, major, or minor will now fail fast with a clear ::error:: message before touching any files.

- 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 fercor-cisco left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 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__.py at 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 in splunk-ao-adk/pyproject.toml with tag_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 just git 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: The Get current version step re-greps the file that was just written from the validated input. If the assertion-based hardening above is adopted, this step can set version=${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 no timeout-minutes, unlike ci-tests-splunk-ao-adk.yaml which caps each job at 30 minutes. Consider adding a timeout to both jobs to bail out on hangs (e.g. during pip install build/python -m build or the publish upload).
  • .github/workflows/release-splunk-ao-adk.yaml:3-9: No concurrency group is defined. Two manual dispatches in quick succession (or for the same version) could race. A concurrency group keyed on the workflow name would serialize releases; the sibling CI workflow already uses this pattern.

Comment on lines +38 to +45
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"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🟡 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.

Suggested change
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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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.

@adityamehra adityamehra merged commit afd0419 into main Jun 29, 2026
13 checks passed
@adityamehra adityamehra deleted the feat/release-splunk-ao-adk-pypi branch June 29, 2026 23:05
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 29, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants