From 292fe43731728db58dc66fbbc9596dee2c16855d Mon Sep 17 00:00:00 2001 From: huanghuoguoguo <1051233107@qq.com> Date: Fri, 30 Oct 2026 11:11:31 +0800 Subject: [PATCH] test(plugins): use in-tree sources without hash pins Use the in-tree plugins directly for consumer contracts and avoid per-edit hash refreshes. --- plugins/MIGRATION.md | 10 ++++++---- plugins/scripts/test_repository.py | 5 +++++ tests/utils/legacy_plugin_contract.py | 14 ++++++++------ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/plugins/MIGRATION.md b/plugins/MIGRATION.md index 62d15b09d..3988dc3b3 100644 --- a/plugins/MIGRATION.md +++ b/plugins/MIGRATION.md @@ -20,10 +20,12 @@ remain historical evidence, not certification of newly built packages. installation, configuration and Marketplace publication remain independent. - Each plugin retains its dependency declarations and test environment. Core's pytest configuration and pre-commit formatting do not apply to plugin suites. -- Core consumer tests use this checkout's `plugins/` and integrity-checked files - in `tests/fixtures/legacy_plugin_identity_sources.json`. Refresh the relevant - hashes deliberately when changing those consumer contracts. Published SDK - compatibility continues to be tested by the independent plugin workflows. +- Core consumer tests use this checkout's `plugins/` directly when the source lock + is marked `in-tree`; the listed files are required to exist, but their contents + are not pinned so ordinary plugin changes do not require fixture updates. + Hashes remain available for externally provisioned, revision-pinned sources. + Published SDK compatibility continues to be tested by the independent plugin + workflows. - Core wheels, sdists, Docker contexts, release ZIPs and fnOS staging exclude this tree and `.lbpkg` files. Git export archives exclude this tree as well; a normal Git checkout still contains all plugin sources. diff --git a/plugins/scripts/test_repository.py b/plugins/scripts/test_repository.py index 2f6fe01c9..2af5bb192 100644 --- a/plugins/scripts/test_repository.py +++ b/plugins/scripts/test_repository.py @@ -137,6 +137,11 @@ class RepositoryTests(unittest.TestCase): lock = json.loads((CORE / 'tests/fixtures/legacy_plugin_identity_sources.json').read_text()) self.assertEqual(lock['root'], 'plugins') self.assertEqual(lock['repository'], 'langbot-app/LangBot') + if lock.get('revision') == 'in-tree': + for key in ('files', 'local_agent_files'): + for relative in lock[key]: + self.assertTrue((ROOT / relative).is_file(), relative) + return for key in ('files', 'local_agent_files'): for relative, expected in lock[key].items(): self.assertEqual(hashlib.sha256((ROOT / relative).read_bytes()).hexdigest(), expected, relative) diff --git a/tests/utils/legacy_plugin_contract.py b/tests/utils/legacy_plugin_contract.py index e2bbf5a9c..3bbc84892 100644 --- a/tests/utils/legacy_plugin_contract.py +++ b/tests/utils/legacy_plugin_contract.py @@ -25,16 +25,18 @@ def verified_plugin_root(*, files_key: str = 'files') -> Path: pytest.fail('LANGBOT_LEGACY_PLUGIN_ROOT is set but empty', pytrace=False) root = Path(configured).resolve() lock = json.loads(SOURCE_LOCK.read_text()) + verify_hashes = lock.get('revision') != 'in-tree' for relative, expected in lock[files_key].items(): path = root / relative if not path.resolve().is_relative_to(root) or not path.is_file(): pytest.fail(f'Official plugin fixture is missing or outside its root: {relative}', pytrace=False) - actual = hashlib.sha256(path.read_bytes()).hexdigest() - if actual != expected: - pytest.fail( - f'Official plugin fixture hash mismatch: {relative}; expected {lock["repository"]}@{lock["revision"]}', - pytrace=False, - ) + if verify_hashes: + actual = hashlib.sha256(path.read_bytes()).hexdigest() + if actual != expected: + pytest.fail( + f'Official plugin fixture hash mismatch: {relative}; expected {lock["repository"]}@{lock["revision"]}', + pytrace=False, + ) return root