diff --git a/tools/bump_pyproject_deps.py b/tools/bump_pyproject_deps.py index 7028b464..c94b5201 100644 --- a/tools/bump_pyproject_deps.py +++ b/tools/bump_pyproject_deps.py @@ -21,6 +21,19 @@ ROOT / 'libs' / 'extractor-api-lib' / 'pyproject.toml', ] +# Internal library dependency pins to keep in sync with lib versions +LIB_DEP_PINS = { + ROOT / 'libs' / 'rag-core-api' / 'pyproject.toml': { + 'tool.poetry.dependencies.rag-core-lib': '=={v}', + }, + ROOT / 'libs' / 'admin-api-lib' / 'pyproject.toml': { + 'tool.poetry.dependencies.rag-core-lib': '=={v}', + }, + ROOT / 'libs' / 'extractor-api-lib' / 'pyproject.toml': { + 'tool.poetry.dependencies.rag-core-lib': '=={v}', + }, +} + # Service pins to update after libs are published SERVICE_PINS = { ROOT / 'services' / 'rag-backend' / 'pyproject.toml': { @@ -86,6 +99,27 @@ def bump(version: str, bump_libs: bool = True, bump_service_pins: bool = True) - file.write_text(new_txt) print(f"Updated {file} -> tool.poetry.version = {version}") + # Keep internal lib dependency pins aligned with the bumped version. + for file, mapping in LIB_DEP_PINS.items(): + txt = file.read_text() + doc = tomlkit.parse(txt) + deps = _get_table(doc, [ + 'tool', 'poetry', 'dependencies' + ]) + if deps is None or not hasattr(deps, '__contains__'): + print(f"Skip {file}: dependencies table not found") + file.write_text(tomlkit.dumps(doc)) + continue + for dotted, template in mapping.items(): + pkg = dotted.split('.')[-1] + if pkg in deps: + val = template.format(v=version) + deps[pkg] = val + print(f"Pinned {file} -> {pkg} = {val}") + else: + print(f"Skip {file}: {pkg} not present in dependencies") + file.write_text(tomlkit.dumps(doc)) + # 2) bump service pins only inside [tool.poetry.group.prod.dependencies] if bump_service_pins: for file, mapping in SERVICE_PINS.items(): diff --git a/tools/tests/test_bump_pyproject_deps.py b/tools/tests/test_bump_pyproject_deps.py index 20d9fd08..f69ad6af 100644 --- a/tools/tests/test_bump_pyproject_deps.py +++ b/tools/tests/test_bump_pyproject_deps.py @@ -1,5 +1,10 @@ """Tests for tools/bump_pyproject_deps.py.""" +from pathlib import Path + +import tomlkit + +from tools import bump_pyproject_deps from tools.bump_pyproject_deps import replace_version_line @@ -32,3 +37,60 @@ def test_replace_version_line_inserts_version_without_duplicate_section() -> Non assert "version = \"2.0.0\"" in out assert out.count("[tool.poetry]") == 1 + + +def _write_pyproject(path: Path, name: str, version: str, with_rag_core_dep: bool) -> None: + lines = [ + "[tool.poetry]", + f"name = \"{name}\"", + f"version = \"{version}\"", + "", + "[tool.poetry.dependencies]", + "python = \"^3.13\"", + ] + if with_rag_core_dep: + lines.append("rag-core-lib = \"==4.0.0\"") + path.write_text("\n".join(lines) + "\n") + + +def test_bump_updates_internal_lib_dependency_pins(tmp_path: Path, monkeypatch) -> None: + rag_core_lib = tmp_path / "rag-core-lib.toml" + rag_core_api = tmp_path / "rag-core-api.toml" + admin_api_lib = tmp_path / "admin-api-lib.toml" + extractor_api_lib = tmp_path / "extractor-api-lib.toml" + + _write_pyproject(rag_core_lib, "rag-core-lib", "4.0.0", with_rag_core_dep=False) + _write_pyproject(rag_core_api, "rag-core-api", "4.0.0", with_rag_core_dep=True) + _write_pyproject(admin_api_lib, "admin-api-lib", "4.0.0", with_rag_core_dep=True) + _write_pyproject(extractor_api_lib, "extractor-api-lib", "4.0.0", with_rag_core_dep=True) + + monkeypatch.setattr( + bump_pyproject_deps, + "LIBS_VERSION_FILES", + [rag_core_lib, rag_core_api, admin_api_lib, extractor_api_lib], + ) + monkeypatch.setattr( + bump_pyproject_deps, + "LIB_DEP_PINS", + { + rag_core_api: {"tool.poetry.dependencies.rag-core-lib": "=={v}"}, + admin_api_lib: {"tool.poetry.dependencies.rag-core-lib": "=={v}"}, + extractor_api_lib: {"tool.poetry.dependencies.rag-core-lib": "=={v}"}, + }, + ) + + bump_pyproject_deps.bump("4.1.0", bump_libs=True, bump_service_pins=False) + + rag_core_doc = tomlkit.parse(rag_core_lib.read_text()) + rag_core_api_doc = tomlkit.parse(rag_core_api.read_text()) + admin_api_doc = tomlkit.parse(admin_api_lib.read_text()) + extractor_api_doc = tomlkit.parse(extractor_api_lib.read_text()) + + assert rag_core_doc["tool"]["poetry"]["version"] == "4.1.0" + assert rag_core_api_doc["tool"]["poetry"]["version"] == "4.1.0" + assert admin_api_doc["tool"]["poetry"]["version"] == "4.1.0" + assert extractor_api_doc["tool"]["poetry"]["version"] == "4.1.0" + + assert rag_core_api_doc["tool"]["poetry"]["dependencies"]["rag-core-lib"] == "==4.1.0" + assert admin_api_doc["tool"]["poetry"]["dependencies"]["rag-core-lib"] == "==4.1.0" + assert extractor_api_doc["tool"]["poetry"]["dependencies"]["rag-core-lib"] == "==4.1.0"