name: tests on: workflow_dispatch: push: branches: - master pull_request: branches: - master paths: - "shap/**" - "tests/**" - "data/**" - "javascript/**" # Include JS changes that affect bundle.js - ".github/workflows/run_tests.yml" - "pyproject.toml" - "CMakeLists.txt" concurrency: group: ${{ github.workflow }}-${{ github.ref }} # Cancel only PR intermediate builds cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} jobs: # we need this test since we run into 403 errors on MacOS, see GH #4179 prepare_data: runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@v4 - name: Set up Python 3.12 uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install uv uses: astral-sh/setup-uv@v7 - name: Install dependencies for dataset download run: | uv pip install --system . --group download-datasets - name: Pre-download datasets run: python -P tests/datasets_to_cache.py - name: Create unified cache directory run: | mkdir -p /tmp/test_data_cache cp -r ~/scikit_learn_data /tmp/test_data_cache/ || true cp -r shap/cached_data /tmp/test_data_cache/ || true ls -la /tmp/test_data_cache/ - name: Upload cached datasets uses: actions/upload-artifact@v4 with: name: test-data-cache path: /tmp/test_data_cache retention-days: 1 run_tests: needs: prepare_data strategy: matrix: os: ["ubuntu-latest"] # The total number of matrix jobs should match codecov.yml `after_n_builds`. python-version: ["3.12", "3.13", "3.14" ] extras: ["test"] include: # Test on windows/mac, just one job each - os: windows-latest python-version: "3.13" extras: "test" - os: macos-latest python-version: "3.13" extras: "test" # Run tests with only the core dependencies, to ensure we # cover the latest version of numpy/pandas. See GH dsgibbons#46 - os: ubuntu-latest python-version: "3.13" extras: "test-core" fail-fast: false runs-on: ${{ matrix.os }} timeout-minutes: 40 steps: - uses: actions/checkout@v4 - uses: dorny/paths-filter@v3 id: filter with: filters: | js: - 'javascript/**' - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} # Build JavaScript bundle if JS files have changed - name: Set up Node.js if: steps.filter.outputs.js == 'true' uses: actions/setup-node@v3 with: node-version: lts/Hydrogen - name: Build JavaScript bundle conditionally if: steps.filter.outputs.js == 'true' shell: bash run: | cd javascript npm ci npm run build cp build/bundle.js ../shap/plots/resources/bundle.js - name: Install libomp (macOS) if: runner.os == 'macOS' run: | brew install libomp # Set DYLD_LIBRARY_PATH to avoid OpenMP conflicts, see https://github.com/unit8co/darts/pull/3050 _libomp_path=$(brew --prefix libomp 2>/dev/null)/lib echo "DYLD_LIBRARY_PATH=$_libomp_path:$DYLD_LIBRARY_PATH" >> $GITHUB_ENV unset _libomp_path - name: Install uv uses: astral-sh/setup-uv@v7 - name: Install dependencies # Do regular install NOT editable install: see GH #3020 run: | uv pip install --system . --group ${{matrix.extras}} --group plots - name: Download pre-cached datasets uses: actions/download-artifact@v4 with: name: test-data-cache path: /tmp/test_data_cache - name: Restore datasets to correct locations shell: bash run: | # Restore sklearn data if [ "$RUNNER_OS" == "Windows" ]; then cp -r /d/tmp/test_data_cache/scikit_learn_data ~/scikit_learn_data || true else cp -r /tmp/test_data_cache/scikit_learn_data ~/scikit_learn_data || true fi # Restore shap cached data to the installed package location SHAP_CACHE_DIR=$(python -P -c "import shap, os; print(os.path.join(os.path.dirname(shap.__file__), 'cached_data'))") mkdir -p "$SHAP_CACHE_DIR" if [ "$RUNNER_OS" == "Windows" ]; then cp -r /d/tmp/test_data_cache/cached_data/* "$SHAP_CACHE_DIR/" 2>/dev/null || true else cp -r /tmp/test_data_cache/cached_data/* "$SHAP_CACHE_DIR/" 2>/dev/null || true fi echo "Sklearn data:" ls -la ~/scikit_learn_data/ 2>/dev/null || echo "No sklearn data" echo "Shap cache data:" ls -la "$SHAP_CACHE_DIR" 2>/dev/null || echo "No shap data" - name: Test with pytest # Ensure we avoid adding current working directory to sys.path: # - Use "pytest" over "python -m pytest" # - Use "append" import mode rather than default "prepend" run: > pytest --durations=20 --cov --cov-report=xml --mpl-generate-summary=html --mpl-results-path=./mpl-results --import-mode=append - name: Upload mpl test report if: failure() uses: actions/upload-artifact@v4 with: name: mpl-results-${{ matrix.python-version }}-${{ runner.os }}-${{ matrix.extras }} path: mpl-results/ if-no-files-found: ignore - name: Upload coverage to Codecov uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} test_oldest_supported_numpy: # Package is built with numpy 2.X # This job is recommended by https://numpy.org/doc/stable/dev/depending_on_numpy.html#numpy-2-0-specific-advice # The "oldest supported numpy" is determined by SPEC 0: # https://scientific-python.org/specs/spec-0000/ name: run tests (oldest supported numpy) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python 3.12 uses: actions/setup-python@v5 with: python-version: 3.12 - name: Install uv uses: astral-sh/setup-uv@v7 - name: Install dependencies run: | uv pip install --system numpy==2.0 . --group test-core --group plots - name: Test with pytest run: pytest --durations=20 --import-mode=append run_mypy: # Run mypy on the latest Python version name: run mypy runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python 3.13 uses: actions/setup-python@v5 with: python-version: 3.13 - name: Install uv uses: astral-sh/setup-uv@v7 - name: Install dependencies run: | uv pip install --system . --group test-core - name: Run mypy run: mypy shap tests