Upload Python Package #32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Upload Python Package | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Release tag to publish, for example v0.4.0" | |
| required: true | |
| type: string | |
| concurrency: | |
| group: python-publish-${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }} | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| jobs: | |
| deploy: | |
| # PyPI trusted publishing requires a GitHub-hosted runner. | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }} | |
| - uses: astral-sh/setup-uv@v7 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Install dependencies | |
| run: uv sync --dev --frozen | |
| - name: Validate release tag | |
| env: | |
| RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.event.release.tag_name }} | |
| run: | | |
| set -euo pipefail | |
| uv run python - <<'PY' | |
| import os | |
| import re | |
| import subprocess | |
| import sys | |
| import tomllib | |
| release_tag = os.environ.get("RELEASE_TAG", "") | |
| if not re.fullmatch(r"v\d+\.\d+\.\d+(?:\.post\d+|\.post)?", release_tag): | |
| sys.exit( | |
| f"Release tags must match vX.Y.Z or vX.Y.Z.postN; received {release_tag or '<missing>'}." | |
| ) | |
| with open("pyproject.toml", "rb") as handle: | |
| version = tomllib.load(handle)["project"]["version"] | |
| expected = f"v{version}" | |
| if release_tag != expected: | |
| sys.exit( | |
| f"Release tag {release_tag} does not match pyproject version {version}; expected {expected}." | |
| ) | |
| tagged_commit = subprocess.run( | |
| ["git", "tag", "--points-at", "HEAD"], | |
| check=True, | |
| capture_output=True, | |
| text=True, | |
| ).stdout.splitlines() | |
| if release_tag not in tagged_commit: | |
| sys.exit(f"Checked-out commit is not tagged with {release_tag}.") | |
| print(f"Release tag {release_tag} matches pyproject.toml.") | |
| PY | |
| - name: Ensure version is not already published | |
| run: | | |
| set -euo pipefail | |
| version="$(uv run python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')" | |
| status="$(curl -s -o /dev/null -w '%{http_code}' "https://pypi.org/pypi/manim-voiceover/$version/json")" | |
| if [ "$status" = "200" ]; then | |
| echo "manim-voiceover@$version is already published on PyPI." | |
| exit 1 | |
| fi | |
| echo "Publishing manim-voiceover@$version" | |
| - name: Validate package | |
| run: | | |
| uv run ruff format --check . | |
| uv run ruff check . | |
| uv run ty check src/manim_voiceover | |
| uv run mypy | |
| uv run pytest --cov=manim_voiceover --cov-fail-under=85 | |
| - name: Build distributions | |
| run: uv build | |
| - name: Publish to PyPI | |
| run: uv publish --trusted-publishing always |