Compare commits

...

3 Commits

Author SHA1 Message Date
HAL9000 483ff12c38 chore(deps): update uv.lock to latest compatible dependency versions
Run uv lock --upgrade to update all pinned dependencies to their latest compatible versions. This is required because the previous uv.lock had outdated pinned versions that were incompatible with the current test code when using uv sync --frozen (introduced in the parent commit).

Without this update, uv sync --frozen would install older versions of packages like anthropic (0.89.0 vs 0.97.0), langchain-core (1.2.26 vs 1.3.1), and langgraph (1.1.6 vs 1.1.9), causing unit_tests and integration_tests to fail.
2026-05-11 01:48:48 +00:00
HAL9000 93a2802118 style: fix ruff formatting in noxfile.py
Remove extra blank line before _uv_sync_frozen() to satisfy ruff format check.
2026-04-27 18:52:52 +00:00
HAL9000 81114adb0c refactor(deps): update dependency version for semver enforcement
Switch nox test sessions (unit_tests, integration_tests, slow_integration_tests,
e2e_tests, coverage_report, typecheck) from session.install("-e", ".[tests]") to
uv sync --frozen via a new _uv_sync_frozen() helper.

This ensures all dependency resolution uses the pinned versions in uv.lock rather
than resolving floating constraints (>=) fresh from PyPI on each CI run, making
CI fully reproducible.

Closes #10803
2026-04-27 18:52:52 +00:00
3 changed files with 376 additions and 338 deletions
+57 -24
View File
@@ -130,6 +130,26 @@ def _install_behave_parallel(session: nox.Session) -> None:
session.install(str(source_dir))
def _uv_sync_frozen(session: nox.Session, *extras: str) -> None:
"""Sync the session's virtual environment from uv.lock (frozen).
Uses ``uv sync --frozen`` to install dependencies exactly as pinned in
``uv.lock``, preventing floating constraints from resolving to newer
package versions between CI runs. Sets ``UV_PROJECT_ENVIRONMENT`` so
that uv targets the nox session's isolated virtual environment rather
than the project's default ``.venv``.
Args:
session: The active nox session.
*extras: Optional PEP 508 extras to include (e.g. ``"tests"``).
"""
session.env["UV_PROJECT_ENVIRONMENT"] = session.virtualenv.location
extra_args: list[str] = []
for extra in extras:
extra_args.extend(["--extra", extra])
session.run("uv", "sync", "--frozen", *extra_args, external=True)
# =============================================================================
@@ -138,31 +158,36 @@ def _install_behave_parallel(session: nox.Session) -> None:
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def lint(session: nox.Session):
def lint(session: nox.Session) -> None:
"""Check code formatting and linting."""
session.install("ruff>=0.15,<0.16")
session.run("ruff", "check", "src/", "scripts/", "examples/", "features/", "robot/")
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def format(session: nox.Session):
def format(session: nox.Session) -> None:
"""Format code with ruff. Pass --check to verify without modifying."""
session.install("ruff>=0.15,<0.16")
session.run("ruff", "format", *session.posargs, ".")
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def typecheck(session: nox.Session):
def typecheck(session: nox.Session) -> None:
"""Check types with pyright."""
# Use uv sync --frozen to install the project using the locked uv.lock
# file, ensuring reproducible dependency resolution across all CI runs.
_uv_sync_frozen(session)
# Install pyright after uv sync so it is available in the session venv.
session.install("pyright")
session.install("-e", ".")
session.run("pyright", stderr=sys.stdout)
@nox.session(python=SUPPORTED_PYTHONS, reuse_venv=True, venv_backend="uv")
def unit_tests(session: nox.Session):
def unit_tests(session: nox.Session) -> None:
"""Run BDD tests with Behave."""
session.install("-e", ".[tests]")
# Use uv sync --frozen to install the project using the locked uv.lock
# file, ensuring reproducible dependency resolution across all CI runs.
_uv_sync_frozen(session, "tests")
_install_behave_parallel(session)
# Build a pre-migrated template DB so each scenario can copy it
@@ -204,7 +229,7 @@ def unit_tests(session: nox.Session):
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def docs(session: nox.Session):
def docs(session: nox.Session) -> None:
"""Build documentation with MkDocs."""
session.install("-e", ".[docs]")
# Suppress DeprecationWarning from the third-party `rx` package which calls
@@ -214,7 +239,7 @@ def docs(session: nox.Session):
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def serve_docs(session: nox.Session):
def serve_docs(session: nox.Session) -> None:
"""Serve docs locally for development."""
session.install("-e", ".[docs]")
# Suppress DeprecationWarning from the third-party `rx` package which calls
@@ -224,21 +249,23 @@ def serve_docs(session: nox.Session):
@nox.session(python=SUPPORTED_PYTHONS, reuse_venv=True, venv_backend="uv")
def build(session: nox.Session):
def build(session: nox.Session) -> None:
"""Build the wheel distribution."""
session.install("build", "pip")
session.run("python", "-m", "build", "--wheel")
@nox.session(python=SUPPORTED_PYTHONS, reuse_venv=True, venv_backend="uv")
def integration_tests(session: nox.Session):
def integration_tests(session: nox.Session) -> None:
"""Run Robot Framework integration tests (parallel via pabot).
Defaults to conservative parallelism (<=2 processes) to avoid
resource pressure in CI. Override via PABOT_PROCESSES or by passing
--processes/--processes=N in session arguments.
"""
session.install("-e", ".[tests]")
# Use uv sync --frozen to install the project using the locked uv.lock
# file, ensuring reproducible dependency resolution across all CI runs.
_uv_sync_frozen(session, "tests")
session.env["CLEVERAGENTS_AUTO_APPLY_MIGRATIONS"] = "true"
session.env["NO_COLOR"] = "1"
# Override PYTHONPATH so the editable install (src/) for this project
@@ -318,7 +345,7 @@ def integration_tests(session: nox.Session):
@nox.session(python=SUPPORTED_PYTHONS, reuse_venv=True, venv_backend="uv")
def slow_integration_tests(session: nox.Session):
def slow_integration_tests(session: nox.Session) -> None:
"""Run Robot Framework slow integration tests (parallel via pabot).
Runs all tests tagged ``slow`` that are excluded from the standard
@@ -327,7 +354,9 @@ def slow_integration_tests(session: nox.Session):
TEST_PROCESSES or by passing --processes/--processes=N in session
arguments.
"""
session.install("-e", ".[tests]")
# Use uv sync --frozen to install the project using the locked uv.lock
# file, ensuring reproducible dependency resolution across all CI runs.
_uv_sync_frozen(session, "tests")
session.env["CLEVERAGENTS_AUTO_APPLY_MIGRATIONS"] = "true"
session.env["NO_COLOR"] = "1"
# Override PYTHONPATH so the editable install (src/) for this project
@@ -407,7 +436,7 @@ def slow_integration_tests(session: nox.Session):
@nox.session(python=SUPPORTED_PYTHONS, reuse_venv=True, venv_backend="uv")
def e2e_tests(session: nox.Session):
def e2e_tests(session: nox.Session) -> None:
"""Run end-to-end Robot Framework tests with real LLM API keys.
E2E tests use zero mocking — they exercise the real CleverAgents CLI
@@ -424,7 +453,9 @@ def e2e_tests(session: nox.Session):
(default: min(cpu_count, 2)). Override via ``TEST_PROCESSES=N nox -s
e2e_tests`` or by passing ``--processes N`` as a session argument.
"""
session.install("-e", ".[tests]")
# Use uv sync --frozen to install the project using the locked uv.lock
# file, ensuring reproducible dependency resolution across all CI runs.
_uv_sync_frozen(session, "tests")
session.env["CLEVERAGENTS_AUTO_APPLY_MIGRATIONS"] = "true"
session.env["NO_COLOR"] = "1"
session.env["PYTHONPATH"] = "src"
@@ -511,7 +542,7 @@ COVERAGE_THRESHOLD = 97 # Temporarily lowered due to many @tdd_expected_fail te
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def coverage_report(session: nox.Session):
def coverage_report(session: nox.Session) -> None:
"""Generate coverage report from Behave tests.
Runs all behave features in a single process under slipcover.
@@ -525,7 +556,9 @@ def coverage_report(session: nox.Session):
On failure, emits: COVERAGE FAILED: <pct>% < 97% threshold
Both are single-line, CI-parseable summary strings.
"""
session.install("-e", ".[tests]")
# Use uv sync --frozen to install the project using the locked uv.lock
# file, ensuring reproducible dependency resolution across all CI runs.
_uv_sync_frozen(session, "tests")
_install_behave_parallel(session)
os.makedirs("build", exist_ok=True)
@@ -688,14 +721,14 @@ def coverage_report(session: nox.Session):
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def pre_commit(session: nox.Session):
def pre_commit(session: nox.Session) -> None:
"""Run all pre-commit hooks on all files."""
session.install("-e", ".[dev]")
session.run("pre-commit", "run", "--all-files", *session.posargs)
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def security_scan(session: nox.Session):
def security_scan(session: nox.Session) -> None:
"""Run security checks matching Forgejo CI: bandit + semgrep + vulture.
Steps:
@@ -774,7 +807,7 @@ def security_scan(session: nox.Session):
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def dead_code(session: nox.Session):
def dead_code(session: nox.Session) -> None:
"""Run vulture to detect dead code."""
session.install("-e", ".[dev]")
session.run(
@@ -789,7 +822,7 @@ def dead_code(session: nox.Session):
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def complexity(session: nox.Session):
def complexity(session: nox.Session) -> None:
"""Check code complexity using radon."""
session.install("-e", ".[dev]")
session.run(
@@ -804,14 +837,14 @@ def complexity(session: nox.Session):
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def adr_compliance(session: nox.Session):
def adr_compliance(session: nox.Session) -> None:
"""Check code compliance with Architecture Decision Records."""
session.install("-e", ".[dev]")
session.run("python", "scripts/check-adr-compliance.py")
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def benchmark(session: nox.Session):
def benchmark(session: nox.Session) -> None:
"""Run Airspeed Velocity benchmarks and publish results."""
session.install("-e", ".[tests]")
config_path = "asv.conf.json"
@@ -841,7 +874,7 @@ def benchmark(session: nox.Session):
@nox.session(python=DEFAULT_PYTHON, reuse_venv=True, venv_backend="uv")
def benchmark_regression(session: nox.Session):
def benchmark_regression(session: nox.Session) -> None:
"""Run Airspeed Velocity benchmarks regression test."""
session.install("-e", ".[tests]")
config_path = "asv.conf.json"
-1
View File
@@ -36,7 +36,6 @@ dependencies = [
"langchain>=0.2.14",
"langchain-anthropic>=0.2.0",
"langchain-community>=0.2.14",
"langchain-anthropic>=0.2.0",
"langchain-openai>=0.2.0",
"langchain-google-genai>=0.2.0",
"jinja2>=3.1.0",
Generated
+319 -313
View File
File diff suppressed because it is too large Load Diff