publish-pypi #3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: publish-pypi | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| confirm: | |
| description: "Type 'publish' to publish wheels + sdist to PyPI" | |
| required: true | |
| default: "dry-run" | |
| permissions: | |
| id-token: write | |
| contents: read | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| guard: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Confirm input | |
| run: | | |
| if [ "${{ inputs.confirm }}" != "publish" ]; then | |
| echo "Refusing to publish: set workflow input confirm=publish" | |
| exit 1 | |
| fi | |
| - name: Verify CI passed for this SHA | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| conclusion=$(gh run list \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --workflow=ci.yml \ | |
| --commit="$GITHUB_SHA" \ | |
| --json conclusion \ | |
| --jq '.[0].conclusion // "missing"') | |
| echo "CI conclusion for $GITHUB_SHA: $conclusion" | |
| if [ "$conclusion" != "success" ]; then | |
| echo "::error::CI for $GITHUB_SHA is '$conclusion', not 'success'. Aborting publish." | |
| exit 1 | |
| fi | |
| # Wheels are abi3 (cp39-abi3) -- one wheel per platform/arch covers all | |
| # CPython 3.9+ versions. Free-threaded Python is not supported by abi3. | |
| build-wheels: | |
| needs: guard | |
| strategy: | |
| # One bad build shouldn't cancel the rest -- partial publishes are | |
| # preferable to all-or-nothing because a bad runner config gets | |
| # diagnosed faster when other artifacts still upload. | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| manylinux: "2_28" | |
| artifact-suffix: manylinux-x86_64 | |
| # Native aarch64 runner -- cross-compiling Rust+pyo3 from x86_64 | |
| # to aarch64 musl/gnu via maturin-action hits linker-sysroot | |
| # mismatches; native arm runners avoid the entire class of bug. | |
| - os: ubuntu-24.04-arm | |
| target: aarch64-unknown-linux-gnu | |
| manylinux: "2_28" | |
| artifact-suffix: manylinux-aarch64 | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| manylinux: "musllinux_1_2" | |
| artifact-suffix: musllinux-x86_64 | |
| - os: ubuntu-24.04-arm | |
| target: aarch64-unknown-linux-gnu | |
| manylinux: "musllinux_1_2" | |
| artifact-suffix: musllinux-aarch64 | |
| - os: macos-14 | |
| target: aarch64-apple-darwin | |
| manylinux: "auto" | |
| artifact-suffix: macos-arm64 | |
| # Intel macOS wheels intentionally omitted: macos-13 runner queue | |
| # is severely backlogged (deprecated Dec 2026). Intel Mac users | |
| # fall back to sdist (Rust toolchain required). Re-add when | |
| # macos-latest defaults back to x86_64 (it won't) or when GH | |
| # provides a reliable macos-13 alternative. | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| manylinux: "auto" | |
| artifact-suffix: windows-x86_64 | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v6.0.2 | |
| - uses: actions/setup-python@v6.2.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Build wheels | |
| uses: PyO3/maturin-action@v1.51.0 | |
| with: | |
| target: ${{ matrix.target }} | |
| args: --release --out dist --features "hnsw,python,parallel" | |
| manylinux: ${{ matrix.manylinux }} | |
| - name: Upload wheels | |
| uses: actions/upload-artifact@v7.0.1 | |
| with: | |
| name: wheels-${{ matrix.artifact-suffix }} | |
| path: dist/*.whl | |
| if-no-files-found: error | |
| build-sdist: | |
| needs: guard | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6.0.2 | |
| - uses: actions/setup-python@v6.2.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Build sdist | |
| uses: PyO3/maturin-action@v1.51.0 | |
| with: | |
| command: sdist | |
| args: --out dist | |
| - name: Upload sdist | |
| uses: actions/upload-artifact@v7.0.1 | |
| with: | |
| name: sdist | |
| path: dist/*.tar.gz | |
| if-no-files-found: error | |
| publish: | |
| needs: [build-wheels, build-sdist] | |
| runs-on: ubuntu-latest | |
| environment: pypi | |
| steps: | |
| - name: Gather dist artifacts | |
| uses: actions/download-artifact@v8.0.1 | |
| with: | |
| path: dist | |
| merge-multiple: true | |
| - name: Publish to PyPI (trusted publishing) | |
| uses: pypa/gh-action-pypi-publish@v1.14.0 | |
| with: | |
| packages-dir: dist |