rasgapdf 0.2.6

Blazing-fast spatial 2D PDF parser in pure Rust with multi-language bindings (Python, Node.js, Go, C#) for RAG, LLMs, bounding boxes, and table extraction
Documentation
name: Release & Publish

on:
  release:
    types: [published]
  workflow_dispatch:

permissions:
  contents: read

jobs:
  publish-pypi:
    name: 🐍 Publish to PyPI (with Provenance)
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.0

      - name: Install Linux dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y pkg-config libfontconfig1-dev libfreetype6-dev libharfbuzz-dev libclang-dev

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable

      - name: Build Rust Shared Library
        run: cargo build --release

      - name: Copy Linux library to Python package
        run: cp target/release/librasgapdf.so bindings/python/rasgapdf/librasgapdf.so

      - name: Set up Python
        uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.0.0
        with:
          python-version: "3.11"

      - name: Build sdist and wheel
        run: |
          cd bindings/python
          python -m pip install --upgrade pip build twine
          python -m build
          twine check dist/*

      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # release/v1
        with:
          packages-dir: bindings/python/dist/
          attestations: true

  publish-npm:
    name: 📦 Publish to npm (with Provenance)
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.0

      - name: Install Linux dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y pkg-config libfontconfig1-dev libfreetype6-dev libharfbuzz-dev libclang-dev

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable

      - name: Build Rust Shared Library
        run: cargo build --release

      - name: Copy Linux library to Node package
        run: cp target/release/librasgapdf.so bindings/nodejs/librasgapdf.so

      - name: Set up Node.js
        uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.0.0
        with:
          node-version: "22"
          registry-url: "https://registry.npmjs.org"

      - name: Publish to npm with Provenance
        run: |
          cd bindings/nodejs
          npm publish --access public --provenance
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

  publish-crates:
    name: 🦀 Publish to crates.io
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.0

      - name: Install Linux dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y pkg-config libfontconfig1-dev libfreetype6-dev libharfbuzz-dev libclang-dev

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable

      - name: Publish to crates.io
        run: cargo publish
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

  sync-huggingface:
    name: 🤗 Sync to Hugging Face (Model & Space)
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.0

      - name: Set up Python
        uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.0.0
        with:
          python-version: "3.12"

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install huggingface_hub

      - name: Sync Model Repository and Space to Hugging Face
        run: python upload_to_hf.py
        env:
          HF_TOKEN: ${{ secrets.HF_TOKEN }}

  generate-sbom:
    name: 🛡️ Generate & Attest SBOM (Supply Chain Security)
    runs-on: ubuntu-latest
    permissions:
      contents: write
      id-token: write
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.0

      - name: Generate SPDX SBOM
        uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.7.0
        with:
          format: spdx-json
          output-file: rasgapdf-sbom.spdx.json

      - name: Attach SBOM to GitHub Release
        if: github.event_name == 'release'
        uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.0
        with:
          files: rasgapdf-sbom.spdx.json

  publish-nuget:
    name: 🔷 Publish to NuGet (.NET)
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.0

      - name: Install Linux dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y pkg-config libfontconfig1-dev libfreetype6-dev libharfbuzz-dev libclang-dev

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable

      - name: Build Rust Shared Library
        run: cargo build --release

      - name: Set up .NET
        uses: actions/setup-dotnet@3951f0ca7a015626166687bcc430754c67195b84 # v4.3.0
        with:
          dotnet-version: '8.0.x'

      - name: Build and Pack NuGet Package
        run: |
          cd bindings/csharp
          dotnet pack -c Release -o dist

      - name: NuGet login (OIDC Trusted Publishing)
        id: login
        continue-on-error: true
        uses: NuGet/login@291cf541e21b76df479f6e1f0e21bc5c88686a3d # v1.1.0
        with:
          user: MartinsMessias

      - name: Publish to NuGet.org
        run: |
          KEY="${{ steps.login.outputs.NUGET_API_KEY }}"
          if [ -z "$KEY" ]; then
            KEY="${{ secrets.NUGET_API_KEY }}"
          fi
          if [ -n "$KEY" ]; then
            dotnet nuget push bindings/csharp/dist/*.nupkg \
              --api-key "$KEY" \
              --source https://api.nuget.org/v3/index.json \
              --skip-duplicate
          else
            echo "Neither Trusted Publishing nor NUGET_API_KEY available; skipping push"
          fi