From f9c037b5c4236c9bdcad2164818d1d9022e3debb Mon Sep 17 00:00:00 2001 From: Brad Barnett <127794626+bdbarnett@users.noreply.github.com> Date: Fri, 25 Sep 2026 08:01:23 -0500 Subject: [PATCH 1/3] Upload to production PyPI from this workflow, not the reusable one v0.6.1's PyPI upload failed with invalid-publisher: PyPI matches the Trusted Publisher against the workflow that runs the upload job, and that job ran inside PyDevices/.github's reusable coordinator. The upload is now the pypi job here, fed by the coordinator's pypi-publish and dist-artifact outputs, and report-pypi tells Release Health how it went. id-token:write is granted to that one job instead of the whole workflow. Both reusable refs are publishing-vNEXT, a placeholder for the first publishing tag cut after the .github change; it must be replaced before merge. docs/building-wheels.md said 21 wheels and publishing-v8; it is 18, and the pin is named where it lives. --- .../workflows/publish-release-packages.yml | 60 ++++++++++++++++--- docs/building-wheels.md | 24 +++++--- 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/.github/workflows/publish-release-packages.yml b/.github/workflows/publish-release-packages.yml index 804a537..4496aa4 100644 --- a/.github/workflows/publish-release-packages.yml +++ b/.github/workflows/publish-release-packages.yml @@ -11,12 +11,12 @@ on: required: true type: string -# publishing-v5 needs contents:write (attach release assets) and -# id-token:write (PyPI Trusted Publishing); a called workflow may not -# exceed the caller's grant, so the ceiling is set here. +# The coordinator needs contents:write to attach release assets; a called +# workflow may not exceed the caller's grant, so the ceiling is set here. +# id-token:write is granted only to the pypi job below, the one job that +# uses it. permissions: contents: write - id-token: write jobs: parity: @@ -64,7 +64,12 @@ jobs: needs: - parity - credentials - uses: PyDevices/.github/.github/workflows/reusable-publish-release-packages.yml@publishing-v8 + # publishing-vNEXT is a placeholder for the first publishing tag cut after + # PyDevices/.github's caller-side PyPI change (the coordinator's pypi-gate + # job and its pypi-publish / dist-artifact / version outputs). Replace it + # with that tag's real name before merging; as written, a run fails at + # startup. + uses: PyDevices/.github/.github/workflows/reusable-publish-release-packages.yml@publishing-vNEXT with: build-kind: native-and-wasm distribution-name: pydevices-audiodsp @@ -85,9 +90,48 @@ jobs: wheel-filename-prefix: pydevices_audiodsp # Production PyPI too, for final releases (Brad, 2026-09-23): the name # was parked at 0.6.0 by mirroring TestPyPI's files, and its Trusted - # Publisher (this workflow, environment "pypi") is configured. The pypi - # environment requires a reviewer, so each production publish waits for - # Brad's approval. + # Publisher (this workflow, environment "pypi") is configured. The + # coordinator only decides; the upload is the pypi job below. pypi-publish: true release-ref: ${{ inputs.release-ref }} secrets: inherit + + pypi: + # The upload has to run here, in this file. PyPI matches the Trusted + # Publisher against the workflow that runs the upload job, and when that + # job lived in the reusable coordinator, the workflow was + # PyDevices/.github's, not this one: v0.6.1 failed with invalid-publisher. + # The pypi environment requires Brad's approval and allows v* tags only. + needs: publish + if: >- + !cancelled() && needs.publish.outputs.pypi-publish == 'true' + runs-on: ubuntu-latest + environment: pypi + permissions: + id-token: write + steps: + - name: Download the validated distributions + uses: actions/download-artifact@v8 + with: + name: ${{ needs.publish.outputs.dist-artifact }} + path: dist + - name: Publish to PyPI via Trusted Publishing + uses: pypa/gh-action-pypi-publish@release/v1 + with: + skip-existing: true + + report-pypi: + # The coordinator's Release Health report went out before this upload, + # with pypi "pending"; this fills in the outcome on the same row. + needs: + - publish + - pypi + if: >- + !cancelled() && needs.publish.outputs.pypi-publish == 'true' + # Same placeholder as the publish job above: the same tag, both lines. + uses: PyDevices/.github/.github/workflows/reusable-report-pypi-result.yml@publishing-vNEXT + with: + distribution-name: pydevices-audiodsp + version: ${{ needs.publish.outputs.version }} + pypi-result: ${{ needs.pypi.result }} + secrets: inherit diff --git a/docs/building-wheels.md b/docs/building-wheels.md index 8f4602c..24b9970 100644 --- a/docs/building-wheels.md +++ b/docs/building-wheels.md @@ -8,14 +8,21 @@ python -m build ``` A GitHub Release `vX.Y.Z` — matching the `VERSION` file, which is also where -`_audiodsp.__version__` comes from — invokes the organization `publishing-v8` -workflow (the pin is the `@publishing-v8` ref in +`_audiodsp.__version__` comes from — invokes the organization's reusable +publishing workflow (the pin is the `@publishing-vN` ref in `.github/workflows/publish-release-packages.yml`) with -`build-kind: native-and-wasm`. It builds and validates exactly **21** wheels: +`build-kind: native-and-wasm`. It builds and validates exactly **18** wheels: - CPython 3.11–3.14, manylinux_2_28 x86_64, Windows AMD64, and - macosx_arm64 — 15. -- CPython 3.13–3.14, Android API 21 arm64_v8a/x86_64 and Pyodide wasm32 — 6. + macosx_arm64 — 12. +- CPython 3.13–3.14, Android API 21 arm64_v8a/x86_64 — 4. +- CPython 3.13–3.14, Pyodide wasm32 — 2. + +Final releases then go to production PyPI too, after Brad approves the `pypi` +environment. That upload is the `pypi` job in this repository's own +`publish-release-packages.yml`, not in the reusable workflow, because PyPI's +Trusted Publishing only matches the workflow that runs the upload +([why](https://github.com/PyDevices/.github/blob/main/docs/publishing-automation.md#production-pypi-opt-in-protected-trusted-publishing)). (This paragraph said `publishing-v6` and 16 wheels until 2026-09-02, having gone stale when macOS landed. The count that matters is @@ -111,16 +118,15 @@ written beside it. That is both a faithful reading of the rule and a stricter regression detector than a threshold. **Release-time gap, precisely — this one IS open.** The organization -desktop matrix (`reusable-build-native-and-wasm-wheels.yml`, at -`publishing-v8`) runs `ubuntu-latest`, `windows-latest` and +desktop matrix (`reusable-build-native-and-wasm-wheels.yml`) runs `ubuntu-latest`, `windows-latest` and `macos-latest`. There is no ARM cell, so **a release still ships no -aarch64 wheel** and `expected-wheel-count` stays 21. Closing it is three +aarch64 wheel** and `expected-wheel-count` stays 18. Closing it is three coupled steps, all outside this repository: 1. add an ARM runner to that matrix (the macOS comment there describes the same shape: repos that skip the arch build a no-op cell); 2. cut the new `publishing-vN` tag; -3. move this repository's pin and raise `expected-wheel-count` 21 → 26 +3. move this repository's pin and raise `expected-wheel-count` 18 → 22 in the same change. Steps 2 and 3 are release-machinery version decisions and belong to Brad. From d5376439bd1499e891c9778a28c0120bf91a74c9 Mon Sep 17 00:00:00 2001 From: Brad Barnett <127794626+bdbarnett@users.noreply.github.com> Date: Sat, 26 Sep 2026 19:08:42 -0500 Subject: [PATCH 2/3] publish: the reusable refs name publishing-v12, which carries .github#53 --- .github/workflows/publish-release-packages.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-release-packages.yml b/.github/workflows/publish-release-packages.yml index 4496aa4..8ea330c 100644 --- a/.github/workflows/publish-release-packages.yml +++ b/.github/workflows/publish-release-packages.yml @@ -64,12 +64,12 @@ jobs: needs: - parity - credentials - # publishing-vNEXT is a placeholder for the first publishing tag cut after + # publishing-v12 is a placeholder for the first publishing tag cut after # PyDevices/.github's caller-side PyPI change (the coordinator's pypi-gate # job and its pypi-publish / dist-artifact / version outputs). Replace it # with that tag's real name before merging; as written, a run fails at # startup. - uses: PyDevices/.github/.github/workflows/reusable-publish-release-packages.yml@publishing-vNEXT + uses: PyDevices/.github/.github/workflows/reusable-publish-release-packages.yml@publishing-v12 with: build-kind: native-and-wasm distribution-name: pydevices-audiodsp @@ -129,7 +129,7 @@ jobs: if: >- !cancelled() && needs.publish.outputs.pypi-publish == 'true' # Same placeholder as the publish job above: the same tag, both lines. - uses: PyDevices/.github/.github/workflows/reusable-report-pypi-result.yml@publishing-vNEXT + uses: PyDevices/.github/.github/workflows/reusable-report-pypi-result.yml@publishing-v12 with: distribution-name: pydevices-audiodsp version: ${{ needs.publish.outputs.version }} From a90c0ea64a3f42260f6f9c8c34d2608391a28365 Mon Sep 17 00:00:00 2001 From: Brad Barnett <127794626+bdbarnett@users.noreply.github.com> Date: Sat, 26 Sep 2026 19:09:10 -0500 Subject: [PATCH 3/3] publish: v12 is real, not a placeholder; the wheels doc names the pin --- .github/workflows/publish-release-packages.yml | 8 +++----- docs/building-wheels.md | 3 ++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-release-packages.yml b/.github/workflows/publish-release-packages.yml index 8ea330c..456b31c 100644 --- a/.github/workflows/publish-release-packages.yml +++ b/.github/workflows/publish-release-packages.yml @@ -64,11 +64,9 @@ jobs: needs: - parity - credentials - # publishing-v12 is a placeholder for the first publishing tag cut after - # PyDevices/.github's caller-side PyPI change (the coordinator's pypi-gate - # job and its pypi-publish / dist-artifact / version outputs). Replace it - # with that tag's real name before merging; as written, a run fails at - # startup. + # publishing-v12 (cut 2026-09-26) is the first publishing tag that carries + # PyDevices/.github's caller-side PyPI change (#53: the coordinator's + # pypi-gate job and its pypi-publish / dist-artifact / version outputs). uses: PyDevices/.github/.github/workflows/reusable-publish-release-packages.yml@publishing-v12 with: build-kind: native-and-wasm diff --git a/docs/building-wheels.md b/docs/building-wheels.md index 24b9970..1476779 100644 --- a/docs/building-wheels.md +++ b/docs/building-wheels.md @@ -50,7 +50,8 @@ Intel-Mac field report is what would add x86_64. **The release-time gap is closed** (corrected 2026-09-02; this section described it as open long after it shut). `macos-latest` joined the org desktop matrix in **publishing-v7**, this repository is pinned at -**`@publishing-v8`**, and `expected-wheel-count` is already **21** — the +**`@publishing-v12`** (the production PyPI upload runs here, not in the +reusable, since 2026-09-26), and `expected-wheel-count` is already **21** — the five `macosx_arm64` wheels ship. Hardware audio output on a real Mac is still community-verified; that part has not changed.