From 886920f48a8092d9ff8de77f4566df6034bcc53b Mon Sep 17 00:00:00 2001 From: bigboateng Date: Fri, 7 Aug 2026 21:25:46 +0100 Subject: [PATCH] Build PyPI wheels only for stable releases --- .github/workflows/package-publish.yml | 5 ++++- scripts/check-release-control.mjs | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/package-publish.yml b/.github/workflows/package-publish.yml index f319fda..453025a 100644 --- a/.github/workflows/package-publish.yml +++ b/.github/workflows/package-publish.yml @@ -120,6 +120,7 @@ jobs: done node packaging/assemble.mjs --version "$VERSION" --binaries dist/bin --output dist/packages - name: Build Python wheels + if: needs.resolve.outputs.channel == 'stable' env: VERSION: ${{ needs.resolve.outputs.version }} shell: bash @@ -139,11 +140,13 @@ jobs: (cd "$directory" && npm pack --dry-run) done - name: Assemble immutable release unit + env: + CHANNEL: ${{ needs.resolve.outputs.channel }} run: | mkdir -p dist/release-unit cp dist/packages/SHA256SUMS.json dist/release-unit/ cp -R dist/packages/npm dist/release-unit/npm - cp -R dist/pypi dist/release-unit/pypi + if [[ "$CHANNEL" == stable ]]; then cp -R dist/pypi dist/release-unit/pypi; fi - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: packages-${{ needs.resolve.outputs.version }}-${{ needs.resolve.outputs.source_sha }} diff --git a/scripts/check-release-control.mjs b/scripts/check-release-control.mjs index 87e736f..33c24b9 100644 --- a/scripts/check-release-control.mjs +++ b/scripts/check-release-control.mjs @@ -74,6 +74,8 @@ export async function checkReleaseControl(root = resolve(import.meta.dirname, ". expect(publisher.jobs?.npm?.permissions?.contents === "read" && publisher.jobs?.npm?.permissions?.["id-token"] === "write", "npm publisher must use read-only source plus OIDC"); expect(publisher.jobs?.pypi?.permissions?.contents === "read" && publisher.jobs?.pypi?.permissions?.["id-token"] === "write", "PyPI publisher must use read-only source plus OIDC"); expect(publisher.jobs?.pypi?.environment === "pypi-production", "stable PyPI publishing must use the protected pypi-production environment"); + const pythonWheelStep = publisher.jobs?.build?.steps?.find((step) => step.name === "Build Python wheels"); + expect(pythonWheelStep?.if === "needs.resolve.outputs.channel == 'stable'", "PyPI wheels must be built only for stable PEP 440 versions"); expect(raw["package-publish.yml"].indexOf("Publish platform runtimes") < raw["package-publish.yml"].indexOf("Publish SDK and CLI"), "runtime packages must publish before the SDK package"); expect(raw["package-publish.yml"].includes("pypa/gh-action-pypi-publish@"), "PyPI publishing must use the trusted-publishing action"); expect(!raw["package-publish.yml"].includes("skip-existing"), "PyPI retries must verify hashes instead of blindly skipping existing files");