From a39ddaf3540bd2c30e637c4acb1722566af08fa3 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Wed, 1 Jul 2026 21:33:40 +0300 Subject: [PATCH 1/3] ci: publish to PyPI via Trusted Publishing (OIDC) Drop the long-lived PYPI_TOKEN secret in favor of OIDC. uv publish auto-detects the GitHub Actions id-token, so the release job grants id-token: write and runs under a `pypi` environment that scopes the PyPI Trusted Publisher. Requires a matching Trusted Publisher on the httpware PyPI project (workflow: release.yml, environment: pypi) before the next tag. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/release.yml | 8 +++++--- Justfile | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8cff843..e859946 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,13 +11,15 @@ on: - '[0-9]+.[0-9]+.[0-9]+' # stable: 2.7.2 - '[0-9]+.[0-9]+.[0-9]+[a-z]+[0-9]+' # pre-release: 2.0.0rc1, 4.0.0a2 -# Needed for softprops/action-gh-release to create the GitHub Release. +# contents: write -> create the GitHub Release; id-token: write -> OIDC for PyPI Trusted Publishing. permissions: contents: write + id-token: write jobs: release: runs-on: ubuntu-latest + environment: pypi # scopes the PyPI Trusted Publisher; hook for approval rules steps: - uses: actions/checkout@v6 - uses: extractions/setup-just@v4 @@ -45,9 +47,9 @@ jobs: # PyPI is irreversible, so it runs FIRST: if it fails the job stops and no # GitHub Release is created advertising a version that never reached PyPI. # `just publish` derives the version from $GITHUB_REF_NAME (the tag name). + # Auth via PyPI Trusted Publishing (OIDC); no PYPI_TOKEN. Needs a Trusted + # Publisher on the httpware PyPI project (env: pypi, workflow: release.yml). - run: just publish - env: - PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} # Description source: planning/releases/.md if present (verbatim, no # auto-changelog appended); otherwise GitHub's generated notes. A tag with diff --git a/Justfile b/Justfile index 529fedb..c40d7b7 100644 --- a/Justfile +++ b/Justfile @@ -31,13 +31,14 @@ test *args: test-branch: @just test --cov-branch +# Auth via PyPI Trusted Publishing (OIDC); uv publish auto-detects the CI id-token. publish: @test -n "${GITHUB_REF_NAME:-}" || (echo "GITHUB_REF_NAME is required; refusing to run outside CI" >&2; exit 1) @test -n "${PYPI_TOKEN:-}" || (echo "PYPI_TOKEN is required; refusing to run outside CI" >&2; exit 1) rm -rf dist uv version $GITHUB_REF_NAME uv build - uv publish --token $PYPI_TOKEN + uv publish # Build the docs site, failing on broken links / nav warnings; CI runs this on every PR. docs-build: From e98af626d7595be4da28c7b383ba06be07c63666 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Wed, 1 Jul 2026 21:35:28 +0300 Subject: [PATCH 2/3] ci: drop PYPI_TOKEN guard from publish recipe OIDC publishing sets no PYPI_TOKEN, so the guard would abort the run. The GITHUB_REF_NAME check still refuses to run outside CI. Co-Authored-By: Claude Opus 4.8 (1M context) --- Justfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Justfile b/Justfile index c40d7b7..1c50413 100644 --- a/Justfile +++ b/Justfile @@ -34,7 +34,6 @@ test-branch: # Auth via PyPI Trusted Publishing (OIDC); uv publish auto-detects the CI id-token. publish: @test -n "${GITHUB_REF_NAME:-}" || (echo "GITHUB_REF_NAME is required; refusing to run outside CI" >&2; exit 1) - @test -n "${PYPI_TOKEN:-}" || (echo "PYPI_TOKEN is required; refusing to run outside CI" >&2; exit 1) rm -rf dist uv version $GITHUB_REF_NAME uv build From 42e400975cea62bedfa76b37243c02f34abaf4c3 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Wed, 1 Jul 2026 23:31:01 +0300 Subject: [PATCH 3/3] docs(release): add 0.15.1 notes (Trusted Publishing pipeline) Co-Authored-By: Claude Opus 4.8 (1M context) --- planning/releases/0.15.1.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 planning/releases/0.15.1.md diff --git a/planning/releases/0.15.1.md b/planning/releases/0.15.1.md new file mode 100644 index 0000000..38528fa --- /dev/null +++ b/planning/releases/0.15.1.md @@ -0,0 +1,11 @@ +# httpware 0.15.1 — release pipeline on PyPI Trusted Publishing + +No library changes. The package is identical to 0.15.0; this release exercises the new publish path end-to-end. + +## CI + +- Releases now authenticate to PyPI via **Trusted Publishing (OIDC)** instead of a long-lived `PYPI_TOKEN` secret. `uv publish` auto-detects the GitHub Actions id-token; the release job runs under a `pypi` environment that scopes the trusted publisher (#89). + +## Downstream + +No action required. Nothing about the installed package changes.