diff --git a/cip/cip0008.md b/cip/cip0008.md index 17537bfd2..b90843e7e 100644 --- a/cip/cip0008.md +++ b/cip/cip0008.md @@ -2,7 +2,7 @@ author: Neil Lawrence created: '2026-10-17' id: '0008' -last_updated: '2026-10-24' +last_updated: '2026-11-01' status: In Progress compressed: false related_requirements: [] @@ -111,14 +111,44 @@ check, `environment` for publish), not a single Ubuntu `poetry publish` job. 2. **Retire `deploy`:** **yes**. Last commit July 2024 (1.13.2). Drop it from CI triggers; leave the branch for a while, then delete. 3. **Who can publish:** maintainers who can publish a GitHub Release on `main`. - Add a GitHub Actions **environment** (`pypi` or `release`) for the upload - job. Prefer **Trusted Publishing** (`pypa/gh-action-pypi-publish` + OIDC); - GPy already sets `id-token: write` but still uses `twine` + `TWINE_*`. + Trusted Publishing is live via **twine 6.1 OIDC** (see below). The + remaining control is the unused GitHub Actions **`release`** environment: + attach it to the deploy job, then name it on the PyPI publisher. 4. **TestPyPI:** **not required** for this CIP. Optional later. The dispatch dry-run is the preflight for aarch64 / manylinux. 5. **Version source of truth:** `pyproject.toml` via Poetry. CI fails the publish job unless the Release tag is `v$(poetry version -s)`. +### Trusted Publishing (2026-11-01) + +[sronix on Discussion #1228](https://github.com/SheffieldML/GPy/discussions/1228#discussioncomment-19325951) +caught stale CIP text. The 2026-10-24 decision said GPy still used +`twine` + `TWINE_*`. Those env lines left in +[`d6bbf9f`](https://github.com/SheffieldML/GPy/commit/d6bbf9f9) +(August). The v1.15.0 deploy log already shows twine minting the token +(`Got OIDC token for audience pypi`): +[job 120984126014](https://github.com/SheffieldML/GPy/actions/runs/40130966985/job/120984126014). + +From **twine 6.1**, `twine upload` tries Trusted Publishing when no token is +configured and the job has `id-token: write`. Keep that path. Do **not** +switch to `pypa/gh-action-pypi-publish` unless we specifically want +[PEP 740](https://peps.python.org/pep-0740/) attestations (the action +generates them by default). That switch is optional and is not required +to close this CIP. + +The repo already has a **`release`** environment with no protection rules. +The deploy job does not name it yet. Remaining work, in this order: + +1. Add `environment: release` to the deploy job, and a deployment rule + limited to `v*` tags. A published GitHub Release runs on its tag ref, + so real releases still upload. That limits *which ref* can publish, not + *who*: anyone with write access can still publish a Release. Required + reviewers on the environment are an optional extra (watch self-review + and admin-bypass settings). +2. **Then** name that environment on the PyPI trusted publisher. PyPI will + refuse tokens from runs outside it. Workflow first, PyPI second: the + other order breaks the next upload. + ### Out of scope here (do not block Accept) - Merging #1242 (Python ≥3.11). That waits until 1.15.0 is on PyPI @@ -133,8 +163,9 @@ check, `environment` for publish), not a single Ubuntu `poetry publish` job. `vX.Y.Z`, publish a GitHub Release. 3. **CI:** `push`/`pull_request` on `main` only; split wheel build from publish; `workflow_dispatch` dry-run; `release.types: [published]`; - tag == Poetry version; Trusted Publishing + environment; keep aarch64 - (#1209). + tag == Poetry version; keep aarch64 (#1209). Trusted Publishing is + already twine 6.1 OIDC. Remaining: `environment: release` on deploy, + then name that environment on PyPI. 4. **Branch policy:** rename default `devel` → `main`; Dependabot `target-branch: main`; drop `deploy` from triggers. 5. **First release on the new path** (after 1.15.0): checklist; close CIP. @@ -169,6 +200,8 @@ CIP-0003 / #1209. - [x] v1.15.0 on PyPI (`pip install gpy==1.15.0`; aarch64 wheels included) - [x] CI: `types: [published]`, `workflow_dispatch` wheel dry-run, drop `deploy` trigger, tag == Poetry version - [x] Default branch renamed `devel` → `main`; Dependabot `target-branch: main` +- [x] Trusted Publishing via twine 6.1 OIDC (v1.15.0; `TWINE_*` gone since `d6bbf9f`) +- [ ] Attach `environment: release` to deploy, then name it on the PyPI publisher - [ ] First release on new pipeline verified; CIP Closed ## References @@ -176,3 +209,6 @@ CIP-0003 / #1209. - Current workflow: `.github/workflows/test-and-deploy.yml` - Packaging: [CIP-0003](cip0003.md); arm64 / optional plotting: #1209 / #1226 - Discussion: [#1228](https://github.com/SheffieldML/GPy/discussions/1228) + (sronix, 2026-11-01: twine 6.1 OIDC already live; environment-before-PyPI) +- Twine 6.1 Trusted Publishing: https://twine.readthedocs.io/en/stable/changelog.html +- v1.15.0 deploy log: https://github.com/SheffieldML/GPy/actions/runs/40130966985/job/120984126014