ci: 新增 Windows job 与 MySQL service
## Windows 跨平台回归(观察期,不阻塞)
目的:验证 paths.py / process_utils.py 在 win32 上真的可用,而不是"写完就算"。
这两个模块已接线 4 个脚本,一旦 Windows 分支写错,表现是采集器静默不启动
或 PID 检测失效——本地 macOS 上完全看不出来。
**范围有意收窄:不装 akshare**。它传递依赖 py_mini_racer(62MB V8 预编译),
Windows 上是否有 3.12 wheel 未验证,属迁移计划列明的唯一硬阻塞点。
在验证它之前塞进 CI 只会让 job 长期飘红、失去信号价值。
覆盖:check_python_version --strict → compileall → test_paths_process_utils
(32 条,核心)→ Scripts/bin/tests(252 条,此前只在 POSIX 跑过)→ core + client。
continue-on-error: true + 注释写明转正条件(连续两次全绿后删掉)。
首次接跨平台 CI 若直接阻塞,一次环境差异就把主线挡死,反而逼人绕过它。
已提前修掉一处确定会失败的用例:test_newsflash_collect 的 SIGTERM 留痕测试。
Windows 的 send_signal(SIGTERM) 实际走 TerminateProcess,不触发子进程里的
Python handler,断言必然失败。已加 skipif 并注明该能力本身是 POSIX 专属。
## MySQL service(集成测试转阻塞)
python job 增加 services: mysql(mysql:8.0),集成测试成为阻塞性步骤。
三个必须处理的差异:
1. 认证插件:MySQL 8 默认 caching_sha2_password,首次连接走 full path
需 RSA → 装 cryptography,另加 --default-authentication-plugin 双保险
(注意 8.4 起该参数已移除,升镜像需同步改)。
⚠️ 本机某些 venv 没装 cryptography 也能连——那是认证缓存命中 fast path,
不代表 CI 也需要。只看本地结果会误判依赖冗余。
2. 版本:CI 8.0 vs 生产 26.7。事务/回滚语义一致(InnoDB),套件只用
CREATE TABLE + UNIQUE KEY,无版本敏感语法。
3. YAML 的 >- 折叠块内不能写注释:'#' 会被当成内容传给 docker,容器启动即失败。
注释必须置于 options: 之前(已用 assert '#' not in opts 验证)。
两级排除避免重复跑:python job 单元测试步骤与 windows job 均加
--ignore=.../integration。
This commit is contained in:
1 parent
cd076018ba
commit
ad3dbdb9dc
1 file changed
+120
-3
+120
-3
@@ -15,6 +15,29 @@ jobs:
|
||||
python:
|
||||
name: Python 3.12 一致性 / 语法 / 测试
|
||||
runs-on: ubuntu-latest
|
||||
# 真实 MySQL:给 replace 的事务语义做真库验证(fake 游标验不出回滚与半成品)
|
||||
#
|
||||
# 版本差异需知悉:CI 用 MySQL 8.0,生产是 26.7。事务/回滚语义一致(同为 InnoDB),
|
||||
# 但 DDL 默认值与部分语法可能不同。集成套件只用 CREATE TABLE + UNIQUE KEY,
|
||||
# 不含版本敏感语法;若将来要测分区表、生成列等特性,须先在此对齐版本。
|
||||
#
|
||||
# 密码为临时容器专用明文:service container 不暴露到公网,且随 runner 销毁。
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: ci_root_pw_test_only
|
||||
ports:
|
||||
- 3306:3306
|
||||
# 注:--default-authentication-plugin 仅为双保险(配合 cryptography)。
|
||||
# MySQL 8.4 起该参数已移除、改用 --authentication-policy,
|
||||
# 将来升级镜像版本需同步调整,否则容器启动即失败。
|
||||
options: >-
|
||||
--health-cmd="mysqladmin ping -h 127.0.0.1 -uroot -pci_root_pw_test_only"
|
||||
--health-interval=10s
|
||||
--health-timeout=5s
|
||||
--health-retries=12
|
||||
--default-authentication-plugin=mysql_native_password
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -42,7 +65,13 @@ jobs:
|
||||
Services/akshare_fetcher/src
|
||||
|
||||
- name: 安装测试依赖
|
||||
run: python3 -m pip install --quiet pytest pytest-asyncio
|
||||
# cryptography 是 pymysql 走 caching_sha2_password 的 **full path** 认证时
|
||||
# 必需的(需要 RSA 公钥交换)。缺了会报 "cryptography package is required"。
|
||||
#
|
||||
# 注意一个容易误判的现象:本机某些 venv 没装 cryptography 也能连上库——
|
||||
# 那是因为该 MySQL 实例的认证信息已被缓存,握手走了 fast path。
|
||||
# CI 里是**全新容器、首次连接**,必然走 full path,所以这里必须装。
|
||||
run: python3 -m pip install --quiet pytest pytest-asyncio cryptography
|
||||
|
||||
- name: 安装本地包(含各服务)
|
||||
# findatahub-core 不在 PyPI 上,必须先本地安装;
|
||||
@@ -54,15 +83,37 @@ jobs:
|
||||
python3 -m pip install --quiet ./Services/findatahub-client
|
||||
python3 -m pip install --quiet -e ./Services/findatahub-core --no-build-isolation 2>/dev/null || true
|
||||
|
||||
- name: 统一测试入口自检
|
||||
# 只验证解释器探测与套件声明是否可用,不跑测试(成本近乎 0)。
|
||||
# 目的:防止 Scripts/bin/run_all_tests.py 随目录调整悄悄失效——
|
||||
# 脚本腐烂时这里会以退出码 2 明确报错,而不是等到有人在本地踩坑。
|
||||
run: python3 Scripts/bin/run_all_tests.py --list
|
||||
|
||||
- name: 运行单元测试(核心与采集器,纯离线)
|
||||
# 这些用例全部为 mock 驱动、不连库,故设为阻塞性
|
||||
# 这些用例全部为 mock 驱动、不连库,故设为阻塞性。
|
||||
# integration 子目录单独跑(见下一步),此处排除以免重复。
|
||||
run: |
|
||||
python3 -m pytest Services/findatahub-core/tests -q
|
||||
python3 -m pytest Services/findatahub-core/tests -q --ignore=Services/findatahub-core/tests/integration
|
||||
python3 -m pytest Services/findatahub-client/tests -q
|
||||
python3 -m pytest Services/tushare_fetcher/tests/unit -q
|
||||
python3 -m pytest Services/akshare_fetcher/tests -q
|
||||
python3 -m pytest Scripts/bin/tests -q
|
||||
|
||||
- name: 真实库集成测试(replace 事务语义)
|
||||
# 验证 fake 游标验不了的三件事:
|
||||
# 1. 事务是否真的回滚(fake 的 rollback 只是置标志位)
|
||||
# 2. 跨 chunk 失败是否留下「半成品」(fake 不会真提交,永远复现不出来)
|
||||
# 3. 熔断时表是否真的没动
|
||||
# 测试自建 fdh_it_replace_<随机> 空库并 DROP,不碰 service 里的任何现有库。
|
||||
# 曾做证伪:把实现改回「每 chunk 提交」,本套件会报
|
||||
# 「回滚不完整:表内行数既不是旧值」,证明用例有效。
|
||||
env:
|
||||
MYSQL_HOST: 127.0.0.1
|
||||
MYSQL_PORT: "3306"
|
||||
MYSQL_USER: root
|
||||
MYSQL_PASSWORD: ci_root_pw_test_only
|
||||
run: python3 -m pytest Services/findatahub-core/tests/integration -q
|
||||
|
||||
- name: 运行单元测试(kuaixun-service,部分用例可能依赖本机服务)
|
||||
# 该套件含需要 MySQL / Ollama 的用例,暂不阻塞 CI
|
||||
continue-on-error: true
|
||||
@@ -87,3 +138,69 @@ jobs:
|
||||
for f in Scripts/build-app.sh Scripts/bin/*.sh; do
|
||||
bash -n "$f" && echo "ok: $f"
|
||||
done
|
||||
|
||||
# ── Windows 侧:跨平台抽象层回归 ──────────────────────────────
|
||||
#
|
||||
# 目的:验证 `Scripts/bin/paths.py` 与 `process_utils.py` 在 win32 上真的可用,
|
||||
# 而不是"写完就算"。这两个模块已接线 4 个脚本,一旦 Windows 分支写错,
|
||||
# 表现是采集器静默不启动或 PID 检测失效——本地 macOS 上完全看不出来。
|
||||
#
|
||||
# 范围有意收窄:**不装 akshare**。它传递依赖 py_mini_racer(62MB V8 预编译二进制),
|
||||
# Windows 上是否有 3.12 wheel 未验证,属已知硬阻塞点;
|
||||
# 因此 Windows 侧只跑不依赖它的套件。tushare / akshare / backend 待后续单独验证。
|
||||
windows:
|
||||
name: Windows 跨平台回归
|
||||
runs-on: windows-latest
|
||||
# 观察期:首次接入,先不阻塞合并。
|
||||
# 转正条件:连续两次 CI 全绿后删掉这一行,改为阻塞。
|
||||
continue-on-error: true
|
||||
env:
|
||||
# Windows 控制台默认 cp936,中文用例名/日志会乱码甚至抛 UnicodeEncodeError。
|
||||
# 采集器 stdout 是 JSON 状态协议,一旦被编码污染,Swift 端会误判"未运行"。
|
||||
PYTHONUTF8: "1"
|
||||
PYTHONIOENCODING: "utf-8"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version-file: '.python-version'
|
||||
|
||||
- name: 显示版本
|
||||
run: python --version
|
||||
|
||||
- name: 版本一致性检查
|
||||
run: python Scripts/bin/check_python_version.py --strict
|
||||
|
||||
- name: 语法编译检查
|
||||
run: >-
|
||||
python -m compileall -q
|
||||
Scripts/bin
|
||||
Services/findatahub-core/src
|
||||
Services/findatahub-client/src
|
||||
|
||||
- name: 安装依赖
|
||||
# 显式列依赖而不装各服务的 requirements:
|
||||
# 这里要验的是跨平台代码路径,不是完整运行环境。
|
||||
run: |
|
||||
python -m pip install --quiet pytest pytest-asyncio
|
||||
python -m pip install --quiet ./Services/findatahub-core
|
||||
python -m pip install --quiet ./Services/findatahub-client
|
||||
python -m pip install --quiet pymysql httpx pandas sqlalchemy
|
||||
|
||||
- name: 跨平台抽象层测试(本次 Windows 接入的核心)
|
||||
# 32 条用例锁定:paths 的 Windows 分支、process_utils 的
|
||||
# OpenProcess / taskkill / creationflags、UTF-8 环境构造
|
||||
run: python -m pytest Scripts/bin/tests/test_paths_process_utils.py -v
|
||||
|
||||
- name: 脚本层测试
|
||||
# 含 PidManager、DB 池等;这批用例此前只在 POSIX 上跑过,
|
||||
# Windows 上首次运行,暴露的问题正是需要修的
|
||||
run: python -m pytest Scripts/bin/tests -q
|
||||
|
||||
- name: 数据层测试
|
||||
# 排除 integration:Windows job 未接 MySQL service,跑它只会得到一片 skip
|
||||
run: python -m pytest Services/findatahub-core/tests -q --ignore=Services/findatahub-core/tests/integration
|
||||
|
||||
- name: SDK 测试
|
||||
run: python -m pytest Services/findatahub-client/tests -q
|
||||
Reference in new issue
Block a user