From b22bc4348984073895135cfaabd7d9622047267d Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Tue, 14 Jul 2026 13:26:52 -0400 Subject: [PATCH 1/3] ci: build, test, and release shield-swap-sdk from the wheels workflow Pure-Python universal wheel + sdist; the job installs the release's own aleo-sdk wheel (linux-x86_64 artifact) and runs the hermetic suite against it before uploading. Artifact name matches the release job's '*wheels-*' glob, so one tag publishes all three packages. Co-Authored-By: Claude Fable 5 --- .github/workflows/sdk-wheels.yml | 40 +++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sdk-wheels.yml b/.github/workflows/sdk-wheels.yml index 36db9fc..928002e 100644 --- a/.github/workflows/sdk-wheels.yml +++ b/.github/workflows/sdk-wheels.yml @@ -5,6 +5,7 @@ on: paths: - 'sdk/**' - 'sdk-abi/**' + - 'shield-swap-sdk/**' - '.github/workflows/sdk-wheels.yml' - '.github/workflows/sdk.yml' branches: @@ -16,6 +17,7 @@ on: paths: - 'sdk/**' - 'sdk-abi/**' + - 'shield-swap-sdk/**' - '.github/workflows/sdk-wheels.yml' - '.github/workflows/sdk.yml' workflow_dispatch: @@ -227,11 +229,47 @@ jobs: name: abi-wheels-sdist path: sdk-abi/dist + # shield-swap-sdk is pure Python (hatchling): one universal wheel + sdist. + # Depends on the built aleo-sdk wheel so its hermetic suite runs against + # the exact artifact shipping in this release, not a PyPI version. + build-shield-swap: + name: shield-swap-build + needs: [build] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - uses: actions/download-artifact@v4 + with: + name: wheels-linux-x86_64 + path: sdk-dist + - name: Build wheel + sdist + run: | + pip install build + python -m build shield-swap-sdk --outdir shield-swap-sdk/dist + - name: Test against the built aleo-sdk wheel + run: | + pip install --find-links sdk-dist aleo-sdk + pip install --find-links shield-swap-sdk/dist "shield-swap-sdk[async,mcp]" pytest pytest-asyncio + cd shield-swap-sdk && python -m pytest + # Prove the installed wheel imports on its own, away from the source tree. + - name: Smoke test wheel + run: | + cd "$RUNNER_TEMP" + python -c "import aleo_shield_swap; print('shield-swap-sdk', aleo_shield_swap.__version__)" + - name: Upload wheel + uses: actions/upload-artifact@v4 + with: + name: shield-swap-wheels-universal + path: shield-swap-sdk/dist + release: name: Release runs-on: ubuntu-latest if: "startsWith(github.ref, 'refs/tags/')" - needs: [build, sdist, build-abi, sdist-abi] + needs: [build, sdist, build-abi, sdist-abi, build-shield-swap] steps: - uses: actions/download-artifact@v4 with: From cf47a87d3fbbde6d4c83fbfb728cc91153d9b6e4 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Tue, 14 Jul 2026 13:56:08 -0400 Subject: [PATCH 2/3] =?UTF-8?q?ci:=20macos-13=20runner=20is=20retired=20?= =?UTF-8?q?=E2=80=94=20build=20x86=5F64=20macOS=20wheels=20on=20macos-15-i?= =?UTF-8?q?ntel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The macos-13 label got no runners since GitHub retired the image (2025-12-04), so both macos-x86_64 jobs queued forever. macos-15-intel is GitHub's designated Intel migration path (supported until Fall 2027). Co-Authored-By: Claude Fable 5 --- .github/workflows/sdk-wheels.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sdk-wheels.yml b/.github/workflows/sdk-wheels.yml index 928002e..9d28cdf 100644 --- a/.github/workflows/sdk-wheels.yml +++ b/.github/workflows/sdk-wheels.yml @@ -48,7 +48,7 @@ jobs: runner: ubuntu-24.04-arm target: aarch64 - name: macos-x86_64 - runner: macos-13 + runner: macos-15-intel target: x86_64 - name: macos-aarch64 runner: macos-latest @@ -157,7 +157,7 @@ jobs: runner: ubuntu-24.04-arm target: aarch64 - name: macos-x86_64 - runner: macos-13 + runner: macos-15-intel target: x86_64 - name: macos-aarch64 runner: macos-latest From 7ade532cab5ed9bb818ce4a3d5433d3b3e03a24e Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Tue, 14 Jul 2026 14:13:42 -0400 Subject: [PATCH 3/3] ci: publish via PyPI trusted publishing, one release job per package Replaces the token-based maturin upload with pypa/gh-action-pypi-publish under OIDC (id-token: write, no PYPI_API_TOKEN). Pending publishers must be unique per (repo, workflow, environment), so each package publishes from its own job/environment: pypi-abi, pypi, pypi-shield-swap. Releases run in dependency order abi -> sdk -> shield-swap, each also gated on all builds. Co-Authored-By: Claude Fable 5 --- .github/workflows/sdk-wheels.yml | 63 ++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/.github/workflows/sdk-wheels.yml b/.github/workflows/sdk-wheels.yml index 9d28cdf..e3e27bf 100644 --- a/.github/workflows/sdk-wheels.yml +++ b/.github/workflows/sdk-wheels.yml @@ -265,21 +265,68 @@ jobs: name: shield-swap-wheels-universal path: shield-swap-sdk/dist - release: - name: Release + # Publishing uses PyPI trusted publishing (OIDC) — no token secret. Each + # package has its own job because a pending publisher must be unique per + # (repo, workflow, environment): the job's environment name must exactly + # match the publisher registered on PyPI for that project. All three gate + # on every build job, and they release strictly in dependency order: + # abi -> sdk -> shield-swap (shield-swap-sdk requires aleo-sdk on PyPI). + release-abi: + name: Release aleo-contract-abi-generator runs-on: ubuntu-latest if: "startsWith(github.ref, 'refs/tags/')" needs: [build, sdist, build-abi, sdist-abi, build-shield-swap] + environment: pypi-abi + permissions: + id-token: write steps: - uses: actions/download-artifact@v4 with: - pattern: '*wheels-*' + pattern: 'abi-wheels-*' merge-multiple: true path: dist - name: Publish to PyPI - uses: PyO3/maturin-action@v1 - env: - MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist + skip-existing: true + + release-sdk: + name: Release aleo-sdk + runs-on: ubuntu-latest + if: "startsWith(github.ref, 'refs/tags/')" + needs: [build, sdist, build-abi, sdist-abi, build-shield-swap, release-abi] + environment: pypi + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v4 + with: + pattern: 'wheels-*' + merge-multiple: true + path: dist + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist + skip-existing: true + + release-shield-swap: + name: Release shield-swap-sdk + runs-on: ubuntu-latest + if: "startsWith(github.ref, 'refs/tags/')" + needs: [build, sdist, build-abi, sdist-abi, build-shield-swap, release-sdk] + environment: pypi-shield-swap + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v4 + with: + pattern: 'shield-swap-wheels-*' + merge-multiple: true + path: dist + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 with: - command: upload - args: --non-interactive --skip-existing dist/* + packages-dir: dist + skip-existing: true