# Copyright (c) ONNX Project Contributors
#
# SPDX-License-Identifier: Apache-2.0

name: MacRelease

on:
  schedule:
    # Run weekly on Monday 00:00
    - cron:  '00 00 * * MON'
  push:
    branches: [main, rel-*]
  pull_request:
    branches: [main, rel-*]
  workflow_dispatch:

# Use MACOSX_DEPLOYMENT_TARGET=12.0 to produce compatible wheel
env:
  MACOSX_DEPLOYMENT_TARGET: "12.0"

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name == 'workflow_dispatch' }}
  cancel-in-progress: true

jobs:
  build:
    if: github.event_name != 'pull_request' || startsWith( github.base_ref, 'rel-') || contains( github.event.pull_request.labels.*.name, 'run release CIs')
    runs-on: macos-latest
    strategy:
      matrix:
        python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']

    steps:
    - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
    - name: Checkout submodules
      shell: bash
      run: |
        auth_header="$(git config --local --get http.https://github.com/.extraheader)"
        git submodule sync --recursive
        git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
      with:
        python-version: ${{ matrix.python-version }}

    - name: Install Python dependencies
      run: |
        python -m pip install -q --upgrade pip
        python -m pip install -q -r requirements-release.txt

    - name: Build wheel and install
      env:
        CC: "clang"
        CXX: "clang++"
        ONNX_ML: 1
        CMAKE_OSX_ARCHITECTURES: "arm64;x86_64"
        CMAKE_ARGS: "-DONNX_USE_LITE_PROTO=ON"
      run: |
        # Install Protobuf from source
        export NUM_CORES=`sysctl -n hw.logicalcpu`
        source workflow_scripts/protobuf/build_protobuf_unix.sh $NUM_CORES $(pwd)/protobuf/protobuf_install
        if [ '${{ github.event_name }}' == 'schedule' ]; then
          sed -i '' 's/name = "onnx"/name = "onnx-weekly"/' 'pyproject.toml'
          export ONNX_PREVIEW_BUILD=1
        fi
        python -m build --wheel

    - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
      with:
        name: macos-wheel-${{ matrix.python-version }}
        path: dist

  test:
    needs: build
    runs-on: ${{ (matrix.target-architecture == 'x86_64') && 'macos-12' || 'macos-14' }}
    strategy:
      matrix:
        python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
        target-architecture: ['x86_64', 'arm64']

    steps:
    - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
      with:
        python-version: ${{ matrix.python-version }}

    - name: Install Python dependencies
      run: |
        arch -${{ matrix.target-architecture }} python -m pip install -q --upgrade pip
        arch -${{ matrix.target-architecture }} python -m pip install -q -r requirements-release.txt

    - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
      with:
        name: macos-wheel-${{ matrix.python-version }}
        path: dist

    - name: Test the wheel
      run: |
        arch -${{ matrix.target-architecture }} python -m pip install --upgrade dist/*.whl
        arch -${{ matrix.target-architecture }} pytest

    - name: Upload wheel to PyPI weekly
      if: github.event_name == 'schedule' && matrix.target-architecture == 'arm64'  # Only triggered by weekly event
      run: |
        twine upload --verbose dist/*.whl --repository-url https://upload.pypi.org/legacy/ -u ${{ secrets.ONNXWEEKLY_USERNAME }} -p ${{ secrets.ONNXWEEKLY_TOKEN }}

    - name: Verify ONNX with the latest numpy
      if: ${{ always() }}
      run: |
        arch -${{ matrix.target-architecture }} python -m pip uninstall -y numpy onnx
        arch -${{ matrix.target-architecture }} python -m pip install numpy
        arch -${{ matrix.target-architecture }} python -m pip install --upgrade dist/*.whl
        arch -${{ matrix.target-architecture }} pytest

    - name: Verify ONNX with the latest protobuf
      if: ${{ always() }}
      run: |
        arch -${{ matrix.target-architecture }} python -m pip uninstall -y protobuf onnx
        arch -${{ matrix.target-architecture }} python -m pip install protobuf
        arch -${{ matrix.target-architecture }} python -m pip install --upgrade dist/*.whl
        arch -${{ matrix.target-architecture }} pytest

    - name: Verify ONNX with the minimumly supported packages
      if: always() && (matrix.target-architecture == 'x86_64' || (matrix.python-version != '3.8' && matrix.python-version != '3.9'))
      run: |
        arch -${{ matrix.target-architecture }} python -m pip uninstall -y numpy protobuf onnx
        arch -${{ matrix.target-architecture }} python -m pip install -r requirements-min.txt
        arch -${{ matrix.target-architecture }} python -m pip install --upgrade dist/*.whl
        arch -${{ matrix.target-architecture }} pytest

    # Only triggered by weekly event on certain CI
    - name: Build and upload source distribution to PyPI weekly
      if: github.event_name == 'schedule' && matrix.python-version == '3.10' && matrix.target-architecture == 'arm64'
      run: |
        # Build and upload source distribution to PyPI
        git clean -xdf
        sed -i '' 's/name = "onnx"/name = "onnx-weekly"/' 'pyproject.toml'
        ONNX_PREVIEW_BUILD=1 python -m build --sdist
        twine upload dist/* --repository-url https://upload.pypi.org/legacy/ -u ${{ secrets.ONNXWEEKLY_USERNAME }} -p ${{ secrets.ONNXWEEKLY_TOKEN }}

        # Test weekly source distribution from PyPI
        python -m pip uninstall -y onnx-weekly
        python -m pip install setuptools
        python -m pip install --use-deprecated=legacy-resolver --no-binary onnx-weekly onnx-weekly
        pytest

    - name: Verify ONNX with ONNX Runtime PyPI package
      if: matrix.python-version != '3.12'
      run: |
        arch -${{ matrix.target-architecture }} python -m pip uninstall -y protobuf numpy
        arch -${{ matrix.target-architecture }} python -m pip install -q -r requirements-release.txt
        arch -${{ matrix.target-architecture }} python -m pip install -q onnxruntime==1.17.3
        export ORT_MAX_IR_SUPPORTED_VERSION=9
        export ORT_MAX_ML_OPSET_SUPPORTED_VERSION=3
        export ORT_MAX_ONNX_OPSET_SUPPORTED_VERSION=20
        arch -${{ matrix.target-architecture }} pytest
