Part of the repository modernization effort.
Warning: this issue needs manual PyPI and GitHub settings changes
Register the Trusted Publisher on PyPI before you merge. A merge without that step breaks the next release.
Background
Risk 1: a floating action pin next to a PyPI token
.github/workflows/publish.yml:8 reads uses: actions/checkout@master.
This pins a mutable branch, not a tag or a commit SHA. Any commit that lands on the upstream default branch runs here at once. No review gate stands between the upstream repository and this job.
The same job holds secrets.PYPI_API_TOKEN at .github/workflows/publish.yml:38. A bad upstream commit can read that token.
Risk 2: the workflow runs on every push
.github/workflows/publish.yml:2 reads on: push. No branch filter and no tag filter exist.
Every commit on every branch runs checkout, Python setup, apt install pandoc, the README rewrite, and a full build. Only the last step checks the ref:
if: startsWith(github.ref, 'refs/tags')
The build output is thrown away on every non-tag push.
Other findings
.github/workflows/publish.yml:10 uses actions/setup-python@v3.
- The workflow sets no
permissions: block and no timeout-minutes:.
pypa/gh-action-pypi-publish@release/v1 at line 37 is correct. PyPA documents release/v1 as an intended rolling branch for this action. Do not change it.
- Tags
v0.31.3, v0.31.4, and v0.32.0 exist in git. No GitHub release exists for any of them. The newest GitHub release is v0.31.2.
Proposed workflow
name: Publish to PyPI
on:
push:
tags:
- "v*"
workflow_dispatch:
permissions:
contents: read
jobs:
build-and-publish:
name: Build and publish to PyPI
runs-on: ubuntu-latest
timeout-minutes: 10
environment: pypi
permissions:
id-token: write
steps:
- uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v7
with:
python-version: "3.12"
- name: Install pandoc
run: sudo apt-get update && sudo apt-get install -y pandoc
- name: Build PyPI long description from README and CHANGELOG
run: |
cat README.rst > to-pypi.rst
echo "" >> to-pypi.rst
pandoc -s --to rst -o /dev/stdout CHANGELOG.md | tee -a to-pypi.rst
mv to-pypi.rst README.rst
- name: Install build
run: python -m pip install build
- name: Build sdist and wheel
run: python -m build --sdist --wheel --outdir dist/ .
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
The password: input is gone. Trusted Publishing uses the OIDC token from id-token: write.
The tag filter v* matches the commitizen tag format. .cz.yaml sets tag_format: v$version.
Warning: keep the pandoc step
The pandoc step appends the changelog to the PyPI long description. README.rst is a symlink to the Sphinx source docs/intro.rst. The two files use different formats. reStructuredText and Markdown do not concatenate under one content type.
Keep the pandoc step. Do not convert README.rst to Markdown. That conversion breaks the Sphinx build.
The step rewrites README.rst inside the CI checkout only. It never commits the change back.
Manual steps
- On pypi.org, open the project. Go to Publishing. Add a trusted publisher. Set Owner
jaysonsantos, Repository python-binary-memcached, Workflow publish.yml, Environment pypi.
- In GitHub repository settings, open Environments. Create an environment named
pypi.
- Merge this issue.
- Push a tag. Confirm the publish succeeds.
- Delete the
PYPI_API_TOKEN repository secret.
Acceptance criteria
Files to change
.github/workflows/publish.yml. The manual steps change PyPI and GitHub settings only.
Follow-up
Missing GitHub releases for v0.31.3, v0.31.4, and v0.32.0 are out of scope here. Open a separate issue to add a release step, or to create the missing releases by hand.
Part of the repository modernization effort.
Warning: this issue needs manual PyPI and GitHub settings changes
Register the Trusted Publisher on PyPI before you merge. A merge without that step breaks the next release.
Background
Risk 1: a floating action pin next to a PyPI token
.github/workflows/publish.yml:8readsuses: actions/checkout@master.This pins a mutable branch, not a tag or a commit SHA. Any commit that lands on the upstream default branch runs here at once. No review gate stands between the upstream repository and this job.
The same job holds
secrets.PYPI_API_TOKENat.github/workflows/publish.yml:38. A bad upstream commit can read that token.Risk 2: the workflow runs on every push
.github/workflows/publish.yml:2readson: push. No branch filter and no tag filter exist.Every commit on every branch runs checkout, Python setup,
apt install pandoc, the README rewrite, and a full build. Only the last step checks the ref:The build output is thrown away on every non-tag push.
Other findings
.github/workflows/publish.yml:10usesactions/setup-python@v3.permissions:block and notimeout-minutes:.pypa/gh-action-pypi-publish@release/v1at line 37 is correct. PyPA documentsrelease/v1as an intended rolling branch for this action. Do not change it.v0.31.3,v0.31.4, andv0.32.0exist in git. No GitHub release exists for any of them. The newest GitHub release isv0.31.2.Proposed workflow
The
password:input is gone. Trusted Publishing uses the OIDC token fromid-token: write.The tag filter
v*matches the commitizen tag format..cz.yamlsetstag_format: v$version.Warning: keep the pandoc step
The pandoc step appends the changelog to the PyPI long description.
README.rstis a symlink to the Sphinx sourcedocs/intro.rst. The two files use different formats. reStructuredText and Markdown do not concatenate under one content type.Keep the pandoc step. Do not convert
README.rstto Markdown. That conversion breaks the Sphinx build.The step rewrites
README.rstinside the CI checkout only. It never commits the change back.Manual steps
jaysonsantos, Repositorypython-binary-memcached, Workflowpublish.yml, Environmentpypi.pypi.PYPI_API_TOKENrepository secret.Acceptance criteria
push: tags: ["v*"]and onworkflow_dispatch. It no longer triggers on every push.actions/checkout@v7andactions/setup-python@v7.permissions: id-token: writeandenvironment: pypi. The top level setspermissions: contents: read.password:input topypa/gh-action-pypi-publishis gone.timeout-minutes:.pypienvironment exists in GitHub repository settings.PYPI_API_TOKENsecret is deleted after that run succeeds.Files to change
.github/workflows/publish.yml. The manual steps change PyPI and GitHub settings only.Follow-up
Missing GitHub releases for
v0.31.3,v0.31.4, andv0.32.0are out of scope here. Open a separate issue to add a release step, or to create the missing releases by hand.