turbodiff 1.3.6

Rust-powered DeepDiff core
Documentation
name: CI

on:
  push:

permissions:
  contents: read

concurrency:
  group: ${{ github.event.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up uv
        uses: astral-sh/setup-uv@v7
        with:
          python-version: "3.12"

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy, rustfmt

      - name: Install Python tooling
        run: |
          uv sync
          source .venv/bin/activate

      - name: Rust format check
        run: cargo fmt -- --check

      - name: Rust lint (clippy)
        run: cargo clippy -- -D warnings

      - name: Rust tests
        run: cargo test

      - name: Build Python extension
        run: |
          source .venv/bin/activate
          maturin develop --features python

      - name: Python lint (ruff)
        run: |
          source .venv/bin/activate
          ruff check .

      - name: Python format check (ruff)
        run: |
          source .venv/bin/activate
          ruff format --check .

      - name: Python tests
        run: |
          source .venv/bin/activate
          pytest

  release:
    if: github.event.ref == 'refs/heads/main'
    needs: test
    runs-on: ubuntu-latest
    outputs:
      released: ${{ steps.release.outputs.released }}
      tag: ${{ steps.release.outputs.tag }}
      version: ${{ steps.release.outputs.version }}
    permissions:
      contents: write
      id-token: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Fetch all history so semantic-release can resolve commits
          token: ${{ secrets.CICD_RELEASE_GITHUB_TOKEN_TURBODIFF }}

      - name: Release (python-semantic-release)
        id: release
        uses: python-semantic-release/python-semantic-release@v10.5.3
        with:
          changelog: true
          commit: true
          push: true
          tag: true
          vcs_release: true
          github_token: ${{ secrets.CICD_RELEASE_GITHUB_TOKEN_TURBODIFF }}

  publish_crate:
    if: github.event.ref == 'refs/heads/main' && needs.release.outputs.released == 'true'
    needs: release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          ref: refs/tags/${{ needs.release.outputs.tag }}

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

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

  build_wheels:
    if: github.event.ref == 'refs/heads/main' && needs.release.outputs.released == 'true'
    needs: release
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          ref: refs/tags/${{ needs.release.outputs.tag }}

      - name: Build wheels (maturin)
        if: needs.release.outputs.released == 'true'
        uses: PyO3/maturin-action@v1
        with:
          command: build
          args: --release --features python --out dist

      - name: Build sdist
        if: needs.release.outputs.released == 'true' && matrix.os == 'ubuntu-latest'
        uses: PyO3/maturin-action@v1
        with:
          command: sdist
          args: --out dist

      - name: Upload artifacts
        if: needs.release.outputs.released == 'true'
        uses: actions/upload-artifact@v4
        with:
          name: dist-${{ matrix.os }}
          path: dist

  publish_pypi:
    if: github.event.ref == 'refs/heads/main' && needs.release.outputs.released == 'true'
    needs: [build_wheels, release]
    runs-on: ubuntu-latest
    environment: pypi
    permissions:
      # IMPORTANT: this permission is mandatory for Trusted Publishing
      id-token: write
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          path: dist

      - name: Flatten dist
        run: |
          mkdir -p dist-flat
          find dist -type f \( -name "*.whl" -o -name "*.tar.gz" \) -print0 | xargs -0 -I {} cp {} dist-flat

      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@v1.13.0
        with:
          packages-dir: dist-flat