From 0ae195b64e787ee30c0517e1c78073c10f3ea1ca Mon Sep 17 00:00:00 2001 From: Guillaume Tauzin <4648633+gtauzin@users.noreply.github.com> Date: Wed, 25 Mar 2026 20:42:05 +0100 Subject: [PATCH 1/2] feat(template): add test_compat nox session, justfile command, and CI job Backport compat testing infrastructure from yohou: - noxfile: test_compat session that pins dependency versions via posargs - justfile: test-compat command delegating to nox - tests.yml: test-compat CI job with empty matrix (users populate pins) --- .../tests.yml.jinja | 30 ++++++++++++ template/justfile.jinja | 4 ++ template/noxfile.py.jinja | 47 +++++++++++++++++++ 3 files changed, 81 insertions(+) diff --git a/template/.github/{% if include_actions %}workflows{% endif %}/tests.yml.jinja b/template/.github/{% if include_actions %}workflows{% endif %}/tests.yml.jinja index 37abcf0..d1fb9f5 100644 --- a/template/.github/{% if include_actions %}workflows{% endif %}/tests.yml.jinja +++ b/template/.github/{% if include_actions %}workflows{% endif %}/tests.yml.jinja @@ -51,6 +51,36 @@ jobs: - name: Run fast tests (excluding slow/integration tests) run: nox -s test_fast --python {% raw %}${{ matrix.python-version }}{% endraw %} + # Compatibility test against oldest supported dependency versions + test-compat: + name: {% raw %}Compat tests (${{ matrix.pins }}){% endraw %} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + pins: [] + + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + lfs: true + + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + cache-dependency-glob: "pyproject.toml" + + - name: Install nox + run: uv tool install nox + + - name: Set up Python {{ min_python_version }} + run: uv python install {{ min_python_version }} + + - name: Run compat tests + run: nox -s test_compat -- {% raw %}${{ matrix.pins }}{% endraw %} + # Full test suite runs on Ubuntu when PR is not draft or on main branch test-full: name: {% raw %}Full test suite (Python ${{ matrix.python-version }}){% endraw %} diff --git a/template/justfile.jinja b/template/justfile.jinja index a584881..bc265f5 100644 --- a/template/justfile.jinja +++ b/template/justfile.jinja @@ -28,6 +28,10 @@ test-cov: # Run docstring examples test-docstrings: uv run pytest --doctest-modules --doctest-continue-on-failure --no-cov src/{{ package_name }} + +# Run fast tests after pinning dependency versions (e.g. just test-compat some-package==1.0.0) +test-compat +PINS='': + uvx nox -s test_compat -- {% raw %}{{PINS}}{% endraw %} {% if include_examples %} # Run marimo example notebook interactively example file='': diff --git a/template/noxfile.py.jinja b/template/noxfile.py.jinja index eb7d9cf..f40ebc1 100644 --- a/template/noxfile.py.jinja +++ b/template/noxfile.py.jinja @@ -143,6 +143,53 @@ def test_slow(session: nox.Session) -> None: "-v", *session.posargs, ) + + +@nox.session(python=PYTHON_VERSIONS, venv_backend="uv") +def test_compat(session: nox.Session) -> None: + """Run fast tests after pinning one or more dependency versions. + + Usage:: + + uvx nox -s test_compat -- some-package==1.0.0 + uvx nox -s test_compat -- some-package==1.0.0 other-package==2.0.0 + + Each positional argument must be a pip requirement specifier + (e.g. ``package==version``). If none are given the session runs + with the default (latest compatible) versions. + """ + # Install dependencies + session.run_install( + "uv", + "sync", + "--no-default-groups", + "--group", + "tests", + env={"UV_PROJECT_ENVIRONMENT": session.virtualenv.location}, + ) + + # Downgrade / pin requested packages + if session.posargs: + session.run( + "uv", + "pip", + "install", + *session.posargs, + "--python", + session.virtualenv.location + "/bin/python", + ) + + # Run fast tests + session.run( + "pytest", + "tests", + "--no-cov", + "-m", + "not slow and not integration{% if include_examples %} and not example{% endif %}", + "-n", + "auto", + "-v", + ) {% if include_examples %} @nox.session(venv_backend="uv") From 7d6967d56863012129bf03d59ed2a4c32cfa336a Mon Sep 17 00:00:00 2001 From: Guillaume Tauzin <4648633+gtauzin@users.noreply.github.com> Date: Wed, 25 Mar 2026 20:48:05 +0100 Subject: [PATCH 2/2] test: add assertions for test_compat in workflow and justfile tests --- tests/test_template.py | 4 ++++ tests/test_template_options.py | 1 + 2 files changed, 5 insertions(+) diff --git a/tests/test_template.py b/tests/test_template.py index 97c9819..240c9c9 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -284,6 +284,10 @@ def test_github_workflows(copie_session_default): assert "test_docstrings:" in content, "test_docstrings job not found in tests workflow" assert "nox -s test_docstrings" in content, "test_docstrings nox session not run in CI" + # Check for test-compat job + assert "test-compat:" in content, "test-compat job not found in tests workflow" + assert "nox -s test_compat" in content, "test_compat nox session not run in CI" + # Check PR title validation workflow pr_title_workflow = result.project_dir / ".github" / "workflows" / "pr-title.yml" assert pr_title_workflow.is_file(), "PR title validation workflow not found" diff --git a/tests/test_template_options.py b/tests/test_template_options.py index a5a2cf3..2124462 100644 --- a/tests/test_template_options.py +++ b/tests/test_template_options.py @@ -236,6 +236,7 @@ def test_justfile_commands_comprehensive(copie): "test-slow:", "test-cov:", "test-docstrings:", + "test-compat ", "fix:", # single command for format, lint, and type check "build:", "serve:",