Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 119 additions & 103 deletions .github/workflows/main.yml → .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,39 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

name: pytest
name: Install and test

on:
push:
branches: ["main"]
branches:
- main
pull_request:
branches: ["main"]
branches:
- main

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

jobs:
code-quality:
name: code-quality
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
- name: repository checkout step
uses: actions/checkout@v6

- uses: actions/setup-python@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
python-version: '3.14'
enable-cache: true

- name: python environment step
uses: actions/setup-python@v6
with:
python-version: "3.14"

- name: install pre-commit
run: python3 -m pip install pre-commit
run: uv pip install pre-commit
env:
UV_SYSTEM_PYTHON: 1

- name: Checkout code
uses: actions/checkout@v6
Expand All @@ -40,7 +48,7 @@ jobs:

- name: Print changed files
run: |
echo "Changed files: $CHANGED_FILES"
echo "Changed files:" && echo "$CHANGED_FILES" | tr ' ' '\n'

- name: Run pre-commit on changed files
run: |
Expand All @@ -50,17 +58,42 @@ jobs:
echo "No changed files to check."
fi

pytest-nosoftdeps:
detect-notebooks-change:
needs: code-quality
name: nosoftdeps (${{ matrix.python-version }}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
env:
MPLBACKEND: Agg # https://github.com/orgs/community/discussions/26434
name: detect change affecting notebooks
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
notebooks: ${{ steps.check.outputs.notebooks }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Fetch main branch
run: git fetch origin main

- name: Check if cookbook, pypfopt or pyproject.toml changed
id: check
run: |
if git diff --quiet origin/main -- cookbook/ pypfopt/ pyproject.toml; then
echo "No notebook related changes"
echo "notebooks=false" >> $GITHUB_OUTPUT
else
echo "Detected changes in notebooks or pypfopt"
echo "notebooks=true" >> $GITHUB_OUTPUT
fi

run-notebook-examples:
needs: detect-notebooks-change
if: ${{ needs.detect-notebooks-change.outputs.notebooks == 'true' }}
runs-on: ubuntu-latest

strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
fail-fast: false # to not fail all combinations if just one fails
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
fail-fast: false

steps:
- uses: actions/checkout@v6
Expand All @@ -69,39 +102,39 @@ jobs:
uses: astral-sh/setup-uv@v7
with:
enable-cache: true

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

- name: Display Python version
run: python -c "import sys; print(sys.version)"

- name: Install dependencies
shell: bash
run: uv pip install ".[dev]" --no-cache-dir
env:
UV_SYSTEM_PYTHON: 1
run: uv sync --extra all_extras --group dev --extra notebook_test --no-cache

- name: Show dependencies
run: uv pip list

- name: Test with pytest
- name: Collect notebooks
id: notebooks
shell: bash
run: |
NOTEBOOKS=$(find cookbook -name '*.ipynb' -print0 | xargs -0 echo)
echo "notebooks=$NOTEBOOKS" >> $GITHUB_OUTPUT

- name: Run notebooks
shell: bash
run: |
pytest ./tests
uv run pytest --reruns 3 --nbmake --nbmake-timeout=3600 -vv ${{ steps.notebooks.outputs.notebooks }}

pytest:
needs: pytest-nosoftdeps
name: (${{ matrix.python-version }}, ${{ matrix.os }})
test-nosoftdeps:
needs: code-quality
name: test-nosoftdeps (${{ matrix.python-version }}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
env:
MPLBACKEND: Agg # https://github.com/orgs/community/discussions/26434
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
fail-fast: false # to not fail all combinations if just one fails

steps:
- uses: actions/checkout@v6
Expand All @@ -110,34 +143,67 @@ jobs:
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
python-version: ${{ matrix.python-version }}

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
- name: Display Python version
run: python -c "import sys; print(sys.version)"

- name: Force non-GUI Matplotlib backend (Windows)
if: ${{ matrix.os == 'windows-latest' }}
shell: pwsh
run: echo "MPLBACKEND=Agg" >> $env:GITHUB_ENV

- name: Install dependencies
shell: bash
run: uv sync --group dev --no-cache

- name: Show dependencies
run: uv pip list

- name: Run tests
run: uv run pytest ./tests

test-full:
needs: test-nosoftdeps
name: test-full (${{ matrix.python-version }}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
os: [ubuntu-latest, macos-latest, windows-latest]

steps:
- uses: actions/checkout@v6

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
python-version: ${{ matrix.python-version }}

- name: Display Python version
run: python -c "import sys; print(sys.version)"

- name: Force non-GUI Matplotlib backend (Windows)
if: ${{ matrix.os == 'windows-latest' }}
shell: pwsh
run: echo "MPLBACKEND=Agg" >> $env:GITHUB_ENV

- name: Install dependencies
shell: bash
run: uv pip install ".[dev,all_extras]" --no-cache-dir
env:
UV_SYSTEM_PYTHON: 1
run: uv sync --extra all_extras --extra dev --no-cache

- name: Show dependencies
run: uv pip list

- name: Test with pytest
run: |
pytest ./tests
- name: Run tests
run: uv run pytest ./tests

codecov:
name: coverage (${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
name: codecov (${{ matrix.python-version }}, ${{ matrix.os }})
needs: code-quality
env:
MPLBACKEND: Agg # https://github.com/orgs/community/discussions/26434
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
Expand All @@ -150,27 +216,25 @@ jobs:
uses: astral-sh/setup-uv@v7
with:
enable-cache: true

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

- name: Display Python version
run: python -c "import sys; print(sys.version)"

- name: Force non-GUI Matplotlib backend (Windows)
if: ${{ matrix.os == 'windows-latest' }}
shell: pwsh
run: echo "MPLBACKEND=Agg" >> $env:GITHUB_ENV

- name: Install dependencies
shell: bash
run: uv pip install ".[dev,all_extras]" --no-cache-dir
env:
UV_SYSTEM_PYTHON: 1
run: uv sync --only-group dev --only-group cov

- name: Show dependencies
run: uv pip list

- name: Generate coverage report
run: |
pip install pytest pytest-cov
pytest --cov=./ --cov-report=xml

- name: Upload coverage to Codecov
Expand All @@ -180,51 +244,3 @@ jobs:
with:
files: ./coverage.xml
fail_ci_if_error: true

notebooks:
needs: code-quality
runs-on: ubuntu-latest

strategy:
matrix:
python-version: [ '3.10', '3.11', '3.12', '3.13', '3.14' ]
fail-fast: false

steps:
- uses: actions/checkout@v6

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true

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

- name: Display Python version
run: python -c "import sys; print(sys.version)"

- name: Install dependencies
shell: bash
run: uv pip install ".[dev,all_extras,notebook_test]" --no-cache-dir
env:
UV_SYSTEM_PYTHON: 1

- name: Show dependencies
run: uv pip list

# Discover all notebooks
- name: Collect notebooks
id: notebooks
shell: bash
run: |
NOTEBOOKS=$(find cookbook -name '*.ipynb' -print0 | xargs -0 echo)
echo "notebooks=$NOTEBOOKS" >> $GITHUB_OUTPUT

# Run all discovered notebooks with nbmake
- name: Test notebooks
shell: bash
run: |
uv run pytest --reruns 3 --nbmake --nbmake-timeout=3600 -vv ${{ steps.notebooks.outputs.notebooks }}
Loading