name: Build PYPI wheels for opencv-python on Macos

on:
  pull_request:
    branches:
      - master
    paths-ignore:
      - '.github/workflows/build_wheels_linux*'
      - '.github/workflows/build_wheels_windows*'
      - '.github/workflows/build_wheels_macos_m1.yml'
  release:
    types: [published, edited]


jobs:
  build:
    runs-on: ${{ matrix.os }}
    defaults:
      run:
        shell: bash

    strategy:
      fail-fast: false
      matrix:
        os: [macos-10.15, macos-11]
        python-version: ['3.6']
        platform: [x64]
        with_contrib: [0, 1]
        without_gui: [0, 1]
        build_sdist: [0]
        exclude:
          - os: macos-10.15
            python-version: '3.10'
          - os: macos-11
            python-version: '3.6'
          - os: macos-11
            python-version: '3.7'
          - os: macos-11
            python-version: '3.8'
          - os: macos-11
            python-version: '3.9'

    env:
      ACTIONS_ALLOW_UNSECURE_COMMANDS: true
      REPO_DIR: .
      BUILD_COMMIT: master
      PROJECT_SPEC: opencv-python
      MB_PYTHON_VERSION: ${{ matrix.python-version }}
      TRAVIS_PYTHON_VERSION: ${{ matrix.python-version }}
      MB_ML_VER: 2014
      TRAVIS_BUILD_DIR: ${{ github.workspace }}
      TRAVIS_OS_NAME: osx
      CONFIG_PATH: travis_config.sh
      DOCKER_IMAGE: quay.io/asenyaev/manylinux2014_${PLAT}
      USE_CCACHE: 1
      UNICODE_WIDTH: 32
      PLAT: x86_64
      FFMPEG_FORMULA_VERSION: '@4'
      SDIST: ${{ matrix.build_sdist || 0 }}
      ENABLE_HEADLESS: ${{ matrix.without_gui }}
      ENABLE_CONTRIB: ${{ matrix.with_contrib }}

    steps:
    - name: Checkout
      uses: actions/checkout@v2
      with:
        submodules: false
        fetch-depth: 0

    - name: Update submodules
      if: github.event_name == 'pull_request'
      run: git submodule update --remote

    - name: Build a package
      run: |
        set -e
        # Check out and prepare the source
        # Multibuild doesn't have releases, so --depth would break eventually (see
        # https://superuser.com/questions/1240216/server-does-not-allow-request-for-unadvertised)
        git submodule update --init multibuild
        source multibuild/common_utils.sh
        # https://github.com/matthew-brett/multibuild/issues/116
        if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export ARCH_FLAGS=" "; fi
        source multibuild/travis_steps.sh
        # This sets -x
        # source travis_multibuild_customize.sh
        echo $ENABLE_CONTRIB > contrib.enabled
        echo $ENABLE_HEADLESS > headless.enabled
        set -x
        build_wheel $REPO_DIR $PLAT

    - name: Saving all wheels
      uses: actions/upload-artifact@v2
      with:
        name: wheels
        path: wheelhouse/opencv*.whl

    - name: Saving a wheel accordingly to matrix
      uses: actions/upload-artifact@v2
      with:
        name: wheel-${{ matrix.with_contrib }}-${{ matrix.without_gui }}-${{ matrix.build_sdist }}
        path: wheelhouse/opencv*.whl

  test:
    needs: [build]
    runs-on: ${{ matrix.os }}
    defaults:
      run:
        shell: bash

    strategy:
      fail-fast: false
      matrix:
        os: [macos-10.15, macos-11]
        python-version: ['3.6', '3.7', '3.8', '3.9', '3.10']
        platform: [x64]
        with_contrib: [0, 1]
        without_gui: [0, 1]
        build_sdist: [0]
        exclude:
          - os: macos-10.15
            python-version: '3.10'
          - os: macos-11
            python-version: '3.6'
          - os: macos-11
            python-version: '3.7'
          - os: macos-11
            python-version: '3.8'
          - os: macos-11
            python-version: '3.9'

    env:
      ACTIONS_ALLOW_UNSECURE_COMMANDS: true
      MB_PYTHON_VERSION: ${{ matrix.python-version }}
      NP_TEST_DEP: numpy==1.19.4
      NP_TEST_DEP_LATEST: numpy==1.21.4
      CONFIG_PATH: travis_config.sh
      PLAT: x86_64
      OPENCV_TEST_DATA_PATH: ${{ github.workspace }}/opencv_extra/testdata
      PYLINT_TEST_FILE: ${{ github.workspace }}/opencv/samples/python/squares.py

    steps:
    - name: Checkout
      uses: actions/checkout@v2
      with:
        submodules: true
        fetch-depth: 0

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v2
      with:
        python-version: ${{ matrix.python-version }}
        architecture: ${{ matrix.platform }}

    - name: Setup Environment variables
      run: if [ "3.10" == "${{ matrix.python-version }}" ]; then echo "TEST_DEPENDS=$(echo $NP_TEST_DEP_LATEST)" >> $GITHUB_ENV; else echo "TEST_DEPENDS=$(echo $NP_TEST_DEP)" >> $GITHUB_ENV; fi

    - name: Download a wheel accordingly to matrix
      uses: actions/download-artifact@v2
      with:
        name: wheel-${{ matrix.with_contrib }}-${{ matrix.without_gui }}-${{ matrix.build_sdist }}
        path: wheelhouse/

    - name: Package installation
      run: |
        python -m pip install wheelhouse/opencv*.whl
        cd ${{ github.workspace }}/tests
        python get_build_info.py

    - name: Run tests
      run: |
        cd ${{ github.workspace }}/opencv
        python modules/python/test/test.py -v --repo .

    - name: Pylint test
      run: |
        python -m pip install pylint==2.12.2
        cd ${{ github.workspace }}/tests
        python -m pylint $PYLINT_TEST_FILE

  test_release_opencv_python:
    if: github.event_name == 'release' && github.event.release.prerelease
    needs: [build, test]
    runs-on: ubuntu-latest
    environment: test-opencv-python-release
    defaults:
      run:
        shell: bash
    steps:
      - uses: actions/download-artifact@v2
        with:
          name: wheels
          path: wheelhouse/

      - name: Upload all wheels
        run: |
          python -m pip install twine
          python -m twine upload --repository testpypi -u ${{ secrets.PYPI_USERNAME }} -p ${{ secrets.PYPI_PASSWORD }} --skip-existing wheelhouse/opencv_*

  release_opencv_python:
    if: github.event_name == 'release' && !github.event.release.prerelease
    needs: [build, test]
    runs-on: ubuntu-latest
    environment: opencv-python-release
    defaults:
      run:
        shell: bash
    steps:
      - uses: actions/download-artifact@v2
        with:
          name: wheels
          path: wheelhouse/

      - name: Upload wheels for opencv_python
        run: |
          python -m pip install twine
          python -m twine upload -u ${{ secrets.OPENCV_PYTHON_USERNAME }} -p ${{ secrets.OPENCV_PYTHON_PASSWORD }} --skip-existing wheelhouse/opencv_python-*

      - name: Upload wheels for opencv_contrib_python
        run: |
          python -m pip install twine
          python -m twine upload -u ${{ secrets.OPENCV_CONTRIB_PYTHON_USERNAME }} -p ${{ secrets.OPENCV_CONTRIB_PYTHON_PASSWORD }} --skip-existing wheelhouse/opencv_contrib_python-*

      - name: Upload wheels for opencv_python_headless
        run: |
          python -m pip install twine
          python -m twine upload -u ${{ secrets.OPENCV_PYTHON_HEADLESS_USERNAME }} -p ${{ secrets.OPENCV_PYTHON_HEADLESS_PASSWORD }} --skip-existing wheelhouse/opencv_python_headless-*

      - name: Upload wheels for opencv_contrib_python_headless
        run: |
          python -m pip install twine
          python -m twine upload -u ${{ secrets.OPENCV_CONTRIB_PYTHON_HEADLESS_USERNAME }} -p ${{ secrets.OPENCV_CONTRIB_PYTHON_HEADLESS_PASSWORD }} --skip-existing wheelhouse/opencv_contrib_python_headless-*
