ci: add release-triggered PyPI publish workflow (OIDC, reviewer-gated) - #191
Merged
Conversation
Adds .github/workflows/publish-pypi.yml that publishes to TestPyPI then PyPI via PyPA Trusted Publishing (OIDC) when a GitHub Release is published. Triggers - release: published — primary path - workflow_dispatch with target choice (testpypi / pypi) — manual re-publish / retry Jobs - build: rebuild wheel + sdist from the release tag, twine check --strict - attach-release-assets: upload wheel + sdist as GitHub Release assets - publish-testpypi: uses the testpypi environment, runs first on every release event (and on dispatch when target=testpypi). Uses skip-existing so re-runs of the same version are no-ops. - publish-pypi: uses the pypi environment with a required reviewer, runs only on non-prerelease releases (and on dispatch when target=pypi). Prerelease guard means an rc release goes to TestPyPI only. Auth: Trusted Publishing only — no PyPI tokens, no secrets in repo. Requires a pending publisher registered on pypi.org and test.pypi.org pointing at this repo + workflow filename + environment. The workflow file alone does not publish anything. It only fires on a published GitHub Release, and the pypi environment requires reviewer approval before the upload step runs.
There was a problem hiding this comment.
Pull request overview
Adds a new GitHub Actions workflow that builds assert-ai distributions and publishes them to TestPyPI (always on release) and PyPI (only for non-prerelease releases or manual dispatch) via PyPA Trusted Publishing (OIDC), with a separate job that attaches the wheel/sdist to the GitHub Release. The workflow is gated by GitHub environments (testpypi, pypi), where the pypi environment is intended to require reviewer approval.
Changes:
- New
.github/workflows/publish-pypi.ymltriggered onrelease: publishedandworkflow_dispatch(withtargetchoice). - Build job (PEP 517 +
twine check --strict) produces adistartifact reused by all downstream jobs. - Separate
attach-release-assets,publish-testpypi, andpublish-pypijobs, with the PyPI job gated on build success, TestPyPI success/skip, andrelease.prerelease == false.
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.
Summary
Adds
.github/workflows/publish-pypi.yml— a release-triggered workflow that publishesassert-aito TestPyPI and PyPI via PyPA Trusted Publishing (OIDC).Triggers
release: published— primary pathworkflow_dispatchwith atargetchoice (testpypi/pypi) for manual re-publish or retryJobs
twine check --strict, uploadsdist/as an artifact.testpypienvironment. Runs on every release event (and on dispatch whentarget=testpypi).skip-existing: trueso re-runs of the same version are no-ops.pypienvironment with a required reviewer. Runs only on non-prerelease releases (and on dispatch whentarget=pypi). Theprerelease == falseguard means anrcrelease uploads to TestPyPI only.Auth
Trusted Publishing only — no PyPI tokens, no secrets in this repo.
To activate, a maintainer needs to register the following pending publishers on pypi.org and test.pypi.org:
assert-aiassert-airesponsibleairesponsibleaiASSERTASSERTpublish-pypi.ymlpublish-pypi.ymlpypitestpypiAnd create matching GitHub environments under repo Settings → Environments:
testpypi— no protection rulespypi— required reviewer (e.g. release manager)Safety
This workflow is inert when merged:
pypienvironment requires reviewer approval before the upload step runs.All three gates must be in place for a real publish to happen.
Companion
Builds on top of the wheel build hardening from #182, which already exercises
python -m build+twine checkon every PR.