Repository navigation
Conversation
Adds a workflow that publishes to PyPI via Trusted Publishing (OIDC) whenever a GitHub Release is published, so tagging a release no longer requires a manual build+twine step. Guards against publishing a mismatched version by checking the tag against zenpy/__init__.py's __version__ before building. Addresses facetoe#692 (comment) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KiP1kDx4T3Ea8UyviXD8NM
- Trigger on 'released' instead of 'published' - the latter also fires for GitHub pre-releases, which would otherwise publish an unintended version to PyPI. Added a job-level 'if' guard on release.prerelease as defense in depth. - Pin pypa/gh-action-pypi-publish to a commit SHA (v1.14.2) instead of the floating release/v1 tag, so a compromised/repointed tag on that action can't run inside a trusted-publishing job. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KiP1kDx4T3Ea8UyviXD8NM
The comment in publish.yml and DEPLOY.md still described the trigger as "a GitHub Release is published", left over from before the release/pre-release hardening. Clarifies that a release marked pre-release will not run the publish workflow. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KiP1kDx4T3Ea8UyviXD8NM
Addresses findings from a max-effort code review of this branch: - Split into a 'build' job (untrusted code: pip install, setup.py via python -m build; no PyPI credential) and a 'publish' job (only downloads the artifact and uploads it; holds the OIDC token). Per PyPA's Trusted Publishing guidance, this stops anything running during the build from being able to reach the id-token permission. - The version check now verifies setup.py's version too, not just zenpy/__init__.py's __version__ - the two are independently hand-maintained and only setup.py's is what `python -m build` actually embeds in the built package, since no active pyproject.toml exists. - Anchored the __version__ regex and added a clear failure message instead of an unhandled AttributeError if it doesn't match. - Added skip-existing: true to the publish step, so a re-run after a partial failure (e.g. wheel uploaded, sdist didn't) doesn't hard-fail on re-uploading the file that already succeeded. - DEPLOY.md: added a step to confirm the run succeeded and the version landed on PyPI, noted that unmarking an existing pre-release also triggers publishing, de-duplicated the PyPI publisher setup values (single source of truth in publish.yml's header comment), and flagged that the manual fallback now needs a PyPI token of its own since Trusted Publishing only authorizes GitHub Actions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KiP1kDx4T3Ea8UyviXD8NM
python setup.py --version failed in CI with "No module named setuptools" - GitHub's Python 3.14 runner doesn't have setuptools importable in the base env before the build tool is installed, and executing setup.py at all isn't necessary just to read its version=. Extract it with the same regex approach already used for zenpy/__init__.py's __version__, avoiding the dependency and the unnecessary code execution. Caught by re-running the hassaku63/zenpy-release-poc validation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KiP1kDx4T3Ea8UyviXD8NM
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the request in #692 (comment) — cutting a release currently means a manual
twine uploadfrom a maintainer's machine.What this does
Adds
.github/workflows/publish.yml: when a (non pre-release) GitHub Release is published, it builds the sdist/wheel and uploads them to PyPI via Trusted Publishing (OIDC) — no PyPI token needs to be stored as a repo secret.Version bumping stays manual (
zenpy/__init__.py+setup.py, same as today) — the workflow only builds/publishes once you tag and release. It checks that the release tag matches the version in both files before building, and build/publish run as separate jobs (per PyPA's Trusted Publishing guidance) so the job holding the OIDC token never executes untrusted build-time code.One-time setup needed from you
Register a Trusted Publisher for the
zenpyproject (a few clicks, no secret to manage): https://pypi.org/manage/project/zenpy/settings/publishing/facetoe, Repository:zenpy, Workflow:publish.yml, Environment: blankFull updated release steps in
DEPLOY.md.Validated separately
End-to-end tested (including catching and fixing a couple of real mistakes — a Test PyPI/production mix-up, and a
setuptools-not-available failure — along the way) in a throwaway repo before proposing this here: https://github.com/hassaku63/zenpy-release-poc. Same workflow, published to real PyPI, confirms pre-releases are excluded, the split build/publish jobs work as intended, and Trusted Publishing works end-to-end.🤖 Generated with Claude Code