Skip to content

CI: add PyPI Trusted-Publishing “publish” job to wheels workflow (#61669) #61718

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: main
Choose a base branch
from

Conversation

EvMossan
Copy link

@EvMossan EvMossan commented Jun 27, 2025

Summary

This PR enables Trusted Publishing (OIDC) uploads to PyPI when a GitHub release is published.

What’s changed

  • .github/workflows/wheels.yml

    • adds a new publish job that
      1. downloads all wheel / sdist artifacts from upstream jobs;
      2. excludes Pyodide wheels (*pyodide*.whl);
      3. runs pypa/gh-action-pypi-publish@v1 in the pypi environment.
  • doc/source/whatsnew/v3.0.0.rst

    • adds a single Build / CI line announcing the switch to Trusted Publishing
  • doc/source/development/maintaining.rst

    • drop manual twine step and note Trusted Publishing

No other files or CI matrix settings were changed.

Release prerequisites

  • GitHub repo must have an environment named pypi (OIDC token permission enabled).
  • The pandas project on PyPI must list pandas-dev/pandas → “pypi” as a Trusted Publisher (see https://docs.pypi.org/trusted-publishers/).

@EvMossan EvMossan requested a review from mroeschke as a code owner June 27, 2025 08:03
@EvMossan
Copy link
Author

EvMossan commented Jun 27, 2025

CI failed in the docstring-validation step with

AttributeError: 'getset_descriptor' object has no attribute '__module__'. Did you mean: '__reduce__'?

This occurs before my code runs, so it isn’t caused by the changes in this PR.
It looks related to the latest numpydoc release.
I’ll re-run CI once the upstream fix lands.

@EvMossan EvMossan closed this Jun 28, 2025
@EvMossan EvMossan reopened this Jun 28, 2025
@EpicWink
Copy link

This workflow runs every day, on all pushes, and on all pull requests, but you said "uploads to PyPI when a release tag is pushed" in the description. Perhaps you want to put this in a new publish.yml workflow file, with on: { release: { types: [published] } }.

Because this makes the download-artifacts step run in a different workflow, you'll need to figure out the run-id argument.

You could alternatively add on: { release: { types: [published] } } to the wheels.yml workflow.


You need to update the release process documentation to change the new method for publishing (remove step 5: "Upload wheels to PyPI").


You likely want to document (in this pull request's description, and in the release process documentation) the new pypi GitHub environment needs to exist, and the corresponding publisher needs to be added to the project in PyPI.

@simonjayhawkins simonjayhawkins added Enhancement Build Library building on various platforms CI Continuous Integration labels Jun 30, 2025
@EvMossan EvMossan force-pushed the trusted-publish-pypi branch from d6552ce to 58cb179 Compare June 30, 2025 15:09
@EvMossan EvMossan force-pushed the trusted-publish-pypi branch from 6232f6f to 7359e1b Compare June 30, 2025 15:40
@EvMossan
Copy link
Author

@EpicWink All requested changes are in. Let me know if anything else’s needed - thanks!

Copy link

@EpicWink EpicWink left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You likely want to document (in this pull request's description, and in the release process documentation) the new pypi GitHub environment needs to exist, and the corresponding publisher needs to be added to the project in PyPI.

Still want to do this, at least in this pull request's description

EvMossan and others added 4 commits July 1, 2025 06:37
Co-authored-by: Laurie O <laurie_opperman@hotmail.com>
Co-authored-by: Laurie O <laurie_opperman@hotmail.com>
Co-authored-by: Laurie O <laurie_opperman@hotmail.com>
Co-authored-by: Laurie O <laurie_opperman@hotmail.com>
@EvMossan
Copy link
Author

EvMossan commented Jul 1, 2025

All comments addressed and conversations resolved - ready for another look. Thanks!

@EvMossan EvMossan closed this Jul 8, 2025
@EvMossan EvMossan reopened this Jul 8, 2025
Copy link
Member

@jorisvandenbossche jorisvandenbossche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EvMossan thanks a lot for working on this! (and @EpicWink for the review)

@mroeschke I updated the PyPI configuration to enable trusted publishing on that side.

I suppose we can only test this really once doing a next pre-release?
Could we already test the first part of the added job by temporarily commenting out the last pypa/gh-action-pypi-publish step, but so at least we can check the downloading and filtering of the artifacts is working?

Comment on lines +16 to +17
release:
types: [published]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EpicWink you suggested to add this, but I am wondering if that is needed? As I understand, this wheels.yml workflow will run on the commit pushed to main with a tag, and so that way it will already run for a release? And we can then upload the wheels from that run?

Copy link

@EpicWink EpicWink Jul 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A GitHub release publish happens after a push, allowing you to review the CI, and write release notes in the GitHub release, before triggering the publish to PyPI. Up to you how you want the release workflow to be, if you want to publish unconditionally.

An alternative is to split the workflow into two files (and therefore two workflows), where the publish job downloads the artefacts from the build job of the other workflow.


twine upload pandas/dist/pandas-<version>*.{whl,tar.gz} --skip-existing
5. Verify wheels are uploaded automatically by GitHub Actions
via [**Trusted Publishing**](https://docs.pypi.org/trusted-publishers/)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
via [**Trusted Publishing**](https://docs.pypi.org/trusted-publishers/)
via `**Trusted Publishing** <https://docs.pypi.org/trusted-publishers/>`__)

(this file is still in rst, not markdown)

- name: Publish to **PyPI** (Trusted Publishing)
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://upload.pypi.org/legacy/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this line needed? (it's not included in the example in https://docs.pypi.org/trusted-publishers/using-a-publisher/)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not necessary, and as far as I know there's no recommendation to hard-code it. When the upload API 2.0 PEP lands, in site this URL and action will change anyway.

@jorisvandenbossche jorisvandenbossche added this to the 3.0 milestone Jul 19, 2025
@EpicWink
Copy link

I suppose we can only test this really once doing a next pre-release?

Yes, fortunately PyPI sports uploading pre-releases.

Could we already test the first part of the added job by temporarily commenting out the last pypa/gh-action-pypi-publish step, but so at least we can check the downloading and filtering of the artifacts is working?

That could work, as long as it's in a protected tag, but you would be creating a tag just to test this, unless you change the workflow definition further to support a non-version-tag ref.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Build Library building on various platforms CI Continuous Integration Enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ENH: Switch to trusted publishing for package upload to PyPI in CI
5 participants