Test for DeepChem Jax

name: Test for DeepChem Jax
on:
  push: # ci work when pushing master branch
    branches:
      - master
  pull_request: # ci work when creating a PR to master branch
    branches:
      - master
jobs:
  jax-build:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version: ['3.9', '3.10', '3.11']
    steps:
    - uses: actions/checkout@v4
    - name: Cache pip modules for Linux
      uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements/jax/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Build DeepChem
      run: |
        python -m pip install --upgrade pip
        pip install -e '.[jax]'
    - name: Import checking
      run: python -c "import deepchem; import jax;"

  jax-test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest]
        python-version: ['3.9', '3.10', '3.11']
    env:
      OS: ${{ matrix.os }}
      PYTHON_VERSION: ${{ matrix.python-version }}
    steps:
    - name: Maximize build space
      if: matrix.os == 'ubuntu-latest'
      run: |
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /opt/ghc
        sudo rm -rf "/usr/local/share/boost"
        sudo rm -rf "$AGENT_TOOLSDIRECTORY"
        sudo rm -rf /usr/local/lib/android
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
    # https://github.com/galaxyproject/tools-iuc/blob/master/.github/workflows/pr.yaml
    # The range of commits to check for changes is:
    # - for events on the master branch we compare against the sha before the event
    #   (note that this does not work for feature branch events since we want all
    #   commits on the feature branch and not just the commits of the last event)
    # - for pull requests we compare against the 1st ancestor, given the current
    #   HEAD is the merge between the PR branch and the base branch
    - name: Set commit range (push to the master branch, e.g. merge)
      if: github.ref == 'refs/heads/master' && github.event_name == 'push'
      run: echo "COMMIT_RANGE=${{ github.event.before }}.." >> $GITHUB_ENV
    - name: Set commit range (pull request)
      if: github.event_name == 'pull_request'
      run: |
        git fetch origin master
        echo "COMMIT_RANGE=origin/master..." >> $GITHUB_ENV
    - name: Cache pip packages for Linux
      if: runner.os == 'Linux'
      uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements/jax/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Cache pip packages for MacOS
      if: runner.os == 'macOS'
      uses: actions/cache@v4
      with:
        path: ~/Library/Caches/pip
        key: ${{ matrix.os }}-pip-${{ hashFiles('requirements/jax/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Cache pip packages for Windows
      if: runner.os == 'Windows'
      uses: actions/cache@v4
      with:
        path: ~\AppData\Local\pip\Cache
        key: ${{ matrix.os }}-pip-${{ hashFiles('requirements/jax/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Create env.yml
      shell: bash
      run: |
        python -m pip install --upgrade pip;
        pip install conda-merge;
        conda-merge requirements/env_common.yml requirements/env_test.yml requirements/jax/env_jax.cpu.yml > env.yml
    - name: Install all dependencies
      uses: conda-incubator/setup-miniconda@v3
      with:
        miniconda-version: "latest"
        auto-update-conda: true
        activate-environment: deepchem
        channels: conda-forge,defaults
        python-version: ${{ matrix.python-version }}
        environment-file: env.yml
    - name: Install DeepChem
      id: install
      shell: bash -l {0}
      run: pip install -e .
    - name: PyTest
      if: ${{ (success() || failure()) && (steps.install.outcome == 'failure' || steps.install.outcome == 'success') }}
      shell: bash -l {0}
      run: pytest -v -m 'jax' deepchem


Test for Build

name: Test for Build
on:
  push: # ci work when pushing master branch
    branches:
      - master
  pull_request: # ci work when creating a PR to master branch
    branches:
      - master
jobs:
  core-build:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest]
        python-version: ['3.8', '3.10', '3.11']
        include:
        - os: windows-latest
          python-version: '3.9'
    steps:
    - uses: actions/checkout@v4
      # using cached dependencies to speed up workflow
      # ref: https://docs.github.com/en/actions/advanced-guides/caching-dependencies-to-speed-up-workflows
    - name: Cache pip modules for Linux
      uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        # the key is used to search for cache
        # hashFile(paths) return a single hash for the set of files that matches the path pattern
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Build DeepChem
      run: |
        python -m pip install --upgrade pip
        pip install -e .
    - name: Import checking
      run: python -c "import deepchem"

  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest]
        python-version: ['3.8', '3.10', '3.11']
        include:
          - os: windows-latest
            python-version: 3.9
    env:
      OS: ${{ matrix.os }}
      PYTHON_VERSION: ${{ matrix.python-version }}
    steps:
    - name: Maximize build space
      if: matrix.os == 'ubuntu-latest'
      run: |
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /opt/ghc
        sudo rm -rf "/usr/local/share/boost"
        sudo rm -rf "$AGENT_TOOLSDIRECTORY"
        sudo rm -rf /usr/local/lib/android
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
    # https://github.com/galaxyproject/tools-iuc/blob/master/.github/workflows/pr.yaml
    # The range of commits to check for changes is:
    # - for events on the master branch we compare against the sha before the event
    #   (note that this does not work for feature branch events since we want all
    #   commits on the feature branch and not just the commits of the last event)
    # - for pull requests we compare against the 1st ancestor, given the current
    #   HEAD is the merge between the PR branch and the base branch
    - name: Set commit range (push to the master branch, e.g. merge)
      if: github.ref == 'refs/heads/master' && github.event_name == 'push'
      run: echo "COMMIT_RANGE=${{ github.event.before }}.." >> $GITHUB_ENV
    - name: Set commit range (pull request)
      if: github.event_name == 'pull_request'
      run: |
        git fetch origin master
        echo "COMMIT_RANGE=origin/master..." >> $GITHUB_ENV
    - name: Cache pip packages for Linux
      if: runner.os == 'Linux'
      uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Cache pip packages for MacOS
      if: runner.os == 'macOS'
      uses: actions/cache@v4
      with:
        path: ~/Library/Caches/pip
        key: ${{ matrix.os }}-pip-${{ hashFiles('requirements/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Cache pip packages for Windows
      if: runner.os == 'Windows'
      uses: actions/cache@v4
      with:
        path: ~\AppData\Local\pip\Cache
        key: ${{ matrix.os }}-pip-${{ hashFiles('requirements/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install prerequisites for XGBoost and LightGBM (MacOS)
      if: startsWith(runner.os, 'macOS')
      run: brew update && brew install libomp
    - name: Create env.yml for python >3.8
      shell: bash
      if: ${{ matrix.python-version != '3.8' && matrix.python-version != '3.11'}}
      run: |
        python -m pip install --upgrade pip;
        pip install conda-merge;
        cd requirements
        if [ "$(uname)" == 'Linux' ]; then
          conda-merge env_common.yml env_test.yml env_ubuntu.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.cpu.yml jax/env_jax.cpu.yml > env.yml
        elif [  "$(uname)" == 'Darwin' ]; then
          conda-merge env_common.yml env_test.yml env_mac.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.mac.cpu.yml jax/env_jax.cpu.yml > env.yml
        elif [[  "$(uname)" == "MINGW64_NT"* ]]; then
          conda-merge env_common.yml env_test.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.cpu.yml > env.yml
        fi;
        cd ..
        cp requirements/env.yml env.yml
    - name: Create env.yml for python 3.11
      shell: bash
      # A special case of environment creation for python 3.8 which excludes hhsuite
      if: ${{ matrix.python-version == '3.11' }}
      run: |
        python -m pip install --upgrade pip;
        pip install conda-merge;
        cd requirements
        if [ "$(uname)" == 'Linux' ]; then
          conda-merge env_common.yml env_test.yml env_ubuntu_3_11.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.cpu.yml > env.yml
        elif [  "$(uname)" == 'Darwin' ]; then
          conda-merge env_common.yml env_test.yml env_mac_3_11.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.mac.cpu.yml > env.yml
        elif [[  "$(uname)" == "MINGW64_NT"* ]]; then
          conda-merge env_common.yml env_test.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.cpu.yml > env.yml
        fi;
        cd ..
        cp requirements/env.yml env.yml
    - name: Create env.yml for python 3.8
      shell: bash
      # A special case of environment creation for python 3.8 which excludes jax [deprecated]
      if: ${{ matrix.python-version == '3.8' }}
      run: |
        python -m pip install --upgrade pip;
        pip install conda-merge;
        cd requirements
        if [ "$(uname)" == 'Linux' ]; then
          conda-merge env_common_3_8.yml env_test.yml env_ubuntu.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.cpu.yml > env.yml
        elif [  "$(uname)" == 'Darwin' ]; then
          conda-merge env_common_3_8.yml env_test.yml env_mac.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.mac.cpu.yml > env.yml
        elif [[  "$(uname)" == "MINGW64_NT"* ]]; then
          conda-merge env_common_3_8.yml env_test.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.cpu.yml > env.yml
        fi;
        cd ..
        cp requirements/env.yml env.yml
    - name: Install all dependencies using micromamba
      uses: mamba-org/setup-micromamba@main
      with:
        environment-file: env.yml
        environment-name: deepchem
        create-args: python=${{ matrix.python-version }}

#    - name: Install all dependencies using conda
#      uses: conda-incubator/setup-miniconda@v3
#      with:
#        miniconda-version: "latest"
#        auto-update-conda: true
#        activate-environment: deepchem
#        channels: conda-forge,defaults
#        python-version: ${{ matrix.python-version }}
#        environment-file: env.yml

  pypi-build:
    if: github.event_name == 'push' && github.ref == 'refs/heads/master'
    needs: [core-build]
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.9'
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install setuptools wheel twine
    - name: Publish (Nightly)
      env:
        TWINE_USERNAME: __token__
        TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
      run: |
        python setup.py sdist bdist_wheel
        twine upload dist/*

  docker-build:
    if: github.event_name == 'push' && github.ref == 'refs/heads/master'
    needs: [core-build, pypi-build]
    runs-on: ubuntu-latest
    steps:
    - name: Maximize build space
      run: |
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /opt/ghc
        sudo rm -rf "/usr/local/share/boost"
        sudo rm -rf "$AGENT_TOOLSDIRECTORY"
        sudo rm -rf /usr/local/lib/android
    - uses: actions/checkout@v4
    - name: Set up Docker Buildx
      id: buildx
      uses: docker/setup-buildx-action@master
    - name: Cache Docker layers
      uses: actions/cache@v4
      with:
        path: /tmp/.buildx-cache
        key: ${{ runner.os }}-buildx-${{ github.sha }}
        restore-keys: ${{ runner.os }}-buildx-
    - name: Login to DockerHub
      uses: docker/login-action@v3
      with:
        username: ${{ secrets.DOCKER_HUB_USERNAME }}
        password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
    - name: Build and push
      id: docker_build
      uses: docker/build-push-action@v5
      with:
        builder: ${{ steps.buildx.outputs.name }}
        context: ./docker/nightly
        push: true
        tags: deepchemio/deepchem:latest
        cache-from: type=local,src=/tmp/.buildx-cache
        cache-to: type=local,dest=/tmp/.buildx-cache
    - name: Image digest
      run: echo ${{ steps.docker_build.outputs.digest }}


Release

name: Release
on:
  push:
    tags:
      - '*' # ci work when pushing a tag
jobs:
  pypi:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.9']
    steps:
    - name: Maximize build space
      if: runner.os == 'ubuntu-latest'
      run: |
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /opt/ghc
        sudo rm -rf "/usr/local/share/boost"
        sudo rm -rf "$AGENT_TOOLSDIRECTORY"
        sudo rm -rf /usr/local/lib/android
    - uses: actions/checkout@v4
    - name: Cache pip modules for Linux
      uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('env.*.yml') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Build DeepChem
      run: |
        python -m pip install --upgrade pip
        pip install -e .
    - name: Import checking
      run: python -c "import deepchem"
    - name: Prepare for publishing
      run: |
        rm -rf ./build ./dist ./*egg-info
        pip install setuptools wheel twine
    - name: Publish (Stable)
      env:
        TWINE_USERNAME: __token__
        TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
      run: |
        python setup.py sdist bdist_wheel --release
        twine upload dist/*

  docker:
    needs: [pypi]
    runs-on: ubuntu-latest
    steps:
    - name: Maximize build space
      if: runner.os == 'ubuntu-latest'
      run: |
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /opt/ghc
        sudo rm -rf "/usr/local/share/boost"
        sudo rm -rf "$AGENT_TOOLSDIRECTORY"
        sudo rm -rf /usr/local/lib/android
    - uses: actions/checkout@v4
    - name: Get the tag version
      id: get_tag_version
      run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/}
    - name: Login to DockerHub
      uses: docker/login-action@v3
      with:
        username: ${{ secrets.DOCKER_HUB_USERNAME }}
        password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
    - name: Build and push
      id: docker_build
      uses: docker/build-push-action@v5
      with:
        context: ./docker/tag
        push: true
        tags: deepchemio/deepchem:${{ steps.get_tag_version.outputs.VERSION }}
    - name: Image digest
      run: echo ${{ steps.docker_build.outputs.digest }}


Test for DeepChem Tensorflow

name: Test for DeepChem Tensorflow
on:
  push: # ci work when pushing master branch
    branches:
      - master
  pull_request: # ci work when creating a PR to master branch
    branches:
      - master
jobs:
  tf-build:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest]
        python-version: ['3.8', '3.10', '3.11']
        include:
          - os: windows-latest
            python-version: 3.9
    steps:
    - uses: actions/checkout@v4
    - name: Cache pip modules for Linux
      uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements/tensorflow/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Build DeepChem
      run: |
        python -m pip install --upgrade pip
        pip install -e '.[tensorflow]'
    - name: Import checking
      run: python -c "import deepchem; import tensorflow;"

  tf-test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest]
        python-version: ['3.8', '3.10', '3.11']
        include:
          - os: windows-latest
            python-version: '3.9'
    env:
      OS: ${{ matrix.os }}
      PYTHON_VERSION: ${{ matrix.python-version }}
    steps:
    - name: Maximize build space
      if: matrix.os == 'ubuntu-latest'
      run: |
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /opt/ghc
        sudo rm -rf "/usr/local/share/boost"
        sudo rm -rf "$AGENT_TOOLSDIRECTORY"
        sudo rm -rf /usr/local/lib/android
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
    # https://github.com/galaxyproject/tools-iuc/blob/master/.github/workflows/pr.yaml
    # The range of commits to check for changes is:
    # - for events on the master branch we compare against the sha before the event
    #   (note that this does not work for feature branch events since we want all
    #   commits on the feature branch and not just the commits of the last event)
    # - for pull requests we compare against the 1st ancestor, given the current
    #   HEAD is the merge between the PR branch and the base branch
    - name: Set commit range (push to the master branch, e.g. merge)
      if: github.ref == 'refs/heads/master' && github.event_name == 'push'
      run: echo "COMMIT_RANGE=${{ github.event.before }}.." >> $GITHUB_ENV
    - name: Set commit range (pull request)
      if: github.event_name == 'pull_request'
      run: |
        git fetch origin master
        echo "COMMIT_RANGE=origin/master..." >> $GITHUB_ENV
    - name: Cache pip packages for Linux
      if: runner.os == 'Linux'
      uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements/tensorflow/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Cache pip packages for MacOS
      if: runner.os == 'macOS'
      uses: actions/cache@v4
      with:
        path: ~/Library/Caches/pip
        key: ${{ matrix.os }}-pip-${{ hashFiles('requirements/tensorflow/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Cache pip packages for Windows
      if: runner.os == 'Windows'
      uses: actions/cache@v4
      with:
        path: ~\AppData\Local\pip\Cache
        key: ${{ matrix.os }}-pip-${{ hashFiles('requirements/tensorflow/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Create env.yml for python 3.8
      shell: bash
      # A special case of environment creation for python 3.8 which includes an older version of matminer
      if: ${{ matrix.python-version == '3.8' }}
      run: |
        python -m pip install --upgrade pip;
        pip install conda-merge;
        conda-merge requirements/env_common_3_8.yml requirements/env_test.yml requirements/tensorflow/env_tensorflow.cpu.yml > env.yml
    - name: Create env.yml for python 3.9+
      shell: bash
      if: ${{ matrix.python-version != '3.8' }}
      run: |
        python -m pip install --upgrade pip;
        pip install conda-merge;
        conda-merge requirements/env_common.yml requirements/env_test.yml requirements/tensorflow/env_tensorflow.cpu.yml > env.yml
    - name: Install all dependencies
      uses: conda-incubator/setup-miniconda@v3
      with:
        miniconda-version: "latest"
        auto-update-conda: true
        activate-environment: deepchem
        channels: conda-forge,defaults
        python-version: ${{ matrix.python-version }}
        environment-file: env.yml
    - name: Install DeepChem
      id: install
      shell: bash -l {0}
      run: pip install -e .
    - name: PyTest
      if: ${{ (success() || failure()) && (steps.install.outcome == 'failure' || steps.install.outcome == 'success') }}
      shell: bash -l {0}
      run: pytest -v -m 'tensorflow' deepchem


Unit Tests

name: Unit Tests
on:
  push: # ci work when pushing master branch
    branches:
      - master
  pull_request: # ci work when creating a PR to master branch
    branches:
      - master
jobs:
  core-build:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest]
        python-version: ['3.8', '3.10', '3.11']
        include:
          - os: windows-latest
            python-version: '3.9'
    steps:
    - name: Maximize build space
      if: matrix.os == 'ubuntu-latest'
      run: |
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /opt/ghc
        sudo rm -rf "/usr/local/share/boost"
        sudo rm -rf "$AGENT_TOOLSDIRECTORY"
    - uses: actions/checkout@v4
    - name: Cache pip modules for Linux
      uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements/**.yml') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Build DeepChem
      run: |
        python -m pip install --upgrade pip
        pip install -e .
    - name: Import checking
      run: python -c "import deepchem"

  unit-tests:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest]
        python-version: ['3.8', '3.10', '3.11']
        include:
          - os: windows-latest
            python-version: '3.9'
    env:
      OS: ${{ matrix.os }}
      PYTHON_VERSION: ${{ matrix.python-version }}
    steps:
    - name: Maximize build space
      if: matrix.os == 'ubuntu-latest'
      run: |
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /opt/ghc
        sudo rm -rf "/usr/local/share/boost"
        sudo rm -rf "$AGENT_TOOLSDIRECTORY"
        sudo rm -rf /usr/local/lib/android
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
    # https://github.com/galaxyproject/tools-iuc/blob/master/.github/workflows/pr.yaml
    # The range of commits to check for changes is:
    # - for events on the master branch we compare against the sha before the event
    #   (note that this does not work for feature branch events since we want all
    #   commits on the feature branch and not just the commits of the last event)
    # - for pull requests we compare against the 1st ancestor, given the current
    #   HEAD is the merge between the PR branch and the base branch
    - name: Set commit range (push to the master branch, e.g. merge)
      if: github.ref == 'refs/heads/master' && github.event_name == 'push'
      run: echo "COMMIT_RANGE=${{ github.event.before }}.." >> $GITHUB_ENV
    - name: Set commit range (pull request)
      if: github.event_name == 'pull_request'
      run: |
        git fetch origin master
        echo "COMMIT_RANGE=origin/master..." >> $GITHUB_ENV
    - name: Cache pip packages for Linux
      if: runner.os == 'Linux'
      uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements/**.yml') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Cache pip packages for MacOS
      if: runner.os == 'macOS'
      uses: actions/cache@v4
      with:
        path: ~/Library/Caches/pip
        key: ${{ matrix.os }}-pip-${{ hashFiles('requirements/**.yml') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Cache pip packages for Windows
      if: runner.os == 'Windows'
      uses: actions/cache@v4
      with:
        path: ~\AppData\Local\pip\Cache
        key: ${{ matrix.os }}-pip-${{ hashFiles('requirements/**.yml') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Create env.yml for python 3.11
      shell: bash
      if: ${{ matrix.python-version == '3.11' }}
      run: |
        python -m pip install --upgrade pip;
        pip install conda-merge;
        cd requirements
        if [ "$(uname)" == 'Linux' ]; then
          conda-merge env_common.yml env_test.yml env_ubuntu_3_11.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.cpu.yml jax/env_jax.cpu.yml >  env.yml
        elif [  "$(uname)" == 'Darwin' ]; then
          conda-merge env_common.yml env_test.yml env_mac_3_11.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.mac.cpu.yml jax/env_jax.cpu.yml > env.yml
        elif [[  "$(uname)" == "MINGW64_NT"* ]]; then
          conda-merge env_common.yml env_test.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.cpu.yml > env.yml
        fi;
        cd ..
        cp requirements/env.yml env.yml
    - name: Create env.yml for python 3.8
      shell: bash
      # A special case of environment creation for python 3.8 which excludes jax
      if: ${{ matrix.python-version == '3.8' }}
      run: |
        python -m pip install --upgrade pip;
        pip install conda-merge;
        cd requirements
        if [ "$(uname)" == 'Linux' ]; then
          conda-merge env_common_3_8.yml env_test.yml env_ubuntu.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.cpu.yml env_dqc.yml >  env.yml
        elif [  "$(uname)" == 'Darwin' ]; then
          conda-merge env_common_3_8.yml env_test.yml env_mac.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.mac.cpu.yml > env.yml
        elif [[  "$(uname)" == "MINGW64_NT"* ]]; then
          conda-merge env_common_3_8.yml env_test.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.cpu.yml > env.yml
        fi;
        cd ..
        cp requirements/env.yml env.yml
    - name: Create env.yml for python >= 3.9
      shell: bash
      if: ${{ matrix.python-version != '3.8' && matrix.python-version != '3.11' }}
      run: |
        python -m pip install --upgrade pip;
        pip install conda-merge;
        cd requirements
        if [ "$(uname)" == 'Linux' ]; then
          conda-merge env_common.yml env_test.yml env_ubuntu.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.cpu.yml jax/env_jax.cpu.yml > env.yml
        elif [  "$(uname)" == 'Darwin' ]; then
          conda-merge env_common.yml env_test.yml env_mac.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.mac.cpu.yml jax/env_jax.cpu.yml > env.yml
        elif [[  "$(uname)" == "MINGW64_NT"* ]]; then
          conda-merge env_common.yml env_test.yml tensorflow/env_tensorflow.cpu.yml torch/env_torch.cpu.yml > env.yml
        fi;
        cd ..
        cp requirements/env.yml env.yml
    - name: Install all dependencies
      uses: conda-incubator/setup-miniconda@v3
      with:
        miniconda-version: "latest"
        auto-update-conda: true
        activate-environment: deepchem
        channels: conda-forge,defaults
        python-version: ${{ matrix.python-version }}
        environment-file: env.yml
    - name: Install DeepChem
      id: install
      shell: bash -l {0}
      run: pip install -e .
    - name: Doctest Linux
      if: ${{ (runner.os == 'Linux') && always() }}
      shell: bash -l {0}
      run: DGLBACKEND=pytorch pytest -v --ignore-glob='deepchem/**/test*.py' --ignore-glob='deepchem/models/jax_models/*' --doctest-modules deepchem --doctest-continue-on-failure
    - name: Doctest Windows
      if: ${{ (runner.os == 'Windows') && always() }}
      # Seperate test avoiding Jax in windows since Jax is not supported in Windows
      shell: bash -l {0}
      run: DGLBACKEND=pytorch pytest -v --ignore-glob='deepchem/**/test*.py' --ignore-glob='deepchem/models/jax_models/*' --doctest-modules deepchem --doctest-continue-on-failure
    - name: PyTest
      if: ${{ (success() || failure()) && (steps.install.outcome == 'failure' || steps.install.outcome == 'success') && matrix.python-version == '3.11'}}
      shell: bash -l {0}
      run: pytest -v -m "not jax and not torch and not tensorflow and not dqc" --ignore='deepchem/utils/test/test_sequence_utils.py' deepchem
    - name: PyTest
      if: ${{ (success() || failure()) && (steps.install.outcome == 'failure' || steps.install.outcome == 'success') && matrix.python-version != '3.11'}}
      shell: bash -l {0}
      run: pytest -v -m "not jax and not torch and not tensorflow and not dqc" deepchem


Test for DeepChem Torch

name: Test for DeepChem Torch
on:
  push: # ci work when pushing master branch
    branches:
      - master
  pull_request: # ci work when creating a PR to master branch
    branches:
      - master
jobs:
  torch-build:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest]
        python-version: ['3.8', '3.10', '3.11']
        include:
          - os: windows-latest
            python-version: 3.9
    steps:
    - uses: actions/checkout@v4
    - name: Cache pip modules for Linux
      uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements/torch/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Build DeepChem
      run: |
        python -m pip install --upgrade pip
        pip install -e '.[torch]'
    - name: Import checking
      run: python -c "import deepchem; import torch;"

  torch-tests:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest]
        python-version: ['3.8', '3.10', '3.11']
        include:
          - os: windows-latest
            python-version: '3.9'
    env:
      OS: ${{ matrix.os }}
      PYTHON_VERSION: ${{ matrix.python-version }}
    steps:
    - name: Maximize build space
      if: matrix.os == 'ubuntu-latest'
      run: |
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /opt/ghc
        sudo rm -rf "/usr/local/share/boost"
        sudo rm -rf "$AGENT_TOOLSDIRECTORY"
        sudo rm -rf /usr/local/lib/android
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
    # https://github.com/galaxyproject/tools-iuc/blob/master/.github/workflows/pr.yaml
    # The range of commits to check for changes is:
    # - for events on the master branch we compare against the sha before the event
    #   (note that this does not work for feature branch events since we want all
    #   commits on the feature branch and not just the commits of the last event)
    # - for pull requests we compare against the 1st ancestor, given the current
    #   HEAD is the merge between the PR branch and the base branch
    - name: Set commit range (push to the master branch, e.g. merge)
      if: github.ref == 'refs/heads/master' && github.event_name == 'push'
      run: echo "COMMIT_RANGE=${{ github.event.before }}.." >> $GITHUB_ENV
    - name: Set commit range (pull request)
      if: github.event_name == 'pull_request'
      run: |
        git fetch origin master
        echo "COMMIT_RANGE=origin/master..." >> $GITHUB_ENV
    - name: Cache pip packages for Linux
      if: runner.os == 'Linux'
      uses: actions/cache@v4
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements/torch/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Cache pip packages for MacOS
      if: runner.os == 'macOS'
      uses: actions/cache@v4
      with:
        path: ~/Library/Caches/pip
        key: ${{ matrix.os }}-pip-${{ hashFiles('requirements/torch/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Cache pip packages for Windows
      if: runner.os == 'Windows'
      uses: actions/cache@v4
      with:
        path: ~\AppData\Local\pip\Cache
        key: ${{ matrix.os }}-pip-${{ hashFiles('requirements/torch/**') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Create env.yml for python 3.9+
      shell: bash
      if: ${{ matrix.python-version != '3.8' }}
      run: |
        python -m pip install --upgrade pip;
        pip install conda-merge;
        conda-merge requirements/env_common.yml requirements/torch/env_torch.cpu.yml requirements/env_test.yml > env.yml
    - name: Create env.yml for python 3.8
      shell: bash
      # A special case of environment creation for python 3.8 which includes an older version of matminer
      if: ${{ matrix.python-version == '3.8' }}
      run: |
        python -m pip install --upgrade pip;
        pip install conda-merge;
        conda-merge requirements/env_common_3_8.yml requirements/torch/env_torch.cpu.yml requirements/env_test.yml > env.yml
    - name: Install all dependencies
      uses: conda-incubator/setup-miniconda@v3
      with:
        miniconda-version: "latest"
        auto-update-conda: true
        activate-environment: deepchem
        channels: conda-forge,defaults
        python-version: ${{ matrix.python-version }}
        environment-file: env.yml
    - name: Install DeepChem
      id: install
      shell: bash -l {0}
      run: pip install -e .
    - name: PyTest
      if: ${{ (success() || failure()) && (steps.install.outcome == 'failure' || steps.install.outcome == 'success') }}
      shell: bash -l {0}
      run: pytest -v -m 'torch' deepchem


name: Dispatch trigger for deepchem website re-build
on:
  push: # ci work when pushing to master branch
    branches:
      - master
jobs:
  website-rebuild-trigger-dispatch:
    runs-on: ubuntu-latest
    steps:
      - name: Repository Dispatch
        uses: peter-evans/repository-dispatch@v3
        with:
          token: ${{ secrets.WEBSITE_REPO_PAT }}
          repository: deepchem/deepchem.github.io
          event-type: rebuild-website


Test docs

name: Test docs

# The tests defined in docs/ are currently influenced by changes to _version.py
# and scopes.py.
on:
  pull_request:
    paths:
      - "docs/**"
      - "zmq/**"
      - ".github/workflows/test-docs.yml"
  push:
    paths:
      - "docs/**"
      - "zmq/**"
      - ".github/workflows/test-docs.yml"
    branches-ignore:
      - "dependabot/**"
      - "pre-commit-ci-update-config"
    tags:
      - "**"
  workflow_dispatch:

env:
  LANG: C.UTF-8
  SPHINXOPTS: "-W"

jobs:
  test-docs:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
          cache: pip

      - name: Install libzmq
        run: |
          sudo apt-get -y install libzmq3-dev

      - name: Install pyzmq
        run: |
          pip install -v .

      - name: Install requirements
        run: |
          pip install -r docs/requirements.txt

      # readthedocs doesn't halt on warnings,
      # so raise any warnings here
      - name: build docs
        run: |
          cd docs
          make html

      - name: check links
        run: |
          cd docs
          make linkcheck


Test

name: Test

on:
  push:
    branches-ignore:
      - "dependabot/**"
      - "pre-commit-ci-update-config"
    paths-ignore:
      - "docs/**"
      - "tools/**"
      - ".circleci/**"
      - ".github/workflows/*"
      - "!.github/workflows/test.yml"
  pull_request:
    paths-ignore:
      - "docs/**"
      - "tools/**"
      - ".circleci/**"
      - ".github/workflows/*"
      - "!.github/workflows/test.yml"

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

env:
  FORCE_COLOR: "1"
  # only affects Windows, but easiest to set here for now
  SETUPTOOLS_ENABLE_FEATURES: "legacy-editable"

jobs:
  test:
    runs-on: ${{ matrix.os }}
    timeout-minutes: 20
    continue-on-error: ${{ matrix.zmq == 'head' }}

    env:
      MACOSX_DEPLOYMENT_TARGET: "11.7"

    strategy:
      fail-fast: true
      matrix:
        include:
          - os: macos-13
            python: 3.7

          - os: macos-14
            python: 3.12
            zmq: bundled

          - os: macos-13
            python: pypy-3.9
            zmq: bundled

          - os: ubuntu-20.04
            python: 3.7
            zmq: bundled
            tornado: none

          - os: ubuntu-22.04
            python: pypy-3.9
            zmq: bundled

          - os: ubuntu-22.04
            python: pypy-3.7

          - os: ubuntu-22.04
            python: 3.9
            tornado: head

          - os: ubuntu-22.04
            python: "3.10"

          - os: ubuntu-22.04
            python: "3.11"

          - os: ubuntu-22.04
            python: "3.8"
            zmq: head

          - os: ubuntu-22.04
            python: "3.12"

          - os: windows-2022
            python: "3.7"
            arch: x86

          - os: windows-2022
            python: "3.9"
            arch: x64

          - os: windows-2022
            python: "3.11"
            arch: x64

    steps:
      - uses: actions/checkout@v4

      - name: setup python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python }}
          architecture: ${{ matrix.arch || 'x64' }}
          # allows us to use '3.12' and get '-dev' while we wait
          allow-prereleases: true
          cache: pip

      - name: setup coverage
        if: startsWith(matrix.python, 'pypy') || startsWith(matrix.python, '3.12')
        run: |
          grep -v plugins .coveragerc > .coveragerc-save
          mv .coveragerc-save .coveragerc

      # - name: enable Cython coverage
      #   if: "! (startsWith(matrix.python, 'pypy') || startsWith(matrix.python, '3.12'))"
      #   run: |
      #     echo "PYZMQ_CYTHON_COVERAGE=1" >> "$GITHUB_ENV"

      - name: install dependencies
        run: |
          pip install --upgrade pip wheel
          pip install -r test-requirements.txt

      - name: remove tornado
        if: matrix.tornado == 'none'
        run: |
          pip uninstall -y tornado

      - name: install tornado-head
        if: matrix.tornado == 'head'
        run: |
          pip install https://github.com/tornadoweb/tornado/archive/HEAD.zip

      - name: install pinned tornado
        if: matrix.tornado && matrix.tornado != 'none' && matrix.tornado != 'head'
        run: |
          pip install tornado=="${{ matrix.tornado }}"

      - name: show environment
        run: |
          pip freeze

      - name: install mac dependencies
        if: startsWith(matrix.os, 'mac') && matrix.zmq != 'bundled'
        run: |
          brew install libsodium zeromq

      - name: install linux dependencies
        if: startsWith(matrix.os, 'ubuntu')
        run: |
          sudo apt-get update
          sudo apt-get -y remove libzmq5 || true # workaround https://github.com/actions/virtual-environments/issues/3317
          sudo apt-get -y install libzmq3-dev libsodium-dev

      - name: set $ZMQ_PREFIX
        if: matrix.zmq
        run: |
          echo "ZMQ_PREFIX=${{ matrix.zmq }}" >> "$GITHUB_ENV"

      - name: install libzmq-dev
        if: matrix.zmq == 'head'
        run: |
          wget https://github.com/zeromq/libzmq/archive/HEAD.zip -O libzmq.zip
          unzip libzmq.zip
          pushd libzmq-*
          ./autogen.sh
          ./configure --enable-drafts
          make -j4
          sudo make install
          sudo ldconfig
          popd
          echo "ZMQ_PREFIX=/usr/local" >> "$GITHUB_ENV"
          echo ZMQ_DRAFT_API=1 >> "$GITHUB_ENV"

      - name: build pyzmq
        run: |
          pip install -v -e .

      - name: import zmq
        run: |
          python -c "import zmq"

      - name: run tests
        run: |
          pytest --maxfail 2 --cov zmq -m "not wheel and not new_console" -v

      - name: upload coverage
        run: codecov

      # FIXME: what's the right incantation to call this?
      # the same line from appveyor doesn't work here
      # - name: run extra windows tests
      #   if: startsWith(matrix.os, 'win')
      #   run: |
      #     cmd /c start /wait test pytest -vsx -m new_console --pyargs zmq.tests --junit-xml=./results.xml
      #     python tools/check_junit_result.py ./results.xml


Release

name: Release

on:
  push:
    branches-ignore:
      - "dependabot/**"
      - "pre-commit-ci-update-config"
    tags:
      - "**"
  pull_request:
    paths:
      - pyproject.toml
      - CMakeLists.txt
      - cmake/**
      - buildutils/**
      - .github/workflows/wheels.yml
      - tools/install_libzmq.sh
      - zmq/utils/*.h

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

env:
  PYTHONUNBUFFERED: "1"
  TWINE_NONINTERACTIVE: "1"
#  CIBW_PRERELEASE_PYTHONS: "1"

jobs:
  sdist:
    runs-on: ubuntu-22.04

    steps:
      - uses: actions/checkout@v4

      - name: setup python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
          cache: pip

      - name: install dependencies
        run: |
          pip install --upgrade pip build pytest
          pip install -r tools/wheel-requirements.txt

      - name: build sdist
        run: |
          python -m build --sdist .

      - uses: actions/upload-artifact@v4
        with:
          name: sdist
          path: "dist/*.tar.gz"
          if-no-files-found: error

      - name: verify sdist files
        run:
          pytest -v tools/test_sdist.py

  wheel:
    runs-on: ${{ matrix.os || 'ubuntu-22.04' }}
    name: wheel-${{ matrix.name }}

    env:
      MACOSX_DEPLOYMENT_TARGET: "10.9"
      CIBW_BUILD: "${{ matrix.cibw.build || '*' }}"
      CIBW_SKIP: "${{ matrix.cibw.skip || '' }}"
      CIBW_ARCHS: "${{ matrix.cibw.arch || 'auto' }}"
      CIBW_MANYLINUX_X86_64_IMAGE: "${{ matrix.cibw.manylinux_x86_64_image || '' }}"

    strategy:
      fail-fast: false
      matrix:
        include:
          - os: macos-12
            name: mac-cpython
            cibw:
              build: "cp*"

          - os: macos-12
            name: mac-pypy
            cibw:
              build: "pp*"

          - os: macos-14
            name: mac-arm
            cibw:
              arch: universal2
              build: "cp*"

          - name: manylinux-x86_64
            cibw:
              arch: x86_64
              build: "*manylinux*"

          - name: manylinux-i686
            cibw:
              arch: i686
              build: "*manylinux*"

          # additional manylinux variants, not specified in pyproject.toml:
          # build with newer 2_28 for cpython >= 3.10, pypy 3.9
          - name: manylinux-x86_64-2_28
            cibw:
              arch: x86_64
              build: "cp31*-manylinux* pp39-manylinux*"
              manylinux_x86_64_image: manylinux_2_28

          - name: musllinux
            cibw:
              build: "*musllinux*"

          - name: win32
            os: windows-2019
            architecture: x86
            cibw:
              build: "cp*win32"

          - os: windows-2019
            name: win-pypy
            architecture: x64
            cibw:
              build: "pp*win_amd64"

          - os: windows-2019
            name: win_amd64
            architecture: x64
            cibw:
              build: "cp*win_amd64"

          - os: windows-2022
            name: win_arm64
            architecture: x64
            cibw:
              arch: ARM64
              skip: "cp37*"

    steps:
      - uses: actions/checkout@v4

      - name: setup python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
          architecture: ${{ matrix.architecture }}

      - name: locate windows-arm vcredist
        if: matrix.name == 'win_arm64'
        run: |
          python tools/find_vcredist.py

      - name: customize mac-arm-64
        if: contains(matrix.os, 'macos') && matrix.cibw.arch
        run: |
          echo 'MACOSX_DEPLOYMENT_TARGET=10.15' >> "$GITHUB_ENV"

      - name: install dependencies
        run: |
          pip install --upgrade setuptools pip wheel
          pip install -r tools/wheel-requirements.txt

      - name: show environment
        run: |
          pip freeze

      - name: list target wheels
        run: |
          python -m cibuildwheel . --print-build-identifiers

      - name: build wheels
        run: |
          python -m cibuildwheel .

      - uses: actions/upload-artifact@v4
        with:
          name: wheels-${{ matrix.name }}
          path: "wheelhouse/*"
          if-no-files-found: error

  circle-wheels:
    if: github.repository_owner == 'zeromq'
    runs-on: ubuntu-22.04
    needs:
      # not strictly required, but avoids wasting cpu time waiting
      - wheel
    steps:
      - uses: actions/checkout@v4

      - name: setup python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
          cache: pip

      - name: install dependencies
        run: |
          pip install --upgrade setuptools pip wheel
          pip install requests

      - name: fetch wheels from circleci
        run: python3 tools/circle_wheels.py
        env:
          CIRCLECI_TOKEN: ${{ secrets.CIRCLECI_TOKEN }}
          PR_HEAD_SHA: ${{ github.event.pull_request && github.event.pull_request.head.sha }}

      - uses: actions/upload-artifact@v4
        with:
          name: wheels-linux-arm
          path: "wheelhouse/*"
          if-no-files-found: error

  github-release:
    permissions:
      contents: write
    environment: release
    runs-on: ubuntu-22.04
    if: startsWith(github.ref, 'refs/tags/')
    steps:
      - id: version
        # strip leading `v` from tag, since it's not part of the version
        # see https://github.com/orgs/community/discussions/26625 for substring feature request
        run: |
          echo "${{ github.ref_name }}" | sed s@^v@v=@ >> "${GITHUB_OUTPUT}"

      - uses: ncipollo/release-action@v1
        with:
          # mark as prerelease if it looks like one
          prerelease: ${{ contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc') }}
          # link to release notes, PyPI
          body: |
            See [release notes][], or [pyzmq on PyPI][].

            Install with:

            ```
            pip install 'pyzmq==${{ steps.version.outputs.v }}'
            ```

            [release notes]: https://pyzmq.readthedocs.io/en/latest/changelog.html
            [pyzmq on PyPI]: https://pypi.org/project/pyzmq/${{ steps.version.outputs.v }}/

  list-wheels:
    runs-on: ubuntu-22.04
    needs:
      - sdist
      - wheel
      - circle-wheels
    steps:
      - uses: actions/download-artifact@v4
        with:
          path: dist
          merge-multiple: true
      - name: list wheels
        run: ls -l dist

  upload-pypi:
    permissions:
      id-token: write
    environment: release
    runs-on: ubuntu-22.04
    if: startsWith(github.ref, 'refs/tags/')
    needs:
      - sdist
      - wheel
      - circle-wheels
    steps:
      - uses: actions/download-artifact@v4
        with:
          path: dist
          merge-multiple: true
      - name: Publish wheels to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1


build macos wheel

name: build macos wheel

on: push

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

jobs:
  build_macos10_wheel:
    runs-on: macos-latest
    if: contains(github.event.head_commit.message, 'Bump version to')
    strategy:
      matrix:
        torch: [1.8.0, 1.9.0, 1.10.0, 1.11.0, 1.12.0, 1.13.0, 2.0.0, 2.1.0]
        python-version: [3.7, 3.8, 3.9, '3.10', '3.11']
        include:
          - torch: 1.8.0
            torchvision: 0.9.0
          - torch: 1.9.0
            torchvision: 0.10.0
          - torch: 1.10.0
            torchvision: 0.11.0
          - torch: 1.11.0
            torchvision: 0.12.0
          - torch: 1.12.0
            torchvision: 0.13.0
          - torch: 1.13.0
            torchvision: 0.14.0
          - torch: 2.0.0
            torchvision: 0.15.1
          - torch: 2.1.0
            torchvision: 0.16.0
        exclude:
          - torch: 1.8.0
            python-version: '3.10'
          - torch: 1.9.0
            python-version: '3.10'
          - torch: 1.10.0
            python-version: '3.10'
          - torch: 1.8.0
            python-version: '3.11'
          - torch: 1.9.0
            python-version: '3.11'
          - torch: 1.10.0
            python-version: '3.11'
          - torch: 1.10.0
            python-version: '3.11'
          - torch: 1.11.0
            python-version: '3.11'
          - torch: 1.12.0
            python-version: '3.11'
          - torch: 1.13.0
            python-version: '3.11'
          - torch: 2.0.0
            python-version: 3.7
          - torch: 2.1.0
            python-version: 3.7
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install psutil
        run: pip install psutil
      - name: Install PyTorch
        run: pip install torch==${{matrix.torch}} torchvision==${{matrix.torchvision}} --no-cache-dir
      - name: Build and install
        run: |
          pip install wheel
          python setup.py bdist_wheel
      - uses: actions/upload-artifact@v3
        with:
          name: ${{matrix.torch}}
          path: dist/


lint

name: lint

on: [push, pull_request]

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

jobs:
  lint:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python 3.7
        uses: actions/setup-python@v2
        with:
          python-version: 3.7
      - name: Install pre-commit hook
        run: |
          pip install pre-commit
          pre-commit install
      - name: Linting
        run: pre-commit run --all-files
      - name: Format c/cuda codes with clang-format
        uses: DoozyX/clang-format-lint-action@v0.11
        with:
          source: mmcv/ops/csrc
          extensions: h,c,cpp,hpp,cu,cuh
          style: google


name: merge_stage_test

on:
  push:
    paths-ignore:
      - ".github/**.md"
      - "docker/**"
      - "docs/**"
      - 'examples/**'
      - '.dev_scripts/**'
      - "README.md"
      - "README_zh-CN.md"
      - "CONTRIBUTING.md"
      - ".pre-commit-config.yaml"
      - ".pre-commit-config-zh-cn.yaml"
    branches:
      - main

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

jobs:
  build_without_torch:
    runs-on: ubuntu-22.04
    env:
      MMCV_WITH_OPS: 0
    strategy:
      matrix:
        python-version: [3.7]
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install system dependencies
        run: sudo apt-get update && sudo apt-get install -y ffmpeg libturbojpeg
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests
        run: pytest tests/test_image tests/test_transforms tests/test_video tests/test_arraymisc.py tests/test_visualization.py tests/test_utils/test_env.py --ignore=tests/test_image/test_io.py
  build_without_ops:
    runs-on: ubuntu-22.04
    env:
      MMCV_WITH_OPS: 0
    strategy:
      matrix:
        python-version: [3.7]
        torch: [1.8.1, 1.9.1]
        include:
          - torch: 1.8.1
            torchvision: 0.9.1
          - torch: 1.9.1
            torchvision: 0.10.1
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install system dependencies
        run: sudo apt-get update && sudo apt-get install -y ffmpeg libturbojpeg
      - name: Install PyTorch
        run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/torch_stable.html
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests
        run: pytest tests --ignore=tests/test_ops
  build_cpu_py:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        python-version: [3.8, 3.9, '3.10']
        torch: [1.13.0]
        include:
          - torch: 1.13.0
            torchvision: 0.14.0
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install system dependencies
        run: sudo apt-get update && sudo apt-get install -y ffmpeg libturbojpeg
      - name: Upgrade pip and wheel
        run: pip install pip wheel --upgrade
      - name: Install PyTorch
        run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/torch_stable.html
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests and generate coverage report
        run: |
          coverage run --branch --source mmcv -m pytest tests/
          coverage xml
          coverage report -m
  build_cpu_pt:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        python-version: [3.7]
        torch: [1.8.1, 1.9.1, 1.10.1, 1.11.0, 1.12.0, 1.13.0, 2.0.0, 2.1.0]
        include:
          - torch: 1.8.1
            torchvision: 0.9.1
          - torch: 1.9.1
            torchvision: 0.10.1
          - torch: 1.10.1
            torchvision: 0.11.2
          - torch: 1.11.0
            torchvision: 0.12.0
          - torch: 1.12.0
            torchvision: 0.13.0
          - torch: 1.13.0
            torchvision: 0.14.0
          - torch: 2.0.0
            torchvision: 0.15.1
            python-version: 3.8
          - torch: 2.1.0
            torchvision: 0.16.0
            python-version: 3.8
        exclude:
          - torch: 2.0.0
            python-version: 3.7
          - torch: 2.1.0
            python-version: 3.7
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install system dependencies
        run: sudo apt-get update && sudo apt-get install -y ffmpeg libturbojpeg
      - name: Upgrade pip and wheel
        run: pip install pip wheel --upgrade
      - name: Install PyTorch
        run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/torch_stable.html
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests and generate coverage report
        run: |
          coverage run --branch --source mmcv -m pytest tests/
          coverage xml
          coverage report -m
      # Only upload coverage report for python3.7 && pytorch1.8.1 cpu
      - name: Upload coverage to Codecov
        if: ${{matrix.torch == '1.8.1' && matrix.python-version == '3.8'}}
        uses: codecov/codecov-action@v1.0.14
        with:
          file: ./coverage.xml
          flags: unittests
          env_vars: OS,PYTHON
          name: codecov-umbrella
          fail_ci_if_error: false
  build_cu102:
    runs-on: ubuntu-22.04
    container:
      image: pytorch/pytorch:1.8.1-cuda10.2-cudnn7-devel
    env:
      FORCE_CUDA: 1
      MMCV_CUDA_ARGS: -gencode=arch=compute_61,code=sm_61
    strategy:
      matrix:
        python-version: [3.7]
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip and wheel
        run: pip install pip wheel --upgrade
      - name: Fetch GPG keys
        run: |
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub
      - name: Install system dependencies
        run: apt-get update && apt-get install -y git ffmpeg libturbojpeg
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests and generate coverage report
        run: |
          coverage run --branch --source mmcv -m pytest tests/
          coverage xml
          coverage report -m
  build_cu111:
    runs-on: ubuntu-22.04
    container:
      image: pytorch/pytorch:1.8.1-cuda11.1-cudnn8-devel
    env:
      FORCE_CUDA: 1
      MMCV_CUDA_ARGS: -gencode=arch=compute_61,code=sm_61
    strategy:
      matrix:
        python-version: [3.7]
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip and wheel
        run: pip install pip wheel --upgrade
      - name: Fetch GPG keys
        run: |
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub
      - name: Install system dependencies
        run: apt-get update && apt-get install -y git ffmpeg libturbojpeg
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests and generate coverage report
        run: |
          coverage run --branch --source mmcv -m pytest tests/
          coverage xml
          coverage report -m
  build_cu116:
    runs-on: ubuntu-22.04
    container:
      image: pytorch/pytorch:1.13.0-cuda11.6-cudnn8-devel
    env:
      FORCE_CUDA: 1
      MMCV_CUDA_ARGS: -gencode=arch=compute_61,code=sm_61
    strategy:
      matrix:
        python-version: [3.7]
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip and wheel
        run: pip install pip wheel --upgrade
      - name: Fetch GPG keys
        run: |
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub
      - name: Install system dependencies
        run: apt-get update && apt-get install -y git ffmpeg libturbojpeg
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests and generate coverage report
        run: |
          coverage run --branch --source mmcv -m pytest tests
          coverage xml
          coverage report -m
  build_windows_without_ops:
    runs-on: windows-2019
    env:
      MMCV_WITH_OPS: 0
    strategy:
      matrix:
        python-version: [3.7]
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip and wheel
        run: python -m pip install pip wheel --upgrade
      - name: Install PyTorch
        run: pip install torch==1.8.1+cpu torchvision==0.9.1+cpu -f https://download.pytorch.org/whl/torch_stable.html
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests
        run: pytest tests --ignore=tests/test_ops --ignore tests/test_image/test_io.py
  build_windows:
    runs-on: windows-2019
    strategy:
      matrix:
        torch: [1.8.1, 2.1.0]
        include:
          - torch: 1.8.1
            torchvision: 0.9.1
            python-version: 3.7
          - torch: 2.1.0
            torchvision: 0.16.0
            python-version: 3.8
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip and wheel
        run: python -m pip install pip wheel --upgrade
      - name: Install PyTorch
        run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/torch_stable.html
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests
        run: pytest tests/ --ignore tests/test_image/test_io.py
  build_macos:
    runs-on: macos-latest
    strategy:
      matrix:
        torch: [1.8.1, 2.1.0]
        include:
          - torch: 1.8.1
            torchvision: 0.9.1
            python-version: 3.7
          - torch: 2.1.0
            torchvision: 0.16.0
            python-version: 3.8
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install system dependencies
        run: brew install ffmpeg jpeg-turbo
      - name: Upgrade pip and wheel
        run: pip install pip wheel --upgrade
      - name: Install PyTorch
        run: pip install torch==${{ matrix.torch }} torchvision==${{ matrix.torchvision }}
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests
        run: pytest tests/


name: pr_stage_test

on:
  pull_request:
    paths-ignore:
      - ".github/**.md"
      - "docker/**"
      - "docs/**"
      - 'examples/**'
      - '.dev_scripts/**'
      - "README.md"
      - "README_zh-CN.md"
      - "CONTRIBUTING.md"
      - ".pre-commit-config.yaml"
      - ".pre-commit-config-zh-cn.yaml"

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

jobs:
  build_cu102:
    runs-on: ubuntu-22.04
    container:
      image: pytorch/pytorch:1.8.1-cuda10.2-cudnn7-devel
    env:
      FORCE_CUDA: 1
      MMCV_CUDA_ARGS: -gencode=arch=compute_61,code=sm_61
    strategy:
      matrix:
        python-version: [3.7]
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip and wheel
        run: pip install pip wheel --upgrade
      - name: Fetch GPG keys
        run: |
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub
      - name: Install system dependencies
        run: apt-get update && apt-get install -y git ffmpeg libturbojpeg
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests and generate coverage report
        run: |
          coverage run --branch --source mmcv -m pytest tests/
          coverage xml
          coverage report -m
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v1.0.14
        with:
          file: ./coverage.xml
          flags: unittests
          env_vars: OS,PYTHON
          name: codecov-umbrella
          fail_ci_if_error: false
  build_cu111:
    runs-on: ubuntu-22.04
    container:
      image: pytorch/pytorch:1.8.1-cuda11.1-cudnn8-devel
    env:
      FORCE_CUDA: 1
      MMCV_CUDA_ARGS: -gencode=arch=compute_61,code=sm_61
    strategy:
      matrix:
        python-version: [3.7]
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip and wheel
        run: pip install pip wheel --upgrade
      - name: Fetch GPG keys
        run: |
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub
      - name: Install system dependencies
        run: apt-get update && apt-get install -y git ffmpeg libturbojpeg
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests and generate coverage report
        run: |
          coverage run --branch --source mmcv -m pytest tests/
          coverage xml
          coverage report -m
  build_windows_without_ops:
    runs-on: windows-2019
    env:
      MMCV_WITH_OPS: 0
    strategy:
      matrix:
        python-version: [3.7]
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip and wheel
        run: python -m pip install pip wheel --upgrade
      - name: Install PyTorch
        run: pip install torch==1.8.1+cpu torchvision==0.9.1+cpu -f https://download.pytorch.org/whl/torch_stable.html
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests
        run: pytest tests --ignore=tests/test_ops --ignore tests/test_image/test_io.py
  build_windows:
    runs-on: windows-2019
    strategy:
      matrix:
        torch: [1.8.1, 2.1.0]
        include:
          - torch: 1.8.1
            torchvision: 0.9.1
            python-version: 3.7
          - torch: 2.1.0
            torchvision: 0.16.0
            python-version: 3.8
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip and wheel
        run: python -m pip install pip wheel --upgrade
      - name: Install PyTorch
        run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/torch_stable.html
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests
        run: pytest tests/ --ignore tests/test_image/test_io.py
  build_macos:
    runs-on: macos-latest
    strategy:
      matrix:
        torch: [1.8.1, 2.1.0]
        include:
          - torch: 1.8.1
            torchvision: 0.9.1
            python-version: 3.7
          - torch: 2.1.0
            torchvision: 0.16.0
            python-version: 3.8
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install system dependencies
        run: brew install ffmpeg jpeg-turbo
      - name: Upgrade pip and wheel
        run: pip install pip wheel --upgrade
      - name: Install PyTorch
        run: pip install torch==${{ matrix.torch }} torchvision==${{ matrix.torchvision }}
      - name: Install MMEngine from main branch
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install ninja to speed the compilation
        run: pip install ninja psutil
      - name: Build MMCV from source
        run: pip install -e . -v
      - name: Install unit tests dependencies
        run: pip install -r requirements/test.txt
      - name: Run unit tests
        run: pytest tests/


deploy

name: deploy

on: push

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

jobs:
  build-n-publish_without_ops:
    runs-on: ubuntu-22.04
    if: startsWith(github.event.ref, 'refs/tags')
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python 3.7
        uses: actions/setup-python@v1
        with:
          python-version: 3.7
      - name: Upgrade Setuptools
        run: pip install setuptools wheel --upgrade
      - name: Build MMCV
        run: |
          sed -i "s/os.getenv('MMCV_WITH_OPS', '1')/os.getenv('MMCV_WITH_OPS', '0')/g" setup.py
          python setup.py sdist bdist_wheel
      - name: Publish distribution to PyPI
        run: |
          pip install twine
          twine upload dist/* -u __token__ -p ${{ secrets.pypi_password }}

  build-n-publish_with_ops:
    runs-on: ubuntu-22.04
    if: startsWith(github.event.ref, 'refs/tags')
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python 3.7
        uses: actions/setup-python@v1
        with:
          python-version: 3.7
      - name: Upgrade Setuptools
        run: pip install setuptools --upgrade
      - name: Build MMCV with ops
        run: python setup.py sdist
      - name: Publish distribution to PyPI
        run: |
          pip install twine
          twine upload dist/* -u __token__ -p ${{ secrets.pypi_password }}


Deploy docs to GitHub Pages

# Build and deploy a Jekyll site to GitHub Pages
name: Deploy docs to GitHub Pages

on:
  # Runs on pushes targeting the default branch
  push:
    branches: ["master"]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow only one concurrent deployment
concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  # Build job
  build:
    if: github.repository == 'seleniumbase/SeleniumBase'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup Pages
        uses: actions/configure-pages@v4
      - name: Build with Jekyll
        uses: actions/jekyll-build-pages@v1
        with:
          source: ./
          destination: ./_site
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3

  # Deployment job
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    if: github.repository == 'seleniumbase/SeleniumBase'
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4


Nightly Tests (macOS)

name: Nightly Tests (macOS)

on:
  schedule:
    - cron: "40 1 * * *"
  workflow_dispatch:
    branches:

jobs:
  build:

    env:
      PY_COLORS: "1"
    runs-on: macos-latest
    strategy:
      fail-fast: false
      max-parallel: 5
      matrix:
        python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        python -m pip install --upgrade wheel
        pip install -r requirements.txt
    - name: Install SeleniumBase
      run: |
        python setup.py install
    - name: Check the console scripts interface
      run: |
        seleniumbase
        sbase
    - name: Install chromedriver
      run: |
        seleniumbase install chromedriver
    - name: Make sure pytest is working
      run: |
        echo "def test_1(): pass" > nothing.py
        pytest nothing.py
    - name: Make sure nosetests is working
      run: |
        echo "def test_2(): pass" > nothing2.py
        nosetests nothing2.py
    - name: Run pytest examples/unit_tests/verify_framework.py --browser=chrome --headless
      run: |
        pytest examples/unit_tests/verify_framework.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/offline_examples --browser=chrome --headless --rs
      run: |
        pytest examples/offline_examples --rs --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/boilerplate_test.py --browser=chrome --headless
      run: |
        pytest examples/boilerplates/boilerplate_test.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/test_window_switching.py --browser=chrome --headless
      run: |
        pytest examples/test_window_switching.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Verify seleniumbase install from PyPI
      run: |
        pip install seleniumbase -U --no-deps --force-reinstall --no-cache-dir


Nightly Tests (Ubuntu)

name: Nightly Tests (Ubuntu)

on:
  schedule:
    - cron: "30 1 * * *"
  workflow_dispatch:
    branches:

jobs:
  build:

    env:
      PY_COLORS: "1"
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      max-parallel: 6
      matrix:
        python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        python -m pip install --upgrade wheel
        pip install -r requirements.txt
    - name: Install SeleniumBase
      run: |
        python setup.py install
    - name: Check the console scripts interface
      run: |
        seleniumbase
        sbase
    - name: Install chromedriver
      run: |
        seleniumbase install chromedriver
    - name: Make sure pytest is working
      run: |
        echo "def test_1(): pass" > nothing.py
        pytest nothing.py
    - name: Make sure nosetests is working
      run: |
        echo "def test_2(): pass" > nothing2.py
        nosetests nothing2.py
    - name: Run pytest examples/unit_tests/verify_framework.py --browser=chrome --headless
      run: |
        pytest examples/unit_tests/verify_framework.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/offline_examples --browser=chrome --headless --rs
      run: |
        pytest examples/offline_examples --rs --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/boilerplate_test.py --browser=chrome --headless
      run: |
        pytest examples/boilerplates/boilerplate_test.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/test_window_switching.py --browser=chrome --headless
      run: |
        pytest examples/test_window_switching.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Verify seleniumbase install from PyPI
      run: |
        pip install seleniumbase -U --no-deps --force-reinstall --no-cache-dir


Nightly Tests (Windows)

name: Nightly Tests (Windows)

on:
  schedule:
    - cron: "50 1 * * *"
  workflow_dispatch:
    branches:

jobs:
  build:

    env:
      PY_COLORS: "1"
    runs-on: windows-latest
    strategy:
      fail-fast: false
      max-parallel: 6
      matrix:
        python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        python -m pip install --upgrade wheel
        pip install -r requirements.txt
    - name: Install SeleniumBase
      run: |
        python setup.py install
    - name: Check the console scripts interface
      run: |
        seleniumbase
        sbase
    - name: Install chromedriver
      run: |
        seleniumbase install chromedriver
    - name: Make sure pytest is working
      run: |
        echo "def test_1(): pass" > nothing.py
        pytest nothing.py
    - name: Make sure nosetests is working
      run: |
        echo "def test_2(): pass" > nothing2.py
        nosetests nothing2.py
    - name: Run pytest examples/unit_tests/verify_framework.py --browser=chrome --headless
      run: |
        pytest examples/unit_tests/verify_framework.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/offline_examples --browser=chrome --headless --rs
      run: |
        pytest examples/offline_examples --rs --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/boilerplate_test.py --browser=chrome --headless
      run: |
        pytest examples/boilerplates/boilerplate_test.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/test_window_switching.py --browser=chrome --headless
      run: |
        pytest examples/test_window_switching.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Verify seleniumbase install from PyPI
      run: |
        pip install seleniumbase -U --no-deps --force-reinstall --no-cache-dir


CI build

name: CI build

on:
  pull_request:
    branches:
  push:
    branches:
      - master
  workflow_dispatch:
    branches:

jobs:
  build:

    env:
      PY_COLORS: "1"
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      max-parallel: 6
      matrix:
        python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip wheel setuptools
        pip install -r requirements.txt
    - name: Install SeleniumBase
      run: |
        python setup.py install
    - name: Lint with flake8
      run: |
        pip install flake8
        # Stop the build if there are flake8 issues
        flake8 . --count --show-source --statistics --exclude=temp
    - name: Install Chrome
      run: |
        sudo apt install google-chrome-stable
    - name: Check the console scripts interface
      run: |
        seleniumbase
        sbase
    - name: Install chromedriver
      run: |
        seleniumbase install chromedriver
    - name: Make sure pytest is working
      run: |
        echo "def test_1(): pass" > nothing.py
        pytest nothing.py
    - name: Make sure nosetests is working
      run: |
        echo "def test_2(): pass" > nothing2.py
        nosetests nothing2.py
    - name: Run pytest examples/unit_tests/verify_framework.py --browser=chrome --headless
      run: |
        pytest examples/unit_tests/verify_framework.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/boilerplate_test.py --browser=chrome --headless
      run: |
        pytest examples/boilerplates/boilerplate_test.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/test_demo_site.py --browser=chrome --xvfb
      run: |
        pytest examples/test_demo_site.py --browser=chrome --xvfb -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/iframe_tests.py --browser=chrome --xvfb --rs --crumbs
      run: |
        pytest examples/iframe_tests.py --browser=chrome --xvfb --rs --crumbs -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/test_mfa_login.py --browser=chrome --xvfb
      run: |
        pytest examples/test_mfa_login.py --browser=chrome --xvfb -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/iframe_tests.py --browser=chrome --xvfb --rs
      run: |
        pytest examples/iframe_tests.py --browser=chrome --xvfb --rs -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/test_window_switching.py --browser=chrome --headless
      run: |
        pytest examples/test_window_switching.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/my_first_test.py --browser=chrome --headless
      run: |
        pytest examples/my_first_test.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run pytest examples/test_inspect_html.py --browser=chrome --headless
      run: |
        pytest examples/test_inspect_html.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
    - name: Run behave examples/behave_bdd/features/calculator.feature -D rs -D crumbs -D xvfb
      run: |
        behave examples/behave_bdd/features/calculator.feature -D rs -D crumbs -D xvfb -T -k
    - name: Run behave examples/behave_bdd/features/realworld.feature -D rs -D crumbs -D xvfb
      run: |
        behave examples/behave_bdd/features/realworld.feature -D rs -D crumbs -D xvfb -T -k


GitHub Event Processor

name: GitHub Event Processor

on:
  issues:
    types: [edited, labeled, opened, reopened, unlabeled]
  # issue_comment is used for both issues and pull_requests
  # github.event.issue.pull_request will be non-null on pull request comments
  issue_comment:
    types: [created]
  # synchronize is the pull_request_target event when changes are pushed
  # pull request merged is the closed event with github.event.pull_request.merged = true
  pull_request_target:
    types: [closed, labeled, opened, reopened, review_requested, synchronize, unlabeled]

# This removes all unnecessary permissions, the ones needed will be set below.
# https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
permissions: {}

jobs:
  # This event requires the Azure CLI to get the LABEL_SERVICE_API_KEY from the vault.
  # Because the azure/login step adds time costly pre/post Az CLI commands to any every job
  # it's used in, split this into its own job so only the event that needs the Az CLI pays
  # the cost.
  event-handler-with-azure:
    permissions:
      issues: write
      pull-requests: write
      # For OIDC auth
      id-token: write
      contents: read
    name: Handle ${{ github.event_name }} ${{ github.event.action }} event with azure login
    runs-on: ubuntu-latest
    if: ${{ github.event_name == 'issues' && github.event.action == 'opened' }}
    steps:
      - name: 'Az CLI login'
        uses: azure/login@v2
        with:
            client-id: ${{ secrets.AZURE_CLIENT_ID }}
            tenant-id: ${{ secrets.AZURE_TENANT_ID }}
            subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

      - name: 'Run Azure CLI commands'
        run: |
          LABEL_SERVICE_API_KEY=$(az keyvault secret show \
            --vault-name issue-labeler \
            -n issue-labeler-func-key \
            -o tsv \
            --query value)

          echo "::add-mask::$LABEL_SERVICE_API_KEY"
          echo "LABEL_SERVICE_API_KEY=$LABEL_SERVICE_API_KEY" >> $GITHUB_ENV

      # To run github-event-processor built from source, for testing purposes, uncomment everything
      # in between the Start/End-Build From Source comments and comment everything in between the
      # Start/End-Install comments
      # Start-Install
      - name: Install GitHub Event Processor
        run: >
          dotnet tool install
          Azure.Sdk.Tools.GitHubEventProcessor
          --version 1.0.0-dev.20240610.2
          --add-source https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-net/nuget/v3/index.json
          --global
        shell: bash
      # End-Install

      # Testing checkout of sources from the Azure/azure-sdk-tools repository
      # The ref: is the SHA from the pull request in that repository or the
      # refs/pull/<PRNumber>/merge for the latest on any given PR. If the repository
      # is a fork eg. <User>/azure-sdk-tools then the repository down below will
      # need to point to that fork
      # Start-Build
      # - name: Checkout tools repo for GitHub Event Processor sources
      #   uses: actions/checkout@v3
      #   with:
      #     repository: Azure/azure-sdk-tools
      #     path: azure-sdk-tools
      #     ref: <refs/pull/<PRNumber>/merge> or <sha>

      # - name: Build and install GitHubEventProcessor from sources
      #   run: |
      #     dotnet pack
      #     dotnet tool install --global --prerelease --add-source ../../../artifacts/packages/Debug Azure.Sdk.Tools.GitHubEventProcessor
      #   shell: bash
      #   working-directory: azure-sdk-tools/tools/github-event-processor/Azure.Sdk.Tools.GitHubEventProcessor
      # End-Build

      - name: Process Action Event
        run: |
          cat > payload.json << 'EOF'
          ${{ toJson(github.event) }}
          EOF
          github-event-processor ${{ github.event_name }} payload.json
        shell: bash
        env:
          # This is a temporary secret generated by github
          # https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          LABEL_SERVICE_API_KEY: ${{ env.LABEL_SERVICE_API_KEY }}

  event-handler:
    permissions:
      issues: write
      pull-requests: write
    name: Handle ${{ github.event_name }} ${{ github.event.action }} event
    runs-on: ubuntu-latest
    if: ${{ github.event_name != 'issues' || github.event.action != 'opened' }}
    steps:
      # To run github-event-processor built from source, for testing purposes, uncomment everything
      # in between the Start/End-Build From Source comments and comment everything in between the
      # Start/End-Install comments
      # Start-Install
      - name: Install GitHub Event Processor
        run: >
          dotnet tool install
          Azure.Sdk.Tools.GitHubEventProcessor
          --version 1.0.0-dev.20240610.2
          --add-source https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-net/nuget/v3/index.json
          --global
        shell: bash
      # End-Install

      # Testing checkout of sources from the Azure/azure-sdk-tools repository
      # The ref: is the SHA from the pull request in that repository or the
      # refs/pull/<PRNumber>/merge for the latest on any given PR. If the repository
      # is a fork eg. <User>/azure-sdk-tools then the repository down below will
      # need to point to that fork
      # Start-Build
      # - name: Checkout tools repo for GitHub Event Processor sources
      #   uses: actions/checkout@v3
      #   with:
      #     repository: Azure/azure-sdk-tools
      #     path: azure-sdk-tools
      #     ref: <refs/pull/<PRNumber>/merge> or <sha>

      # - name: Build and install GitHubEventProcessor from sources
      #   run: |
      #     dotnet pack
      #     dotnet tool install --global --prerelease --add-source ../../../artifacts/packages/Debug Azure.Sdk.Tools.GitHubEventProcessor
      #   shell: bash
      #   working-directory: azure-sdk-tools/tools/github-event-processor/Azure.Sdk.Tools.GitHubEventProcessor
      # End-Build

      - name: Process Action Event
        run: |
          cat > payload.json << 'EOF'
          ${{ toJson(github.event) }}
          EOF
          github-event-processor ${{ github.event_name }} payload.json
        shell: bash
        env:
          # This is a temporary secret generated by github
          # https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


Check Enforcer

# NOTE: currently azure-sdk-actions only hosts check enforcer code.
# If further functionality is added, this name should be updated to reflect
# the more generic behavior
name: Check Enforcer

on:
  check_suite:
    types: [completed]
  issue_comment:
    types: [created]

permissions: {}

jobs:
  event-handler:
    permissions:
      statuses: write # to set status (azure/azure-sdk-actions)
      pull-requests: write # to read pull requests and write comments (azure/azure-sdk-actions)
      checks: read # to read check status (azure/azure-sdk-actions)
    name: Handle ${{ github.event_name }} ${{ github.event.action }} event
    runs-on: ubuntu-latest
    steps:
      - uses: azure/azure-sdk-actions@main
        with:
          token: ${{ secrets.GITHUB_TOKEN }}


Javascript SDK Release Tool Pull Request Check


Remove needs-triage and needs-team-triage labels if it is assigned