动机
main 的 CI 矩阵在 macos/windows 仍有两簇恒红(ubuntu 已由 #23 转绿):①cli.test.mjs 用例 20(TTY)断言 stderr 含中文「命令一览」,但语言链 locale 探测 > zh 在 en-US runner 上渲染英文——PR #10 引入的 locale 依赖,本地中文机掩盖;已用 SHADOW_DEV_LANG=en 本地复现同款断言失败。②install.test.mjs 全部用例在 windows runner 死于 makeTarball:node 直接 spawn 的 tar 绑到 System32 bsdtar,读不了 toUnix 产出的 MSYS /tmp 路径(38b1364 起即存在)。两簇都是测试侧缺陷,运行时行为正确。红 CI 继续让真实回归裸奔。
引用规范
- shadow-docs/knowledge/cli-output-contract.md
- 当前结论: 语言链
--lang > SHADOW_DEV_LANG > locale 探测 > 默认 zh,只影响 stderr 文案
- 适用 scope: 测试必须显式固定语言(--lang / SHADOW_DEV_LANG),不得依赖 runner locale
- shadow-docs/knowledge/install-distribution.md
- 当前结论: shim/产物断言是平台分支的;跨平台命令要在设计上可移植
- 适用 scope: test/install.test.mjs
- norms/tdd-verification.md
- 当前结论: 先复现红(本地 SHADOW_DEV_LANG=en 已复现 ①;②的权威红源是 windows CI 矩阵)再修
决策
- 选型: ①用例 20 的
runTty(['--help']) 显式传 SHADOW_DEV_LANG=zh(断言中文通道);②makeTarball 的 tar 改在 bash 内执行(bash -c "tar ..."),与安装器本体同源(install-cli.sh 里 tar 天然由 bash 解析,Windows 下命中 git 的 GNU tar),测试与实现走同一条解析路径。
- 对比方案: ①改成"按 locale 断言中英文任一"被否——非确定性断言是反模式;②toUnix 产 Windows 原生路径给 bsdtar 被否——
-C 参数与包内 POSIX 路径又需要 MSYS 形态,两头不讨好;根治是统一交给 bash 解析。
- 理由: 测试向契约要确定性:语言显式声明、工具链与生产路径一致;均不动运行时代码。
任务
Phase 1
Phase 2
完整 brief:shadow-docs/changes/20260918-fix-cross-platform-ci/brief.md
动机
main 的 CI 矩阵在 macos/windows 仍有两簇恒红(ubuntu 已由 #23 转绿):①
cli.test.mjs用例 20(TTY)断言 stderr 含中文「命令一览」,但语言链locale 探测 > zh在 en-US runner 上渲染英文——PR #10 引入的 locale 依赖,本地中文机掩盖;已用SHADOW_DEV_LANG=en本地复现同款断言失败。②install.test.mjs全部用例在 windows runner 死于makeTarball:node 直接 spawn 的tar绑到 System32 bsdtar,读不了 toUnix 产出的 MSYS/tmp路径(38b1364 起即存在)。两簇都是测试侧缺陷,运行时行为正确。红 CI 继续让真实回归裸奔。引用规范
--lang>SHADOW_DEV_LANG> locale 探测 > 默认 zh,只影响 stderr 文案决策
runTty(['--help'])显式传SHADOW_DEV_LANG=zh(断言中文通道);②makeTarball的 tar 改在 bash 内执行(bash -c "tar ..."),与安装器本体同源(install-cli.sh 里 tar 天然由 bash 解析,Windows 下命中 git 的 GNU tar),测试与实现走同一条解析路径。-C参数与包内 POSIX 路径又需要 MSYS 形态,两头不讨好;根治是统一交给 bash 解析。任务
Phase 1
test/cli.test.mjs— 用例 20 的 plain(无 --json 的 TTY help)runTty 显式SHADOW_DEV_LANG=zh;本地SHADOW_DEV_LANG=en强制下先跑红(已复现)后转绿test/install.test.mjs—makeTarball的spawnSync('tar',...)改为spawnSync('bash', ['-c', ...]);本地 8 用例保持绿Phase 2
完整 brief:shadow-docs/changes/20260918-fix-cross-platform-ci/brief.md