mmap-chunker-core 0.2.6

Record-aligned byte-range planning for large immutable files with zero-copy mmap framing, CLI, and a stable C ABI.
Documentation
name: Python Wheel

# Bounded wheel + sdist build and proof CI. Builds one py3-none-<platform>
# wheel per supported target (matching the native release matrix), verifies the
# ABI symbols, GLIBC ceiling on Linux, wheel contents, and runs clean-environment
# install proofs. Also builds and verifies the sdist. Wheels and the sdist are
# uploaded as Actions artifacts only; nothing is published to PyPI or GitHub
# Releases from this workflow.
#
# Reusable: the Release workflow calls this via `workflow_call` so the wheel
# target matrix lives in exactly one place. PyPI Trusted Publishing never runs
# inside a reusable workflow; release.yml performs the publish job itself.

on:
  workflow_call:
  push:
    branches: [main]
  pull_request:
    branches: [main]

permissions:
  contents: read

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

env:
  CARGO_TERM_COLOR: always
  RUSTFLAGS: "-D warnings"

jobs:
  wheel-matrix:
    strategy:
      fail-fast: false
      matrix:
        include:
          # Linux targets use `cross` with the CentOS-7 (glibc 2.17) images
          # pinned in Cross.toml so the GLIBC <= 2.17 contract holds regardless
          # of the runner image's glibc.
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            plat: manylinux_2_17_x86_64
            cross: 1
          - os: ubuntu-latest
            target: aarch64-unknown-linux-gnu
            plat: manylinux_2_17_aarch64
            cross: 1
          # bdist_wheel auto-detection on macOS emits a `universal2` platform
          # tag even for thin single-arch binaries, which over-claims arm64
          # compatibility for the Intel wheel (and vice versa). Pin the exact
          # `macosx_<deployment_target>_<arch>` tag per target.
          - os: macos-15-intel
            target: x86_64-apple-darwin
            plat: macosx_10_13_x86_64
            cross: 0
          - os: macos-latest
            target: aarch64-apple-darwin
            plat: macosx_11_0_arm64
            cross: 0
          - os: windows-latest
            target: x86_64-pc-windows-msvc
            plat: win_amd64
            cross: 0
    runs-on: ${{ matrix.os }}
    timeout-minutes: 40
    steps:
      - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0

      - name: Set up Python
        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
        with:
          python-version: "3.12"

      - name: Install Python build tooling
        shell: bash
        run: |
          set -euo pipefail
          python -m pip install --quiet --upgrade pip
          python -m pip install --quiet build wheel setuptools

      - name: Install Rust toolchain
        if: ${{ !matrix.cross }}
        uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
        with:
          targets: ${{ matrix.target }}

      - name: Install cross CLI
        if: ${{ matrix.cross }}
        run: cargo install cross --version 0.2.5 --locked

      - name: Build and verify wheel
        shell: bash
        env:
          TARGET: ${{ matrix.target }}
          WHEEL_PLAT_TAG: ${{ matrix.plat }}
          CROSS: ${{ matrix.cross }}
        run: bash scripts/build-python-wheel.sh

      - name: Fresh venv install + installed-wheel proof
        # The x86_64 runner cannot install an aarch64 wheel; aarch64 runtime
        # conformance is skipped here exactly as in release.yml, and the
        # aarch64 wheel is still built + ABI/GLIBC/content verified.
        if: ${{ matrix.target != 'aarch64-unknown-linux-gnu' }}
        shell: bash
        run: |
          set -euo pipefail
          python -m venv /tmp/wheel-venv
          if [ -f /tmp/wheel-venv/Scripts/python.exe ]; then
            VENV_PY=/tmp/wheel-venv/Scripts/python.exe
          else
            VENV_PY=/tmp/wheel-venv/bin/python
          fi
          "$VENV_PY" -m pip install --quiet --upgrade pip
          "$VENV_PY" -m pip install --quiet dist/*.whl
          "$VENV_PY" python/scripts/wheel_proof.py

      - name: Upload wheel artifact
        uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
        with:
          name: wheel-${{ matrix.target }}
          path: dist/*.whl
          if-no-files-found: error
          retention-days: 7

  python-version-matrix:
    # Prove that the SAME manylinux x86_64 wheel installs and runs on multiple
    # CPython versions (py3-none-<platform> claim). Requires no rebuild.
    needs: wheel-matrix
    runs-on: ubuntu-latest
    timeout-minutes: 20
    strategy:
      fail-fast: false
      matrix:
        python: ["3.10", "3.12", "3.14"]
    steps:
      - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0

      - name: Set up Python ${{ matrix.python }}
        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
        with:
          python-version: ${{ matrix.python }}

      - name: Download Linux x86_64 wheel
        uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
        with:
          name: wheel-x86_64-unknown-linux-gnu
          path: dist

      - name: Install SAME wheel into Python ${{ matrix.python }} and prove it
        shell: bash
        run: |
          set -euo pipefail
          python -m venv /tmp/wheel-venv
          if [ -f /tmp/wheel-venv/Scripts/python.exe ]; then
            VENV_PY=/tmp/wheel-venv/Scripts/python.exe
          else
            VENV_PY=/tmp/wheel-venv/bin/python
          fi
          "$VENV_PY" -m pip install --quiet --upgrade pip
          "$VENV_PY" -m pip install --quiet dist/*.whl
          "$VENV_PY" python/scripts/wheel_proof.py

  datatrove-smoke:
    # Packaged DataTrove integration smoke on one mainstream Python version.
    needs: wheel-matrix
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0

      - name: Set up Python 3.12
        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
        with:
          python-version: "3.12"

      - name: Download Linux x86_64 wheel
        uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
        with:
          name: wheel-x86_64-unknown-linux-gnu
          path: dist

      - name: Install wheel with datatrove extra and run integration tests
        shell: bash
        run: |
          set -euo pipefail
          python -m venv /tmp/dt-venv
          if [ -f /tmp/dt-venv/Scripts/python.exe ]; then
            VENV_PY=/tmp/dt-venv/Scripts/python.exe
          else
            VENV_PY=/tmp/dt-venv/bin/python
          fi
          "$VENV_PY" -m pip install --quiet --upgrade pip
          WHEEL=$(ls dist/*.whl | head -n1)
          "$VENV_PY" -m pip install --quiet "${WHEEL}[datatrove]"
          "$VENV_PY" -m pip install --quiet pytest
          "$VENV_PY" -m pytest python/tests/test_datatrove_integration.py -q

  sdist:
    # Source distribution: packaged from the release tree and verified. An sdist
    # rebuilds the native library with Cargo (documented requirement) and must
    # contain the Rust sources and packaging metadata but no build outputs.
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0

      - name: Set up Python 3.12
        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
        with:
          python-version: "3.12"

      - name: Install Python build tooling
        shell: bash
        run: |
          set -euo pipefail
          python -m pip install --quiet --upgrade pip
          python -m pip install --quiet build wheel setuptools

      - name: Build and verify sdist
        shell: bash
        run: |
          set -euo pipefail
          python -m build --sdist .
          SDIST=$(ls dist/*.tar.gz | head -n 1)
          test -n "$SDIST"
          echo "sdist=$SDIST"

          # Version provenance: sdist PKG-INFO must match Cargo.toml.
          CARGO_VERSION=$(sed -n 's/^version = "\([^"]*\)"/\1/p' Cargo.toml | head -1)
          tar tzf "$SDIST" >/dev/null
          PKG_INFO=$(tar xOf "$SDIST" --wildcards "mmap_chunker_core-$CARGO_VERSION/PKG-INFO")
          printf '%s\n' "$PKG_INFO" | grep -F "Version: $CARGO_VERSION"
          printf '%s\n' "$PKG_INFO" | grep -F 'Name: mmap-chunker-core'

          # Required sources/metadata present; build outputs absent.
          # NOTE: avoid `grep -q` on a `tar` pipe — early exit SIGPIPEs tar and
          # pipefail turns it into a false failure.
          for f in Cargo.toml mmap_chunker.h setup.py pyproject.toml \
                    src/lib.rs python/mmap_chunker/__init__.py \
                    python/mmap_chunker/_native.py python/mmap_chunker/planning.py \
                    python/mmap_chunker/py.typed; do
            if ! tar tzf "$SDIST" | grep -E "(^|/)$f\$" >/dev/null; then
              echo "ERROR: sdist is missing required file $f" >&2
              exit 1
            fi
          done
          if tar tzf "$SDIST" | grep -E '(^|/)(target|\.worktrees|\.git)(/|$)' >/dev/null \
             || tar tzf "$SDIST" | grep -E '(\.crate|\.whl|\.so$|\.dll$|\.dylib$)' >/dev/null; then
            echo "ERROR: sdist contains build outputs or foreign artifacts" >&2
            exit 1
          fi
          echo "PASS: sdist version, metadata, and content contract verified"
      - name: Upload sdist artifact
        uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
        with:
          name: python-sdist
          path: dist/*.tar.gz
          if-no-files-found: error
          retention-days: 7