graphdblite 0.1.2

Embedded graph database with Cypher support. SQLite-grade simplicity, graph-native performance.
Documentation
name: Python Wheels (PyPI)

# On tag push (or manual dispatch with a tag), builds wheels for every
# supported (os, arch) combination plus an sdist, then publishes all of
# them to PyPI as one atomic release. CI is the canonical source for
# PyPI wheels; the locally-built dist/wheels/ artifacts in
# scripts/publish-release.sh are uploaded to the GitHub/Forgejo release
# pages as a convenience but are not what `pip install graphdblite`
# resolves to.
#
# Publishing uses PyPI trusted publishing (OIDC) via the `pypi`
# environment. To enable for the first release:
#   1. PyPI → Account → Publishing → Add pending publisher:
#      owner=ds7n, repo=graphdblite, workflow=python-wheels.yml,
#      environment=pypi.
#   2. GitHub → Settings → Environments → New environment "pypi".
# Token-based fallback: set PYPI_API_TOKEN as a secret and add
#   `password: ${{ secrets.PYPI_API_TOKEN }}` to the publish step.

on:
  push:
    tags:
      - "v*"
  workflow_dispatch:
    inputs:
      tag:
        description: "Tag to publish (e.g. v0.1.0). Required for manual runs."
        required: true

permissions:
  contents: read

concurrency:
  group: python-wheels-${{ github.ref }}
  cancel-in-progress: false

jobs:
  build-wheels:
    name: build (${{ matrix.os }}, ${{ matrix.target }}, ${{ matrix.manylinux }})
    strategy:
      fail-fast: false
      matrix:
        include:
          # Linux glibc (manylinux_2_28)
          - os: ubuntu-latest
            target: x86_64
            manylinux: "2_28"
          - os: ubuntu-latest
            target: aarch64
            manylinux: "2_28"
          # Linux musl (musllinux_1_2)
          - os: ubuntu-latest
            target: x86_64
            manylinux: musllinux_1_2
          - os: ubuntu-latest
            target: aarch64
            manylinux: musllinux_1_2
          # macOS (universal2 would be ideal but maturin builds per-arch)
          - os: macos-latest
            target: x86_64
            manylinux: auto
          - os: macos-latest
            target: aarch64
            manylinux: auto
          # Windows
          - os: windows-latest
            target: x64
            manylinux: auto
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v6

      - uses: astral-sh/setup-uv@v8.1.0
        # PyO3/maturin-action drives cibuildwheel (brings its own per-target
        # Pythons), but a host Python is needed for the action prelude.

      - name: Build wheels
        uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.target }}
          args: --release --out dist --manifest-path bindings/python/Cargo.toml
          manylinux: ${{ matrix.manylinux }}

      - uses: actions/upload-artifact@v7
        with:
          name: wheels-${{ matrix.os }}-${{ matrix.target }}-${{ matrix.manylinux }}
          path: dist/*.whl

  build-sdist:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Build sdist
        uses: PyO3/maturin-action@v1
        with:
          command: sdist
          args: --out dist --manifest-path bindings/python/Cargo.toml

      - uses: actions/upload-artifact@v7
        with:
          name: sdist
          path: dist/*.tar.gz

  publish:
    needs: [build-wheels, build-sdist]
    runs-on: ubuntu-latest
    environment: pypi
    permissions:
      id-token: write  # trusted publishing — no token needed
    steps:
      - uses: actions/download-artifact@v8
        with:
          pattern: wheels-*
          merge-multiple: true
          path: dist/

      - uses: actions/download-artifact@v8
        with:
          name: sdist
          path: dist/

      - name: List artifacts to publish
        run: ls -lh dist/

      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          # Allow re-runs against an already-published version to no-op
          # instead of failing (e.g. when re-firing a moved tag).
          skip-existing: true