petekstatic 0.1.12

petekStatic — the GEOMODEL layer: structural framework, grid construction, property modelling, volumetrics and static uncertainty, consolidated into one crate.
Documentation
name: CI

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

env:
  CARGO_TERM_COLOR: always

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

jobs:
  rust:
    name: fmt / clippy / test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy, rustfmt
      - uses: Swatinem/rust-cache@v2.9.1
      - name: fmt
        run: cargo fmt --all --check
      - name: clippy (warnings = errors)
        run: cargo clippy --workspace --all-targets --all-features -- -D warnings
      - name: test
        run: cargo test --workspace --all-features
      - name: geomodel core has no petekIO edge
        run: |
          cargo tree -p petekstatic --no-default-features -e normal > /tmp/petekstatic-core-tree.txt
          if grep -q 'petekio v' /tmp/petekstatic-core-tree.txt; then
            echo "petekIO leaked into the default geomodel core" >&2
            exit 1
          fi

  wheel-build:
    name: build abi3 wheel once
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2.9.1
      - uses: actions/setup-python@v6
        with:
          python-version: "3.10"
      - name: install maturin
        run: pip install maturin
      - name: build release wheel
        run: maturin build --release --out dist
      - uses: actions/upload-artifact@v7
        with:
          name: ci-abi3-wheel
          path: dist/*.whl

  wheel:
    name: same abi3 wheel + pytest (py ${{ matrix.python-version }})
    needs: wheel-build
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}
          allow-prereleases: true
      - uses: actions/download-artifact@v8
        with:
          name: ci-abi3-wheel
          path: dist
      - name: install pytest
        run: pip install pytest
      - name: install wheel
        run: |
          for attempt in 1 2 3 4 5 6; do
            python -m pip install --no-cache-dir --only-binary=:all: dist/*.whl && break
            if [ "$attempt" = "6" ]; then
              exit 1
            fi
            sleep $((attempt * 20))
          done
      - name: pytest (wheel surface)
        run: pytest python/tests -q
      - name: import without petekIO + build_flat_model smoke
        run: |
          python - <<'PY'
          import importlib.util
          import petekstatic
          assert importlib.util.find_spec("petekio") is None
          m = petekstatic.build_flat_model()
          ip = m.in_place(boi=1.25)
          assert ip["ooip_sm3"] > 0.0
          print("petekstatic ok:", ip["ooip_sm3"])
          PY

  wheel-windows:
    # Windows release-target tripwire: the 0.1.0 release shipped with NO
    # win_amd64 wheel and nobody noticed until a user hit it. This job builds
    # + installs + smokes the wheel on windows-latest so a missing/broken
    # Windows target fails CI, not a user's `pip install`. One interpreter is
    # enough (abi3-py310); the smoke, not the full pytest, is the point.
    name: wheel build + smoke (windows)
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v7
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2.9.1
      - uses: actions/setup-python@v6
        with:
          python-version: "3.11"
      - name: install maturin
        run: pip install maturin
      - name: build release wheel
        run: maturin build --release --out dist
      - name: install wheel
        shell: pwsh
        run: |
          $wheel = Get-ChildItem dist -Filter *.whl | Select-Object -First 1
          for ($attempt = 1; $attempt -le 6; $attempt++) {
            python -m pip install --no-cache-dir --only-binary=:all: $wheel.FullName
            if ($LASTEXITCODE -eq 0) { break }
            if ($attempt -eq 6) { exit $LASTEXITCODE }
            Start-Sleep -Seconds ($attempt * 20)
          }
      - name: import + build_flat_model smoke
        shell: python
        run: |
          import petekstatic
          m = petekstatic.build_flat_model()
          ip = m.in_place(boi=1.25)
          assert ip["ooip_sm3"] > 0.0
          print("petekstatic ok on windows:", ip["ooip_sm3"])