.github/workflows/test.yml
# GENERATED FILE, do not edit
# This file was generated with Typeline
# generated from: workflows/test.ts
name: Automatic Tests
'on':
push:
branches:
- main
paths:
- lenskit*/**.py
- '**pyproject.toml'
- requirements*.txt
- data/**
- utils/measure-coverage.tcl
- .github/workflows/test.yml
pull_request:
paths:
- lenskit*/**.py
- '**pyproject.toml'
- requirements*.txt
- data/**
- utils/measure-coverage.tcl
- .github/workflows/test.yml
concurrency:
group: 'test-${{github.ref}}'
cancel-in-progress: true
jobs:
conda:
name: 'Conda Python ${{matrix.python}} on ${{matrix.platform}}'
runs-on: '${{matrix.platform}}'
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
python:
- py311
- py312
platform:
- ubuntu-latest
- macos-latest
- windows-latest
steps:
- name: "🛒 Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: prefix-dev/setup-pixi@v0.8.1
with:
pixi-version: latest
activate-environment: true
environments: 'test-${{matrix.python}}-core'
cache-write: false
- name: "🔍 Inspect environment"
run: |
python -m lenskit.util.envcheck
- name: "🏃🏻➡️ Test LKPY"
run: |
python -m pytest --verbose --log-file=test.log --durations=25 --cov=lenskit/lenskit lenskit/tests
- name: "📐 Coverage results"
run: |
coverage xml
coverage report
cp .coverage coverage.db
- name: "📤 Upload test results"
uses: actions/upload-artifact@v4
if: always()
with:
name: 'test-conda-${{matrix.platform}}-py${{matrix.python}}'
path: |
test*.log
coverage.db
coverage.xml
vanilla:
name: 'Vanilla Python ${{matrix.python}} on ${{matrix.platform}}'
runs-on: '${{matrix.platform}}'
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
python:
- '3.11'
- '3.12'
platform:
- ubuntu-latest
- macos-latest
steps:
- name: "🛒 Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: "🐍 Set up Python"
id: install-python
uses: actions/setup-python@v5
with:
python-version: '${{matrix.python}}'
- name: "🕶️ Set up uv"
run: |
pip install -U 'uv>=0.1.15'
- name: "📦 Set up Python dependencies"
id: install-deps
run: |
uv pip install --python $PYTHON -e "lenskit[test]"
shell: bash
env:
PYTHON: '${{steps.install-python.outputs.python-path}}'
UV_EXTRA_INDEX_URL: 'https://download.pytorch.org/whl/cpu'
UV_INDEX_STRATEGY: unsafe-first-match
- name: "🔍 Inspect environment"
run: |
python -m lenskit.util.envcheck
- name: "🏃🏻➡️ Test LKPY"
run: |
python -m pytest --verbose --log-file=test.log --durations=25 --cov=lenskit/lenskit lenskit/tests
- name: "📐 Coverage results"
run: |
coverage xml
coverage report
cp .coverage coverage.db
- name: "📤 Upload test results"
uses: actions/upload-artifact@v4
if: always()
with:
name: 'test-vanilla-${{matrix.platform}}-py${{matrix.python}}'
path: |
test*.log
coverage.db
coverage.xml
nojit:
name: Non-JIT test coverage
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: "🛒 Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: "🐍 Set up Python"
id: install-python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: "🕶️ Set up uv"
run: |
pip install -U 'uv>=0.1.15'
- name: "📦 Set up Python dependencies"
id: install-deps
run: |
uv pip install --python $PYTHON -e "lenskit[test]" -e "lenskit-funksvd"
shell: bash
env:
PYTHON: '${{steps.install-python.outputs.python-path}}'
UV_EXTRA_INDEX_URL: 'https://download.pytorch.org/whl/cpu'
UV_INDEX_STRATEGY: unsafe-first-match
- name: "🔍 Inspect environment"
run: |
python -m lenskit.util.envcheck
- name: "🏃🏻➡️ Test LKPY"
run: |
python -m pytest --verbose --log-file=test.log --durations=25 -m 'not slow' --cov=lenskit/lenskit --cov=lenskit-funksvd/lenskit lenskit/tests lenskit-funksvd/tests
env:
NUMBA_DISABLE_JIT: 1
PYTORCH_JIT: 0
- name: "📐 Coverage results"
run: |
coverage xml
coverage report
cp .coverage coverage.db
- name: "📤 Upload test results"
uses: actions/upload-artifact@v4
if: always()
with:
name: test-nojit
path: |
test*.log
coverage.db
coverage.xml
mindep:
name: Minimal dependency tests
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: "🛒 Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: "🐍 Set up Python"
id: install-python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: "🕶️ Set up uv"
run: |
pip install -U 'uv>=0.1.15'
- name: "📦 Set up Python dependencies"
id: install-deps
run: |
uv pip install --python $PYTHON -e "lenskit[test]" --resolution=lowest-direct
shell: bash
env:
PYTHON: '${{steps.install-python.outputs.python-path}}'
UV_EXTRA_INDEX_URL: 'https://download.pytorch.org/whl/cpu'
UV_INDEX_STRATEGY: unsafe-first-match
- name: "🔍 Inspect environment"
run: |
python -m lenskit.util.envcheck
- name: "🏃🏻➡️ Test LKPY"
run: |
python -m pytest --verbose --log-file=test.log --durations=25 --cov=lenskit/lenskit lenskit/tests
- name: "📐 Coverage results"
run: |
coverage xml
coverage report
cp .coverage coverage.db
- name: "📤 Upload test results"
uses: actions/upload-artifact@v4
if: always()
with:
name: test-mindep
path: |
test*.log
coverage.db
coverage.xml
funksvd:
name: 'FunkSVD tests on Python ${{matrix.python}}'
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
python:
- py311
- py312
steps:
- name: "🛒 Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: prefix-dev/setup-pixi@v0.8.1
with:
pixi-version: latest
activate-environment: true
environments: 'test-${{matrix.python}}-full'
cache-write: false
- name: "🔍 Inspect environment"
run: |
python -m lenskit.util.envcheck
- name: "🏃🏻➡️ Test LKPY"
run: |
python -m pytest --verbose --log-file=test.log --durations=25 --cov=lenskit-funksvd/lenskit lenskit-funksvd/tests
- name: "📐 Coverage results"
run: |
coverage xml
coverage report
cp .coverage coverage.db
- name: "📤 Upload test results"
uses: actions/upload-artifact@v4
if: always()
with:
name: 'test-funksvd-py${{matrix.python}}'
path: |
test*.log
coverage.db
coverage.xml
funksvd-mindep:
name: Minimal dependency tests for FunkSVD
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: "🛒 Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: "🐍 Set up Python"
id: install-python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: "🕶️ Set up uv"
run: |
pip install -U 'uv>=0.1.15'
- name: "📦 Set up Python dependencies"
id: install-deps
run: |
uv pip install --python $PYTHON -e "lenskit[test]" -e "lenskit-funksvd" --resolution=lowest-direct
shell: bash
env:
PYTHON: '${{steps.install-python.outputs.python-path}}'
UV_EXTRA_INDEX_URL: 'https://download.pytorch.org/whl/cpu'
UV_INDEX_STRATEGY: unsafe-first-match
- name: "🔍 Inspect environment"
run: |
python -m lenskit.util.envcheck
- name: "🏃🏻➡️ Test LKPY"
run: |
python -m pytest --verbose --log-file=test.log --durations=25 --cov=lenskit/lenskit --cov=lenskit-funksvd/lenskit lenskit/tests lenskit-funksvd/tests
- name: "📐 Coverage results"
run: |
coverage xml
coverage report
cp .coverage coverage.db
- name: "📤 Upload test results"
uses: actions/upload-artifact@v4
if: always()
with:
name: test-mindep-funksvd
path: |
test*.log
coverage.db
coverage.xml
implicit:
name: 'Implicit bridge tests on Python ${{matrix.python}}'
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
python:
- py311
- py312
steps:
- name: "🛒 Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: prefix-dev/setup-pixi@v0.8.1
with:
pixi-version: latest
activate-environment: true
environments: 'test-${{matrix.python}}-full'
cache-write: false
- name: "🔍 Inspect environment"
run: |
python -m lenskit.util.envcheck
- name: "🏃🏻➡️ Test LKPY"
run: |
python -m pytest --verbose --log-file=test.log --durations=25 --cov=lenskit-implicit/lenskit lenskit-implicit/tests
- name: "📐 Coverage results"
run: |
coverage xml
coverage report
cp .coverage coverage.db
- name: "📤 Upload test results"
uses: actions/upload-artifact@v4
if: always()
with:
name: 'test-implicit-py${{matrix.python}}'
path: |
test*.log
coverage.db
coverage.xml
implicit-mindep:
name: Minimal dependency tests for Implicit
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: "🛒 Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: "🐍 Set up Python"
id: install-python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: "🕶️ Set up uv"
run: |
pip install -U 'uv>=0.1.15'
- name: "📦 Set up Python dependencies"
id: install-deps
run: |
uv pip install --python $PYTHON -e "lenskit[test]" -e "lenskit-implicit" --resolution=lowest-direct
shell: bash
env:
PYTHON: '${{steps.install-python.outputs.python-path}}'
UV_EXTRA_INDEX_URL: 'https://download.pytorch.org/whl/cpu'
UV_INDEX_STRATEGY: unsafe-first-match
- name: "🔍 Inspect environment"
run: |
python -m lenskit.util.envcheck
- name: "🏃🏻➡️ Test LKPY"
run: |
python -m pytest --verbose --log-file=test.log --durations=25 --cov=lenskit/lenskit --cov=lenskit-implicit/lenskit lenskit/tests lenskit-implicit/tests
- name: "📐 Coverage results"
run: |
coverage xml
coverage report
cp .coverage coverage.db
- name: "📤 Upload test results"
uses: actions/upload-artifact@v4
if: always()
with:
name: test-mindep-implicit
path: |
test*.log
coverage.db
coverage.xml
hpf:
name: 'HPF bridge tests on Python ${{matrix.python}}'
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
python:
- py311
- py312
steps:
- name: "🛒 Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: prefix-dev/setup-pixi@v0.8.1
with:
pixi-version: latest
activate-environment: true
environments: 'test-${{matrix.python}}-full'
cache-write: false
- name: "🔍 Inspect environment"
run: |
python -m lenskit.util.envcheck
- name: "🏃🏻➡️ Test LKPY"
run: |
python -m pytest --verbose --log-file=test.log --durations=25 --cov=lenskit-hpf/lenskit lenskit-hpf/tests
- name: "📐 Coverage results"
run: |
coverage xml
coverage report
cp .coverage coverage.db
- name: "📤 Upload test results"
uses: actions/upload-artifact@v4
if: always()
with:
name: 'test-hpf-py${{matrix.python}}'
path: |
test*.log
coverage.db
coverage.xml
eval-tests:
name: Evaluation-based tests
runs-on: ubuntu-latest
steps:
- name: "🛒 Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: prefix-dev/setup-pixi@v0.8.1
with:
pixi-version: latest
activate-environment: true
environments: test-py311-full
cache-write: false
- name: Cache ML data
uses: actions/cache@v4
with:
path: |
data
!data/*.zip
key: test-mldata-001-ml-100k-ml-20m
- name: Download ML data
run: |
python -m lenskit.data.fetch ml-100k ml-20m
- name: Run Eval Tests
run: |
python -m pytest --cov=lenskit/lenskit --cov=lenskit-funksvd/lenskit --cov=lenskit-implicit/lenskit --cov=lenskit-hpf/lenskit -m 'eval or realdata' --log-file test-eval.log */tests
- name: "📐 Coverage results"
run: |
coverage xml
coverage report
cp .coverage coverage.db
- name: "📤 Upload test results"
uses: actions/upload-artifact@v4
if: always()
with:
name: test-eval-tests
path: |
test*.log
coverage.db
coverage.xml
doc-tests:
name: 'Demos, examples, and docs'
runs-on: ubuntu-latest
steps:
- name: "🛒 Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: prefix-dev/setup-pixi@v0.8.1
with:
pixi-version: latest
activate-environment: true
environments: test-examples
cache-write: false
- name: Cache ML data
uses: actions/cache@v4
with:
path: |
data
!data/*.zip
key: test-mldata-001-ml-100k-ml-1m-ml-10m-ml-20m
- name: Download ML data
run: |
python -m lenskit.data.fetch ml-100k ml-1m ml-10m ml-20m
- name: "📕 Validate documentation examples"
run: |
python -m pytest --cov=lenskit/lenskit --cov=lenskit-funksvd/lenskit --cov=lenskit-implicit/lenskit --cov=lenskit-hpf/lenskit --nbval-lax --doctest-glob='*.rst' --log-file test-docs.log docs */lenskit
- name: "📐 Coverage results"
run: |
coverage xml
coverage report
cp .coverage coverage.db
- name: "📤 Upload test results"
uses: actions/upload-artifact@v4
if: always()
with:
name: test-examples
path: |
test*.log
coverage.db
coverage.xml
results:
name: Test suite results
runs-on: ubuntu-latest
needs:
- conda
- vanilla
- nojit
- mindep
- funksvd
- funksvd-mindep
- implicit
- implicit-mindep
- hpf
- eval-tests
- doc-tests
steps:
- name: "🛒 Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Add upstream remote & author config
run: |
git remote add upstream https://github.com/lenskit/lkpy.git
git fetch upstream
git config user.name "LensKit Bot"
git config user.email lkbot@lenskit.org
- name: "🧚 Set up Pixi"
uses: prefix-dev/setup-pixi@v0.8.1
with:
pixi-version: latest
activate-environment: true
environments: report
- name: "📥 Download test artifacts"
uses: actions/download-artifact@v4
with:
pattern: test-*
path: test-logs
- name: "📋 List log files"
run: ls -laR test-logs
- name: "🔧 Fix coverage databases"
run: |
for dbf in test-logs/*/coverage.db; do
echo "fixing $dbf"
sqlite3 -echo "$dbf" "UPDATE file SET path = replace(path, '\', '/');"
done
- name: ⛙ Merge and report
run: |
coverage combine --keep test-logs/*/coverage.db
coverage xml
coverage html -d lenskit-coverage
coverage report --format=markdown >coverage.md
- name: Analyze diff coverage
if: github.event_name == 'pull_request'
run: |
diff-cover --json-report diff-cover.json --markdown-report diff-cover.md \
coverage.xml |tee diff-cover.txt
- name: ± Measure and report coverage
run: |
echo $PR_NUMBER > ./lenskit-coverage/pr-number
tclsh ./utils/measure-coverage.tcl
cat lenskit-coverage/report.md >$GITHUB_STEP_SUMMARY
env:
PR_NUMBER: '${{ github.event.number }}'
GH_TOKEN: '${{secrets.GITHUB_TOKEN}}'
- name: "📤 Upload coverage report"
uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-report
path: lenskit-coverage/
- name: "🚫 Fail if coverage is too low"
run: coverage report --fail-under=90