From a37bc15340c776e1dd1f46778b0987113b9338f6 Mon Sep 17 00:00:00 2001 From: Patrick Melix Date: Fri, 13 Mar 2026 10:21:22 +0000 Subject: [PATCH] ci: switch to OIDC trusted publishing for PyPI and TestPyPI Remove PYPI_API_TOKEN and TEST_PYPI_API_TOKEN secrets from both publish workflows. pypa/gh-action-pypi-publish uses OIDC automatically when no password is supplied, authenticated via the id-token: write permission and the GitHub environment (pypi / testpypi). Also removes the broken waitfortest gate from pypi-publish.yml (same issue as release.yml: workflow_dispatch has no tag/branch CI check to wait on). CLAUDE.md documents the one-time trusted publisher registration on PyPI and TestPyPI, including the exact field values needed. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/pypi-publish.yml | 27 ++++----------------------- .github/workflows/release.yml | 2 -- CLAUDE.md | 30 ++++++++++++++++++++++++++++-- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index b38ac50..b172d72 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -1,6 +1,6 @@ -# This workflow uploads a Python Package to TestPyPI on manual trigger +# Manually publish a Python package to TestPyPI (trusted publisher, no token needed) -name: Upload Python Package +name: Upload Python Package to TestPyPI on: workflow_dispatch: @@ -9,20 +9,8 @@ permissions: contents: read jobs: - waitfortest: - name: Wait for tests to succeed - runs-on: ubuntu-latest - steps: - - uses: lewagon/wait-on-check-action@v1.3.4 - with: - ref: ${{ github.ref }} - check-name: 'test' - repo-token: ${{ secrets.GITHUB_TOKEN }} - wait-interval: 20 - build: name: Build distribution - needs: waitfortest runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -31,11 +19,7 @@ jobs: with: python-version: "3.x" - name: Install pypa/build - run: >- - python3 -m - pip install - build - --user + run: python3 -m pip install build --user - name: Build a binary wheel and a source tarball run: python3 -m build - name: Store the distribution packages @@ -53,7 +37,7 @@ jobs: name: testpypi url: https://test.pypi.org/p/tools4vasp permissions: - id-token: write # IMPORTANT: mandatory for trusted publishing + id-token: write # required for OIDC trusted publishing steps: - name: Download all the dists uses: actions/download-artifact@v4 @@ -64,6 +48,3 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 with: repository-url: https://test.pypi.org/legacy/ - password: ${{ secrets.TEST_PYPI_API_TOKEN }} - - diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 72c2706..d2d8d0e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,7 +60,5 @@ jobs: path: dist/ - name: Publish distribution to PyPI uses: pypa/gh-action-pypi-publish@release/v1 - with: - password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/CLAUDE.md b/CLAUDE.md index 9fe48db..b60a59c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -111,8 +111,34 @@ Key points: 1. In the feature branch, bump `version` in `pyproject.toml` and `CITATION.cff` (also update `date-released` in `CITATION.cff`). 2. Merge the PR to `main`. -3. `tag-on-merge.yml` creates tag `v` → `release.yml` runs tests, - builds the wheel, creates a GitHub Release, and publishes to PyPI. +3. `tag-on-merge.yml` creates tag `v` → `release.yml` builds the + wheel, creates a GitHub Release, and publishes to PyPI via trusted publisher. + +### PyPI / TestPyPI trusted publisher (one-time setup) + +Both `release.yml` (PyPI) and `pypi-publish.yml` (TestPyPI) use **OIDC trusted +publishing** — no API token is stored in GitHub secrets. Instead, PyPI/TestPyPI +grant publish rights directly to this workflow via OpenID Connect. + +If the trusted publisher is ever lost or needs to be recreated, register it at: + +- **PyPI**: https://pypi.org/manage/project/tools4vasp/settings/publishing/ +- **TestPyPI**: https://test.pypi.org/manage/project/tools4vasp/settings/publishing/ + +Use these values for each: + +| Field | Value | +|-------|-------| +| Owner | `Tonner-Zech-Group` | +| Repository | `VASP-tools` | +| Workflow (PyPI) | `release.yml` | +| Workflow (TestPyPI) | `pypi-publish.yml` | +| Environment (PyPI) | `pypi` | +| Environment (TestPyPI) | `testpypi` | + +The GitHub environments (`pypi` and `testpypi`) must exist in the repository +settings (Settings → Environments) — they gate the `id-token: write` permission +that OIDC requires. ## Key dependencies