chore: auto release commit (2026-09-15 03:29:00)
All checks were successful
技能自动化发布 / release (push) Successful in 11s

This commit is contained in:
2026-09-15 03:29:00 +08:00
parent 689810eaeb
commit 22b42f8d30
9 changed files with 2063 additions and 1738 deletions

View File

@@ -2225,6 +2225,98 @@ def test_logs_viewer_resolves_relative_path() -> tuple[bool, str]:
os.environ.pop("LOG_FILE", None)
# ---------- v1.1.31: facade 完整性 smoke test(拆分 platform_collector.py 后)----------
def test_facade_reexports_all_symbols_v1_31() -> tuple[bool, str]:
"""v1.1.31: 验证 platform_collector facade 暴露拆分后的所有公开符号。
拆分后 4 个 sub-modules(login / collect / persist / queue)的全部公开符号
都必须从 facade 可见(re-export),保证现有 import 路径(service.platform_collector.X)
不被破坏。CLI handler、Action schema、所有现有测试都依赖这个不变量。
还顺带校验:
- 异常类是 type
- 模块常量是 str
- _ENV_CACHE 是 dict、_ENV_CACHE_LOADED 是 bool
- 其余函数/方法 callable
"""
from service import platform_collector as pc
expected = [
# ---- 异常类(facade 自身持有)----
"RPAError", "LoginTimeoutError", "MissingBrowserError", "TableNotFoundError",
# ---- env utilities(facade 自身持有,测试 _ENV_CACHE.clear() 隔离缓存)----
"_safe_getenv_dir", "_get_env", "_load_env_file",
"_ENV_CACHE", "_ENV_CACHE_LOADED",
# ---- 模块常量(facade 自身持有,测试可 monkey-patch)----
"PLATFORM_BASE", "PLATFORM_HR_PATH", "PLATFORM_URL",
"ROOT_URL", "SELECT_URL", "SPA_HOME_URL", "SPA_LOGIN_URL",
# ---- login (12) re-exported from platform_collector_login ----
"_try_auto_sign_in", "_wait_for_login_inputs_filled",
"_is_login_page_url_for_user", "_wait_for_manual_login",
"_wait_for_url_stable", "_fill_root_login",
"_fill_spa_login_from_env", "_is_dev_mode_panel_open",
"_resolve_target_industry", "_click_dev_mode_sign_in_for_industry",
"_click_campus_link", "_fill_spa_login",
# ---- collect (2) re-exported from platform_collector_collect ----
"collect_all", "_error_result",
# ---- persist (2) re-exported from platform_collector_persist ----
"_persist_contracts", "_enqueue_download_tasks_safe",
# ---- queue (7) re-exported from platform_collector_queue ----
"_download_materials_for_row", "_find_row_for_contract", "process_queue",
"_gen_contract_id", "_normalize_date", "_parse_days", "_parse_alert",
]
missing = [s for s in expected if not hasattr(pc, s)]
if missing:
return False, f"facade 缺失 {len(missing)} 个公开符号: {missing}"
# 类型校验
type_classes = {"RPAError", "LoginTimeoutError", "MissingBrowserError", "TableNotFoundError"}
str_constants = {"PLATFORM_BASE", "PLATFORM_HR_PATH", "PLATFORM_URL",
"ROOT_URL", "SELECT_URL", "SPA_HOME_URL", "SPA_LOGIN_URL"}
for name in expected:
obj = getattr(pc, name)
if name in type_classes:
if not isinstance(obj, type):
return False, f"{name} 不是 type: {obj!r}"
elif name == "_ENV_CACHE":
if not isinstance(obj, dict):
return False, f"{name} 不是 dict: {obj!r}"
elif name == "_ENV_CACHE_LOADED":
if not isinstance(obj, bool):
return False, f"{name} 不是 bool: {obj!r}"
elif name in str_constants:
if not isinstance(obj, str) or not obj:
return False, f"{name} 不是非空 str: {obj!r}"
else:
if not callable(obj):
return False, f"{name} 不可调用: {obj!r}"
# 关键身份校验:re-export 的函数必须是 sub-module 的同一对象(不是 wrapper)
from service.platform_collector_login import (
_try_auto_sign_in as _login_try_auto_sign_in,
_fill_spa_login as _login_fill_spa_login,
)
from service.platform_collector_collect import collect_all as _collect_all
from service.platform_collector_persist import _persist_contracts as _persist_contracts
from service.platform_collector_queue import process_queue as _queue_process_queue
identity_checks = [
("_try_auto_sign_in", _login_try_auto_sign_in),
("_fill_spa_login", _login_fill_spa_login),
("collect_all", _collect_all),
("_persist_contracts", _persist_contracts),
("process_queue", _queue_process_queue),
]
for name, original in identity_checks:
if getattr(pc, name) is not original:
return False, (
f"{name} re-export 不是原对象(sub-module 修改后未同步?)"
)
return True, f"facade 全部 {len(expected)} 个公开符号就位(type/identity 校验通过)"
# ---------- 入口 ----------
def main() -> int:
@@ -2311,6 +2403,7 @@ def main() -> int:
_run("logs_viewer/nonexistent_file", test_logs_viewer_nonexistent_file)
_run("logs_viewer/tail_and_filter", test_logs_viewer_tail_and_filter)
_run("logs_viewer/resolves_relative_path", test_logs_viewer_resolves_relative_path)
_run("facade/reexports_all_symbols_v1_31", test_facade_reexports_all_symbols_v1_31)
total = len(_RESULTS)
passed = sum(1 for _, ok, _ in _RESULTS if ok)