name: Build and deploy

on:
  workflow_dispatch:
  release:
    types:
      - published

jobs:
  build_sdist:
    name: Build and test source distribution
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: 'pip'
      - run: python -m pip install --upgrade pip build twine
      - run: python -m build --sdist
      - run: python -m twine check dist/*
      - run: pip install --pre "$(ls dist/hdf5plugin*.tar.gz)[test]"
      - run: python test/test.py
      - uses: actions/upload-artifact@v4
        with:
          name: cibw-sdist
          path: dist/*.tar.gz

  build_doc:
    name: Build documentation
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
          cache: "pip"
      - run: sudo apt-get install pandoc
      - run: pip install .[doc]
        env:
          HDF5PLUGIN_STRIP: all  # Do not build the filters
      - name: Build doc
        run: |
          export OUTPUT_NAME="hdf5plugin-$(python -c 'import hdf5plugin; print(hdf5plugin.version)')_documentation"
          sphinx-build doc/ "${OUTPUT_NAME}/"
          zip -r "${OUTPUT_NAME}.zip" "${OUTPUT_NAME}/"
      - uses: actions/upload-artifact@v4
        with:
          name: documentation
          path: hdf5plugin-*_documentation.zip

  build_wheels:
    name: Build wheels on ${{ matrix.os }}-${{ matrix.cibw_archs }}
    runs-on: ${{ matrix.os }}
    strategy:
      # Ensure that a wheel builder finishes even if another fails
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-20.04
            cibw_archs: "auto64"
            with_sse2: true
          - os: ubuntu-20.04
            cibw_archs: "aarch64"
            with_sse2: false
          - os: ubuntu-20.04
            cibw_archs: "ppc64le"
            with_sse2: false
          - os: windows-2019
            cibw_archs: "auto64"
            with_sse2: true
          - os: macos-13
            cibw_archs: "universal2"
            with_sse2: true

    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-qemu-action@v3
        if: runner.os == 'Linux'
        with:
          platforms: all
      - uses: pypa/cibuildwheel@v2.23.0
        env:
          # Configure hdf5plugin build
          HDF5PLUGIN_OPENMP: "False"
          HDF5PLUGIN_NATIVE: "False"
          HDF5PLUGIN_SSE2: ${{ matrix.with_sse2 && 'True' || 'False' }}
          HDF5PLUGIN_SSSE3: "False"
          HDF5PLUGIN_AVX2: "False"
          HDF5PLUGIN_AVX512: "False"
          HDF5PLUGIN_BMI2: "False"
          HDF5PLUGIN_CPP11: "True"
          HDF5PLUGIN_CPP14: "True"
          HDF5PLUGIN_CPP20: "True"
          MACOSX_DEPLOYMENT_TARGET: "10.13"

          CIBW_ENVIRONMENT_PASS_LINUX: HDF5PLUGIN_OPENMP HDF5PLUGIN_NATIVE HDF5PLUGIN_SSE2 HDF5PLUGIN_SSSE3 HDF5PLUGIN_AVX2 HDF5PLUGIN_AVX512 HDF5PLUGIN_BMI2 HDF5PLUGIN_CPP11 HDF5PLUGIN_CPP14 HDF5PLUGIN_CPP20

          CIBW_BUILD_VERBOSITY: 1
          # Use Python3.11 to build wheels that are compatible with all supported version of Python
          CIBW_BUILD: cp311-*
          # Do not build for pypy and muslinux
          CIBW_SKIP: pp* *-musllinux_*
          CIBW_ARCHS: ${{ matrix.cibw_archs }}

          # Use silx wheelhouse for ppc64le
          # Use numpy<2 since a wheel for h5py v3.11 which supports numpy v2 is not available for aarch64
          # see https://github.com/h5py/h5py/issues/2408
          CIBW_BEFORE_TEST: pip install "numpy<2" h5py --only-binary ":all:" --find-links=https://www.silx.org/pub/wheelhouse/ --trusted-host=www.silx.org
          CIBW_TEST_COMMAND: python {project}/test/test.py
      - uses: actions/upload-artifact@v4
        with:
          name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
          path: ./wheelhouse/*.whl

  test_wheels:
    needs: [build_wheels]
    name: Test wheel on ${{ matrix.os }}-${{ matrix.python-version }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-13, macos-latest]
        python-version: ['3.8', '3.12']
        include:
          - python-version: '3.8'
            OLDEST_DEPENDENCIES: 'h5py==3.0.0 "numpy<2"'
          - python-version: '3.8'
            os: 'macos-latest'
            OLDEST_DEPENDENCIES: 'h5py==3.7.0 "numpy<2"'
          - python-version: '3.12'
            OLDEST_DEPENDENCIES: 'h5py==3.10.0 "numpy<2"'

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
          cache: 'pip'
      - uses: actions/download-artifact@v4
        with:
          pattern: cibw-wheels-*
          path: dist
          merge-multiple: true
      - name: Install hdf5plugin
        # First select the right wheel from dist/ with pip download, then install it
        run: |
          pip download --no-index --no-cache --no-deps --find-links=./dist --only-binary :all: hdf5plugin
          pip install "$(ls ./hdf5plugin-*.whl)[test]"
      - name: Run test with latest h5py
        run: python test/test.py
      - name: Run test with oldest h5py
        run: |
          pip install ${{ matrix.OLDEST_DEPENDENCIES }}
          python test/test.py

  pypi-publish:
    needs: [build_wheels, build_sdist, build_doc, test_wheels]
    name: Upload release to PyPI
    runs-on: ubuntu-latest
    environment:
      name: pypi
    permissions:
      id-token: write
    if: github.event_name == 'release' && github.event.action == 'published'
    # or, alternatively, upload to PyPI on every tag starting with 'v' (remove on: release above to use this)
    # if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
    steps:
      - uses: actions/download-artifact@v4
        with:
          pattern: cibw-*
          path: dist
          merge-multiple: true
      - uses: pypa/gh-action-pypi-publish@release/v1
