Commit 46c14c1
authored
ci: 新增 Windows 10 / 11 双 job(含完整测试段),并修复 mcpp 索引下限导致的全平台 CI 红 (#33)
* ci: 新增 Windows 10 / 11 双 job(含完整测试段),并修复 mcpp 索引下限导致的全平台 CI 红
Windows 10 / 11 两条产品线:
GitHub 托管 runner 没有 Windows 客户端版的 x64 镜像,用共享同一内核基线的
Server 镜像代表——windows-2022(= Win10 22H2,10.0.20348)与 windows-2025
(= Win11 24H2,10.0.26100),并在 job 里打印实际 caption/build 号存证。
两个 job 都跑完整测试段,而不只是「能编过」:
构建 → 版本自检 → 协议一致性 e2e → d2mcpp 真课程 checker 冒烟
checker 冒烟的判据是「能拉起 Provider、拿到练习、报出第一题的编译错误」,
超时被杀(124)是设计内的健康结局——checker 判 fail 后驻留等待文件变更。
为此把 tests/ 的假 Provider 调用改成可移植形式:
- 目录改经位置参数传入,不再用 `FAKE_DIR=... bash ...` 环境变量前缀 ——
Windows 上 d2x 经 _popen 走 cmd.exe 启动 Provider,cmd 没有这种语法。
- 交给 d2x 的路径先经 cygpath -m 转成 C:/... :d2x 是原生 exe,认不得
/tmp/... 这类 MSYS 路径;bash 同样接受该写法,两边通用。
- 活性超时一组在 Windows 跳过:run_lines_idle 在 _WIN32 下显式回退为无超时
运行(见 protocol/src/process.cppm),该平台上没有被测行为可言。
顺带修复一处既有全平台故障(与本次改动无关,但不修则 CI 不可能全绿):
mcpplibs 依赖索引已把 index floor 抬到 0.0.109,原先钉的 mcpp 0.0.104 一律
E0006「index requires mcpp >= 0.0.109」而拒绝解析 compat.ftxui 等依赖 ——
main 上重跑 2026-07-23 那次全绿的 CI,如今五个 job 全红。这里升到索引
latest ref(2026.8.1.1)。d2mcpp 上游同样仍钉 0.0.104,冒烟前先把课程侧的
pin 对齐到同一版本,上游跟进后可移除该步骤。
* ci: Windows checker 冒烟判据对齐到 d2x 的职责边界,并补原始 Provider 诊断
首轮 CI 在两个 Windows job 上红,原因不是 d2x:checker 确实走完了「读配置 →
拉起 Provider → 枚举 52 道练习 → 选中第一题 → 渲染练习页」,日志里
`Exercise: hello-mcpp` / `Status: ❌ failed` 都在;失败的是课程 Provider ——
它在 Windows 上拿不到 `mcpp test --message-format json` 的记录,于是没发
verdict。d2x 随后报「provider did not report a verdict」,这正是协议规定的
行为(tests/e2e.sh 场景 1b 钉的就是「缺 verdict = fail」)。
原判据 `grep -qiE "error"` 是照 linux 的样子写的:那个 error 串来自课程的
真实编译错误,依赖上面那条断掉的上游链路,在 Windows 上不可能出现。
所以把两档判据显式分开,而不是笼统放宽:
- 共通(d2x 自己的职责):hello-mcpp + Exercise: + Status: 三串同时出现,
即「渲染出了第一题」,而不是卡在加载日志上。
- linux 仍是最严的一档:在上面基础上额外要求透出课程编译错误 —— 整条链路
在 linux 上是通的,这条不能松。
- Windows 暂不要求后者,并在注释里写明这是 mcpp / d2mcpp 的上游缺口、上游
补齐后应收紧到与 linux 一致。
另加一步 Provider check 原始 NDJSON 诊断(continue-on-error),把上游那条
链路的原始输出摆进日志,便于定位,也让日后的回归有据可查。
* fix: normalize_path 在 Windows 上留下前导分隔符,练习页显示成 "\src\...\x.cpp"
Win10 / Win11 CI 实测暴露:练习页的 File: 一行在 Windows 上显示成
`\src\intro\tests\hello-mcpp.cpp` —— 多了个前导分隔符;linux 上是正确的
`src/intro/tests/hello-mcpp.cpp`。
根因是 normalize_path 手写的「前缀匹配 + 掐掉一个 '/'」:
if (!path.empty() && path.front() == '/') path.erase(path.begin());
只认 '/'。Windows 的分隔符是 '\',掐不掉,于是相对化之后前导分隔符留在原地。
(相对化本身是有意的行为,不是 bug;坏的只是这个分隔符。)
改为交给 std::filesystem::path::lexically_relative:分隔符、".." 情形都由标准
库负责,不再手写字符比较。纯词法运算,不碰文件系统 —— 路径来自 Provider,
未必存在于本机。压不出相对关系、或落在 cwd 之外时原样返回,与原行为一致。
输出统一走 generic_string()(正斜杠):课程与文档都以正斜杠书写路径,两个平台
显示一致也便于断言。
回归测试(tests/e2e.sh 场景 5):Provider 报的是绝对路径而 checker 的 cwd 就是
该目录,所以展示路径必须被压成相对形式、任何情况下都不该以分隔符打头。断言拆成
两条(含 ex1.txt / 不以分隔符打头)—— 起初写成单条正则
`^File: +[^\\/].*ex1\.txt`,但 ` +` 会回溯让字符组吃掉一个空格,四种输入全部
放行;实测发现后改掉。该断言在 linux 上恒真(linux 本就没这个 bug),真正的
把关发生在 Windows CI。
* feat: 补上 Windows 的活性超时(Job Object 终止整棵进程树),e2e 五组三平台全跑
run_lines_idle 此前在 _WIN32 下显式回退为「无超时运行」:Windows 上挂死的
Provider 不会被终止,checker 跟着一起等下去。tests/e2e.sh 的活性超时一组也
因此在 Windows 跳过 —— 该平台等于没有这条保护。
实现要点(protocol/src/process.cppm):
- 不用 _popen:拿不到进程句柄,超时了无从终止。改 CreateProcess 起 cmd.exe。
- Job Object + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE:Windows 上终止整棵进程树
的正规手段,语义对应 POSIX 分支的 kill(-pid)。Provider 常有孙进程
(mcpp → 编译器),只杀直接子进程会留孤儿继续占用产物目录。
- CREATE_SUSPENDED:先挂起、纳入 Job、再 ResumeThread。否则子进程可能在被
纳管之前就派生出逃逸在 Job 之外的孙进程。
- 读端 SetHandleInformation 去掉继承,且父进程立刻关掉自己那份写端 ——
否则管道永远多一个写者,读不到 EOF。
- 全程 PeekNamedPipe 探量再 ReadFile,绝不裸调 ReadFile:管道读是阻塞的,
挂死的 Provider 会把轮询线程一起拖住,活性判定就永远轮不到。
- AssignProcessToJobObject 失败时退化为只杀直接子进程,而不是放弃超时 ——
至少 d2x 自己不会跟着挂死。
tests/e2e.sh 去掉 Windows 的跳过分支,五组协议测试三平台同跑。hang 模式下
Provider 是 cmd.exe → bash → sleep 300 的一棵树,正好验证「杀整棵」:只杀
直接子进程的话 sleep 会活下来,20s 窗口内同样出不了 verdict。
linux 侧行为未变(#else 分支原样保留),本地 e2e 五组 ALL GREEN;Windows 侧
由 Win10 / Win11 CI 实测。1 parent dc978bf commit 46c14c1
6 files changed
Lines changed: 293 additions & 24 deletions
File tree
- .github/workflows
- protocol/src
- src
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
11 | 15 | | |
12 | 16 | | |
13 | 17 | | |
| |||
82 | 86 | | |
83 | 87 | | |
84 | 88 | | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
85 | 99 | | |
86 | | - | |
87 | | - | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
88 | 110 | | |
89 | 111 | | |
90 | 112 | | |
| |||
94 | 116 | | |
95 | 117 | | |
96 | 118 | | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
97 | 125 | | |
98 | 126 | | |
99 | 127 | | |
| |||
104 | 132 | | |
105 | 133 | | |
106 | 134 | | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
107 | 215 | | |
108 | 216 | | |
109 | 217 | | |
| |||
135 | 243 | | |
136 | 244 | | |
137 | 245 | | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
138 | 251 | | |
139 | 252 | | |
140 | 253 | | |
| |||
164 | 277 | | |
165 | 278 | | |
166 | 279 | | |
167 | | - | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
168 | 287 | | |
169 | 288 | | |
170 | 289 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
15 | 19 | | |
16 | 20 | | |
17 | 21 | | |
| |||
77 | 81 | | |
78 | 82 | | |
79 | 83 | | |
80 | | - | |
| 84 | + | |
81 | 85 | | |
82 | 86 | | |
83 | | - | |
84 | | - | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
85 | 90 | | |
86 | 91 | | |
87 | 92 | | |
88 | 93 | | |
89 | 94 | | |
90 | | - | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
91 | 202 | | |
92 | 203 | | |
93 | 204 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
8 | 18 | | |
9 | 19 | | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
19 | 31 | | |
20 | 32 | | |
21 | 33 | | |
| |||
0 commit comments