ci(release): migrate PyPI publish to Trusted Publishing + attestations#4249
Merged
Conversation
Switch the `publish-pypi` and `publish-hf-cli` jobs from long-lived API tokens (`PYPI_TOKEN_DIST_*` + `twine upload`) to PyPI Trusted Publishing via `pypa/gh-action-pypi-publish` (pinned by SHA, v1.14.0). Benefits: - No PyPI secret stored in the repo (OIDC exchange at publish time). - Each artifact is signed with Sigstore and gets a PEP 740 attestation (`attestations: true`), giving downstream consumers a cryptographic link back to this workflow run. - The publish jobs now run in a `pypi` GitHub Environment, which gates the actual upload behind required reviewers. - Build switched from the deprecated `python setup.py sdist bdist_wheel` to PEP 517 `python -m build`. Follow-up steps required before this can run: 1. Configure a Trusted Publisher on PyPI for both `huggingface-hub` and `hf`, matching repo `huggingface/huggingface_hub`, workflow `release.yml`, and environment `pypi`. 2. Create a `pypi` Environment in the repo settings with required reviewers. 3. Once green, delete the now-unused `PYPI_TOKEN_DIST_HUGGINGFACE_HUB` and `PYPI_TOKEN_DIST_HF` secrets, and remove or disable the tag-triggered fallback workflows (`python-release.yml`, `python-release-hf.yml`) which still rely on those tokens.
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
Delete `python-release.yml` and `python-release-hf.yml`. They were the pre-`release.yml` publish path, triggered by `push: tags: v*` and using `PYPI_TOKEN_DIST_*` to upload via twine. Since the unified `release.yml` took over, these workflows have only been documented as a "manual fallback" — but the same recovery is already available by re-running the failed publish job from the Actions UI. Keeping them around means anyone with write access can bypass the new `pypi` environment gate (and the OIDC / attestations flow) by pushing a tag with a PAT that cascades events. Removing them closes that bypass. The `PYPI_TOKEN_DIST_HUGGINGFACE_HUB` and `PYPI_TOKEN_DIST_HF` secrets become fully unused after this PR and the first successful Trusted Publishing run; they should be deleted from the repo settings then.
Wauplin
approved these changes
May 22, 2026
Wauplin
left a comment
Collaborator
There was a problem hiding this comment.
Thanks for taking care of this. Will tell you on next release how it went
Contributor
|
This PR has been shipped as part of the v1.17.0 release. |
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
Migrates the
publish-pypiandpublish-hf-clijobs inrelease.ymlfrom long-lived PyPI API tokens (twine upload -p $PYPI_TOKEN) to PyPI Trusted Publishing (OIDC) viapypa/gh-action-pypi-publish, turns on PEP 740 / Sigstore attestations, and removes the now-redundant legacy tag-triggered publish workflows.This closes the largest supply-chain gap surfaced by
huggingface_hub-1.16.1showingattestations: Noneon PyPI.What changes
In
.github/workflows/release.yml:publish-pypiandpublish-hf-clitwine uploadwithpypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b(v1.14.0, SHA-pinned).permissions: id-token: writeandattestations: write(job-scoped, no escalation elsewhere).environment: pypiso the publish step is gated behind required reviewers.python -m build) instead of the deprecatedpython setup.py sdist bdist_wheel.pip install setuptools wheel twine, drop thePYPI_TOKEN_DIST_*env var.PYPI_TOKEN_DIST_*entries from the required-secrets list, document the new Trusted Publisher / Environment requirements, drop the stale reference to the deleted fallback workflows.Delete:
.github/workflows/python-release.yml.github/workflows/python-release-hf.ymlThese were the pre-
release.ymlpublish path, triggered bypush: tags: v*withPYPI_TOKEN_DIST_*+ twine. Keeping them around would let anyone with write access bypass the newpypienvironment gate by pushing a tag with a PAT that cascades events. The "manual fallback" they offered is already covered by re-running the failed publish job from the Actions UI.Already done outside the PR
pypicreated on the repo with required reviewers (Wauplin, hanouticelina, XciD, julien-c) and deployment branch policy restricted tov*-release.huggingface-hub(owner:huggingface, repo:huggingface_hub, workflow:release.yml, env:pypi).hf, same values.Post-merge cleanup
After the first successful release on the new flow:
PYPI_TOKEN_DIST_HUGGINGFACE_HUBandPYPI_TOKEN_DIST_HF.Why this matters
ultralytics(Dec 2024) and PyTorchtorchtriton(Dec 2022).Follow-up PRs (not in scope here)
trufflesecurity/trufflehog@main,codecov/codecov-action@v5, ...).curl | bashOpenCode installs out of jobs that hold release tokens.SECURITY.md, CODEOWNERS, branch protection onv*-release.Note
Medium Risk
Medium risk because it changes the critical release/publish pipeline (build and upload mechanism, permissions, and environment gating), which could block releases if PyPI/GitHub environment configuration is off.
Overview
PyPI publishing is moved from token-based
twine uploadto PyPI Trusted Publishing (OIDC) inrelease.ymlfor bothhuggingface-huband thehfCLI, including job-scopedid-token/attestationspermissions,pypienvironment gating, andpython -m buildbuilds.Legacy tag-triggered publish workflows are removed (
python-release.ymlandpython-release-hf.yml), and the release workflow docs are updated to reflect the new Trusted Publisher/environment requirements and the lack of token-based fallback.Reviewed by Cursor Bugbot for commit eb95bb8. Bugbot is set up for automated code reviews on this repo. Configure here.