diff --git a/scripts/ci/classify_changes.py b/scripts/ci/classify_changes.py index 00ed02d6589..d9b55fb049f 100644 --- a/scripts/ci/classify_changes.py +++ b/scripts/ci/classify_changes.py @@ -56,7 +56,11 @@ def _is_docs(p: str) -> bool: def _py_irrelevant(p: str) -> bool: - return _is_docs(p) or p in _ROOT_NPM or p.startswith(_PY_SKIP) or p.startswith(_DOCKER_META) + # Root npm manifests are NOT python-irrelevant: several Python invariant + # tests read package.json / package-lock.json (tap-cluster, electron pin, + # lazy-deps, lockfile churn), so a lockfile-only change can break the Python + # suite. Omitting them here is what let #63970 merge green then redden main. + return _is_docs(p) or p.startswith(_PY_SKIP) or p.startswith(_DOCKER_META) def _is_scan(p: str) -> bool: diff --git a/tests/ci/test_classify_changes.py b/tests/ci/test_classify_changes.py index e1db0ccf20d..5a7f281c720 100644 --- a/tests/ci/test_classify_changes.py +++ b/tests/ci/test_classify_changes.py @@ -50,8 +50,10 @@ CASES = { "uv.lock → python": (["uv.lock"], _lanes(python=True)), "ts package → frontend": (["apps/desktop/src/app.tsx"], _lanes(frontend=True)), "ui-tui → frontend": (["ui-tui/src/entry.ts"], _lanes(frontend=True)), - # Lockfile bump shifts every TS package's tree, but not the Python suite. - "root lockfile → frontend, not python": (["package-lock.json"], _lanes(frontend=True)), + # Lockfile bump shifts every TS package's tree AND feeds Python invariant + # tests that read package-lock.json (tap-cluster, electron pin, lazy-deps). + "root lockfile → frontend + python": (["package-lock.json"], _lanes(frontend=True, python=True)), + "root package.json → frontend + python": (["package.json"], _lanes(frontend=True, python=True)), "website → site": (["website/docs/intro.md"], _lanes(site=True)), # SKILL.md reads like docs, but the skill-doc tests read skills/, so a # skill edit must still run Python.