Skip to content

Conversation

@dataflake
Copy link
Member

Fixes #198

I'm opening this PR in draft mode because it requires some manual testing.

This PR switches the publish step in the c-code template for the GHA tests workflow from using standard credentials to the "Trusted Publishing" mode. I have been following the guide at https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/.

As a prerequisite, I have configured a "trusted publisher" on all those packages' PyPI settings that use our c-code template, because right now only those packages are published from GitHub Actions to PyPI. See https://pypi.org/manage/project/zope-interface/settings/publishing/ for an example.

As explained in the documentation, both PyPI and GitHub strongly encourage using so-called "environments" and to secure these environments with access rules that are configured in the individual GitHub repository settings under "Environments". I have named the environment "pypi" and created it on all repositories for the c-code template packages. See https://github.com/zopefoundation/zope.interface/settings/environments and click on pypi for an example.

The Python packaging documentation seems to suggest it is mandatory to require workflow run approval for those workflows that use this pypi publishing environment, so I checked "Required reviewers" in the environment settings and for starters added the "release-managers" and "maintainers" teams from the zopefoundation organization there. I will need to check what this does in practice, it would suck if that means all those people will get email whenever the tests run. Hopefully it will only generate review requests if the publish step is triggered, because that is the only step that names and uses the pypi environment.

Even if only the publish step causes emails to be sent this may be annoying for many members in those "release-managers" and "maintainers" teams and it may make sense to create a separate smaller team with only those people who handle publishing of zopefoundation packages to PyPI.

I have added @mauritsvanrees as reviewer. I don't know if you guys use Trusted Publishing on the Plone side and if you do, I'd be interested to see how you configured it.

@dataflake dataflake self-assigned this Nov 28, 2025
@coveralls
Copy link

coveralls commented Nov 28, 2025

Pull Request Test Coverage Report for Build 19781636211

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 14.867%

Totals Coverage Status
Change from base Build 19780803855: 0.0%
Covered Lines: 240
Relevant Lines: 1218

💛 - Coveralls

dataflake added a commit to zopefoundation/ExtensionClass that referenced this pull request Nov 28, 2025
@dataflake
Copy link
Member Author

I have tested this with ExtensionClass and created a release 6.2.1a2:

PyPI: https://pypi.org/project/ExtensionClass/6.2.1a2/
Publish GHA run: https://github.com/zopefoundation/ExtensionClass/actions/runs/19765736533/job/56638217435

This works well. The normal test runs, meaning those without a tag, proceed as before. When I tagged I did not receive any email to approve the deployment, GitHub just presented a button to open an approval popup. It's similar to the approval button I see on the Actions tab when a non-member creates a PR from their own fork. @mauritsvanrees @icemac did you receive email asking you to approve a deployment?

This PR is ready for review.

Once a repository has switched to the Trusted Workflow model the following should be done:

  • remove the TWINE_PASSWORD repository secret by going to the repository's Settings | Secrets and variables | Actions page.
  • log into PyPI with the zope.wheelbuilder account and remove the API token named after the package from the account settings.

I believe once the last API key is gone from the zope.wheelbuilder PyPI account the entire account can be deleted.

@dataflake dataflake marked this pull request as ready for review November 28, 2025 14:14
@davisagli
Copy link
Member

I got an email asking to review the pending deployment:

Screenshot 2025-11-28 at 10 01 05 AM

(After I click the button, I see the current status of the workflow showing that @dataflake already approved it.)

@dataflake
Copy link
Member Author

Thanks David, so there are emails going out. Darn.

@davisagli
Copy link
Member

@dataflake Only for the workflow runs where that step is not skipped, though (i.e. the ones triggered by a tag).

It makes sense to me to require approval from a small group of release managers for this, so that someone can't execute a supply chain attack just because they use their write permission to create a tag. The emails seem like a minor annoyance; it's easy for me to create an inbox filter to deal with them.

@dataflake
Copy link
Member Author

@davisagli Yes, preventing supply chain attacks is exactly the point. It's just that those groups were made for different purposes than that, I just used them for the moment because I didn't have anything better. I didn't just want to put @icemac and me everywhere and make people angry who were used to releasing packages to PyPI before.

It seems there's no one-size-fits-all here without possible making some people angry, so at least for those ~15 repositories that do automated publishing I will go through the commit history to try and identify those people who have done releases in the past. I'll then try and find the best match between existing groups and adding individual contributors. There's a limit of 6 groups/persons I can add to the deployment protection rule.

@dataflake
Copy link
Member Author

I have gone through all 14 c-code repositories that do automatic publishing to PyPI and found that there's just a single one, zope.interface where people other than @icemac and @dataflake seem to have made releases over the last 2+ years (or at least prepared commits commonly found at release time), @davisagli and @tseaver.

I have added @davisagli to the release-managers because I have the impression you don't mind getting publishing approval emails and so you can continue publishing zope.interface releases. I have also added @tseaver specifically to the zope.interface deployment protection rule.

I have removed the team zopefoundation/maintainers and only left zopefoundation/release-managers to approve publishing workflows for all c-code repos other than zope.interface. The team consists of the following people:

@dataflake
Copy link
Member Author

The changes from this PR have now been applied to all c-code package repositories. I have also deleted the TWINE_PASSWORD secret from all those repositories and deleted their respective API key from the PyPI zope.wheelbuilder account.

From everything I can see the zope.wheelbuilder account was only ever used for these 14 repositories. @mgedmin you and I were the only people with a login for that account. After deleting all remaining API tokens that were for used for Appveyor for these 14 repositories there is no token left in the account. Can I delete it?

@mgedmin
Copy link
Member

mgedmin commented Nov 29, 2025

From everything I can see the zope.wheelbuilder account was only ever used for these 14 repositories. @mgedmin you and I were the only people with a login for that account. After deleting all remaining API tokens that were for used for Appveyor for these 14 repositories there is no token left in the account. Can I delete it?

Yes.

@tseaver
Copy link
Member

tseaver commented Nov 29, 2025 via email

@dataflake
Copy link
Member Author

Looks like it was too much for PyPI to delete the zope.wheelbuilder account, I keep getting error messages. So instead I removed it from all projects and then changed its login information so I am the only one who could possibly log in or use it.

@dataflake dataflake merged commit 16011fe into master Nov 29, 2025
13 checks passed
@dataflake dataflake deleted the dataflake/trusted_publishing branch November 29, 2025 14:15
@icemac
Copy link
Member

icemac commented Dec 1, 2025

@dataflake Thank you for taking on this project and completing it so quickly. Looks nice and more secure than before.
I also had credentials for zope.wheelbuilder on PyPI. I'll delete them on my side incl. the 2FA access.

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.

Switch PyPI publish via GHA to 'Trusted Publishers' model

7 participants