Skip to content

CI: switch PyPI publish to Trusted Publishing (OIDC) - #835

Merged
qiyanjun merged 1 commit into
QData:masterfrom
qiyanjun:ci/trusted-publishing
Aug 14, 2026
Merged

CI: switch PyPI publish to Trusted Publishing (OIDC)#835
qiyanjun merged 1 commit into
QData:masterfrom
qiyanjun:ci/trusted-publishing

Conversation

@qiyanjun

Copy link
Copy Markdown
Member

Summary

Switches .github/workflows/publish-to-pypi.yml from username/password (twine upload with secrets.PYPI_USERNAME/PYPI_PASSWORD) to PyPI's Trusted Publishing via the official pypa/gh-action-pypi-publish action.

Why

The v0.3.11 release attempt just failed at the upload step with 403 Forbidden from https://upload.pypi.org/legacy/. The build itself succeeded (textattack-0.3.11-py3-none-any.whl built correctly); PyPI rejected the upload, which is what a stale/deprecated username+password credential looks like — PyPI no longer accepts basic-auth uploads for accounts with 2FA enabled (now effectively mandatory for established projects).

Trusted Publishing removes the credential problem entirely: no secrets are stored in the repo at all. GitHub's OIDC token is exchanged directly with PyPI at publish time, scoped to this exact repo + workflow file.

Required one-time setup (PyPI side, not in this repo)

Before this will work, someone with owner/maintainer access to the textattack PyPI project needs to add a Trusted Publisher:

  1. Go to https://pypi.org/manage/project/textattack/settings/publishing/
  2. Add a new publisher:
    • Owner: QData
    • Repository name: TextAttack
    • Workflow name: publish-to-pypi.yml
    • Environment name: (leave blank — this workflow doesn't use a GitHub environment)

Once that's configured, the old PYPI_USERNAME/PYPI_PASSWORD repo secrets are no longer read by this workflow and can be deleted.

Test plan

  • YAML syntax validated (yaml.safe_load)
  • Verify a real release triggers a successful publish once the PyPI-side Trusted Publisher is configured

🤖 Generated with Claude Code

The username/password (secrets.PYPI_USERNAME/PYPI_PASSWORD) upload in
the v0.3.11 release attempt failed with "403 Forbidden" from PyPI -
password-based twine uploads are no longer accepted now that PyPI
requires token/OIDC-based auth for uploads. Switch to the official
pypa/gh-action-pypi-publish action with OIDC Trusted Publishing, which
needs no stored secrets at all: PyPI verifies the workflow's identity
directly via GitHub's OIDC token.

Requires a one-time, PyPI-side config: add this repo/workflow as a
Trusted Publisher on the `textattack` PyPI project (PyPI account ->
Manage project -> Publishing -> Add a new publisher), owner
"QData", repo "TextAttack", workflow "publish-to-pypi.yml",
environment left blank (this workflow doesn't use one). The old
PYPI_USERNAME/PYPI_PASSWORD secrets are no longer read by this
workflow and can be removed once trusted publishing is confirmed
working.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@qiyanjun
qiyanjun merged commit b206e62 into QData:master Aug 14, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant