name: Publish to PyPI on: release: types: [published] permissions: id-token: write contents: read jobs: publish: runs-on: ubuntu-latest environment: pypi steps: - uses: actions/checkout@v6 - uses: astral-sh/setup-uv@v7 - name: Verify release tag matches package version run: | tag="${{ github.event.release.tag_name }}" version="$(grep -m1 '^version = ' pyproject.toml | sed -E 's/^version = "([^"]+)"/\1/')" if [ "${tag#v}" != "$version" ]; then echo "Release tag '$tag' does not match pyproject.toml version '$version'" >&2 exit 1 fi echo "Release tag '$tag' matches package version '$version'" - name: Build package run: uv build # Publish with `uv publish` (its own uploader, not the twine bundled in the # old pypa action). Trusted publishing is automatic in GitHub Actions: the # `id-token: write` permission + the `pypi` environment supply the OIDC token, # and PyPI's trusted-publisher entry matches on repo + workflow filename + # environment name (all unchanged from the pypa-action setup), so no API token # is needed. uv's uploader also accepts Metadata-Version 2.5 -- the permanent # fix that lets the hatchling pin be relaxed (see pyproject [build-system]). - name: Publish to PyPI run: uv publish