Skip to content

ci(python-sdk): add automated PyPI release workflow#375

Open
fslongjin wants to merge 1 commit into
TencentCloud:masterfrom
fslongjin:ci-python-sdk-release-workflow
Open

ci(python-sdk): add automated PyPI release workflow#375
fslongjin wants to merge 1 commit into
TencentCloud:masterfrom
fslongjin:ci-python-sdk-release-workflow

Conversation

@fslongjin
Copy link
Copy Markdown
Member

Summary

Add a CI-driven release pipeline so the cubesandbox Python SDK can be
published to PyPI automatically from a git tag, and document the procedure
for maintainers.

  • Add .github/workflows/release-python-sdk.yml triggered by
    python-sdk-v* tags (or manual workflow_dispatch). It validates
    tag↔__version__ consistency, builds sdist+wheel via python -m build,
    runs twine check --strict, publishes to PyPI using the
    CUBE_PYPI_TOKEN secret, and creates the matching GitHub Release with
    the built distributions attached. Manual dispatch additionally supports
    a TestPyPI dry-run target.
  • Exclude python-sdk-v* from release-one-click.yml so the two release
    pipelines are mutually exclusive — Python SDK tags will not trigger the
    one-click bundle, and regular vX.Y.Z tags will not trigger PyPI
    publishes.
  • Make cubesandbox.__version__ the single source of truth:
    pyproject.toml now uses dynamic = ["version"] with
    [tool.setuptools.dynamic].version = { attr = "cubesandbox.__version__" }.
    Also fill in proper PyPI metadata: readme, authors, keywords,
    classifiers, and Repository/Issues/Documentation URLs.
  • Update sdk/python/README.md to advertise pip install cubesandbox
    while still documenting the source install path.
  • Add bilingual maintainer documentation
    (docs/guide/maintainer/release-python-sdk.md and the zh translation)
    covering prerequisites, version rules, tag conventions, standard
    release procedure, recovery paths, and future improvements (Trusted
    Publishing, test gating).

Local validation

  • python -m build succeeds and produces cubesandbox-0.2.0.tar.gz /
    cubesandbox-0.2.0-py3-none-any.whl (dynamic version resolves from
    __version__ correctly).
  • python -m twine check --strict dist/* PASSES on both sdist and wheel.
  • Both workflow YAMLs parse cleanly; pyproject.toml parses cleanly.

Test plan

  • Configure repository secret CUBE_PYPI_TOKEN (project-scoped once
    cubesandbox exists on PyPI; user-scoped for the very first
    publish, then rotated).
  • Trigger the workflow manually with target: testpypi from the
    Actions UI to verify the build/publish path against TestPyPI.
  • Cut the first real release by tagging on master:
    git tag python-sdk-v0.2.0 && git push origin python-sdk-v0.2.0,
    then verify pip install cubesandbox from a clean venv.
  • Confirm release-one-click.yml is not triggered by the
    python-sdk-v* tag.

Assisted-by: Cursor:claude-opus-4.7

Made with Cursor

- Add release-python-sdk.yml triggered by python-sdk-v* tags or manual
  dispatch. Validates tag/__version__ consistency, builds sdist+wheel,
  runs twine check --strict, publishes to PyPI via CUBE_PYPI_TOKEN, then
  creates a GitHub Release with the built artifacts. Manual dispatch
  also supports a TestPyPI dry-run target.
- Exclude python-sdk-v* tags from release-one-click.yml so the two
  release pipelines are mutually exclusive.
- Make cubesandbox.__version__ the single source of truth: pyproject.toml
  now reads version dynamically via setuptools attr lookup, and the
  package metadata (readme, classifiers, urls, keywords, authors) is
  filled in for a proper PyPI listing.
- Update sdk/python/README.md to document pip install cubesandbox.
- Add bilingual maintainer guide docs/guide/maintainer/release-python-sdk.md
  (and the zh translation) covering prerequisites, version rules, tag
  conventions, the standard release procedure, and recovery paths.

Assisted-by: Cursor:claude-opus-4.7
Signed-off-by: jinlong <jinlong@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@cubesandboxbot
Copy link
Copy Markdown

cubesandboxbot Bot commented May 27, 2026

Claude finished @fslongjin's task in 58s —— View job


Code Review: CI-driven Python SDK PyPI release pipeline

Overall, this is a well-structured PR. The workflow and documentation are thorough and production-ready. A few observations below.

Workflow (release-python-sdk.yml)

Solid design:

  • Version consistency check between tag and __version__ is a great safety net (line 48-58)
  • Twine --strict check catches metadata issues before publishing (line 73-74)
  • Built artifact filename verification (line 65-71) ensures the package name/version are correct
  • cancel-in-progress: false is correct — you don't want a release to be interrupted
  • concurrency group scoped to github.ref correctly allows different tags to run in parallel

Issues & suggestions:

  1. Working directory / packages-dir alignment — The build step runs under sdk/python (via defaults.run.working-directory), so dist/ is at sdk/python/dist/. The publish step uses packages-dir: sdk/python/dist, which the pypa/gh-action-pypi-publish action resolves relative to $GITHUB_WORKSPACE. This is correct but subtle. Consider adding a comment to make the path relationship explicit, or move the packages-dir to just dist/ and adjust the working-directory accordingly.

pyproject.toml

  1. Documentation URL — Currently points to a GitHub tree path (.../tree/main/sdk/python). Once this is published, consider adding a dedicated documentation site URL (e.g., ReadTheDocs or GitHub Pages) or removing the URL entry if none exists.

  2. requests dependencypyproject.toml declares requests>=2 alongside httpx>=0.27. If requests is used internally for specific functionality, this is fine. If it's only used via httpx (which has its own transport), consider dropping the explicit requests dependency to keep the footprint minimal. (Not blocking, just an observation.)

README.md

  1. Stale version badge — The badge on README.md:9 shows v0.1.0 but the actual __version__ is 0.2.0. Rather than updating a hardcoded value that will drift again, consider switching to a dynamic PyPI badge:
    <img src="https://img.shields.io/pypi/v/cubesandbox" />
    
    This will automatically reflect the latest published version once the package is on PyPI.

Release isolation (release-one-click.yml)

  1. Tag exclusion is correct — The '!python-sdk-v*' negate pattern on line 7 of release-one-click.yml correctly prevents the Python SDK tags from triggering the one-click bundle. Verified that the two workflows are mutually exclusive.

Documentation

  1. Comprehensive and bilingual — The maintainer docs cover prerequisites, version rules, tag conventions, standard procedure, recovery paths, and future improvements. Both English and Chinese versions are well written.

Summary

Category Count
🐛 Bugs 0
⚠️ Issues 0
💡 Suggestions 4 (see above)

No blocking issues. The two actionable items are the stale version badge and confirming whether requests is needed as a direct dependency. The workflow itself is clean and well-structured.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant