Commit Graph
5 Commits
Author SHA1 Message Date
sloray 6f83ebbe3c ci: 修 Windows job 第二个坑 —— TEMP/TMP 为空,Git Bash 的 mktemp 写不进 <Git>\tmp
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m27s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 12s
构建客户端 / Linux x64(deb + AppImage) (push) Successful in 6m4s
run 4 里 bash 已经换成 Git for Windows(那一步本身就成功了),但 dtolnay/rust-toolchain
还是挂在它的脚本里:

    log=$(mktemp)
    mktemp: failed to create file via template '/tmp/tmp.XXXXXXXXXX': Permission denied

原因:这个 job 的环境里 TEMP/TMP 是空的,而 Git Bash 的 /tmp 是从 TEMP 推出来的;
没有 TEMP,MSYS 就退回 <Git 安装目录>\tmp(C:\Program Files\Git\tmp,实测存在),
那个目录普通权限写不进去 —— mktemp 于是 Permission denied,不是"没目录"也不是
"没权限建文件"那么直白。

本机(就是这台 runner)复现 + 验证:
    清空 TEMP/TMP                -> mktemp: ... Permission denied(与 CI 一字不差)
    TEMP/TMP 指向可写目录        -> mount 显示 "... on /tmp",mktemp 正常
                                    rustup toolchain install / target add 也全过

修法:把 Windows job 里"改 PATH 那一步"扩成同时安排临时目录 —— 在 workspace 的同级
建 ci-tmp,把 TEMP/TMP/TMPDIR 写进 GITHUB_ENV,后续步骤(包括 composite action 内部
的 bash)都用它。
2026-10-15 22:21:36 +08:00
sloray 4667d94c45 ci: 修 Windows job 0 秒失败 —— 宿主 runner 上的 bash 是 WSL,不是 Git Bash
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m7s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 13s
构建客户端 / Linux x64(deb + AppImage) (push) Successful in 6m51s
run 3 里 Windows job 挂在第二步、耗时 0 秒:
    装 Rust(stable)  [failure]  14:01:42 → 14:01:42
    装 pnpm / 装 Node / 前端依赖 / 打包 / 上传产物  [skipped]
日志里是一串被当 UTF-8 解码的 GBK:
    ?b?~? 0   ?Nx?  B a s h / E _ A C C E S S D E N I E D
    ... https://github.com/microsoft/WSL/issues
就是 WSL 的 E_ACCESSDENIED:这台 runner 是宿主直跑,PATH 上的 `bash` 指向
C:\Windows\System32\bash.exe(WSL 启动器),而 WSL 在 runner 账户下起不来。于是
所有 shell: bash 的步骤、以及用 bash 写的 composite action(dtolnay/rust-toolchain
就是),都会在 0 秒内失败。

修法:Windows job 的 checkout 之后插一步(shell: pwsh),把
"C:\Program Files\Git\bin" 写进 GITHUB_PATH —— 它的语义是前置插入,会盖过 System32
那个 WSL 版 bash。本机(就是这台 runner)实测通过:
    bash -> C:\Program Files\Git\bin\bash.exe
    rustup toolchain install stable --profile minimal      exit=0
    rustup target add --toolchain stable x86_64-pc-windows-msvc  exit=0
    rustup run stable rustc --version / cargo --version    exit=0
在仓库根目录跑也一样:根 rust-toolchain.toml 的 `esp` override 不影响这几条命令,
只有裸 rustc/cargo 才会撞上它,而 workflow 里没有这种步骤。

顺带:run 3 里 Linux 那条是好的(检查 2m42s、Linux 9m14s 全绿)。
2026-10-15 22:10:57 +08:00
sloray 76b96cc374 ci: Windows 产物默认就编(平台开关从 vars 换成 inputs)
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 2m42s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 27s
构建客户端 / Linux x64(deb + AppImage) (push) Successful in 9m14s
现象:Windows runner 明明在线、job 也确实派给了 windows-runner-01(它自己的日志:
"Runner labels: windows-latest, windows-2025, windows-2022"),但每次运行里
Windows 产物都是 skipped。

原因在 job 级 if 上:
    (github.event_name != 'workflow_dispatch' && vars.ENABLE_WINDOWS == 'true')
Gitea 的 runner 在 job 级 if 里拿不到(或拿不对)vars 上下文,条件恒为假 —— 而这个
条件写反的代价是"静悄悄不编",不看 runner 日志根本看不出来。同一份文件里
`github.event.inputs.linux != 'false'` 这个形式在 runner 日志里能看到正常求值
(evaluating expression '...' evaluated to 'true'),所以三个平台统一成这种形式:

  Linux / Windows : github.event.inputs.<平台> != 'false'   → 默认跑
  macOS           : github.event.inputs.macos == 'true'     → 默认不跑(还没有机器)

同时把 workflow_dispatch 里 windows 的默认值改成 true,并更新文件头:写清三台
runner 各自声明的标签、为什么不能拿 Linux 交叉编 Windows/macOS、以及第 4 条——
平台开关不要用仓库变量(附上这次的证据)。

runs-on 里的 vars.RUNNER_* 保持不变(标签不匹配时用它们覆盖)。
2026-10-15 21:58:02 +08:00
sloray 03f7279b53 ci: 修两处 Gitea 上跑不了的东西(upload-artifact v4 → v3、去掉缓存)
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m22s
构建客户端 / Linux x64(deb + AppImage) (push) Successful in 7m2s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Skipped
第一次真实运行的日志(job 14)钉出来的两件事:

1. 上传产物那一步一直是失败的:
     GHESNotSupportedError: @actions/artifact v2.0.0+, upload-artifact@v4+
     and download-artifact@v4+ are not currently supported on GHES
   v4 里的 @actions/artifact 会拒绝非 github.com 的服务器。Gitea 实现的是 v3 那套
   接口(ACTIONS_RUNTIME_URL),所以三个平台都换成 upload-artifact@v3,并加一个
   .github/actionlint.yaml 把"v3 太旧"这条 GitHub 规则的误报关掉(原因写在里面)。

   产物路径本身没问题:日志里 tauri build 已经产出 deb/AppImage,v4 在报错之前也
   认出了那批文件("The least common ancestor is .../release/bundle")。

2. 缓存服务在 job 容器里连不上:
     Failed to restore: getCacheEntry failed: connect ETIMEDOUT 172.18.0.2:37315
   setup-node 的 cache: pnpm 每次要干等 4 分 39 秒才放弃,cargo 缓存那步也白等 26 秒。
   先全部去掉(两个 job 每轮省约 10 分钟),文件头第 3 条写明了等缓存修好怎么加回来。

其余在真机上都是绿的:rustup 兜底、pnpm 12.11.2、Node 24.22.0、tsc、vite、
protocol 15 / cam-core 80 / src-tauri 30 个测试、tauri build(deb + AppImage)全过。
2026-10-15 20:49:25 +08:00
sloray 98dc87ec6a ci: 构建客户端 workflow(Windows / Linux / macOS)
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 7m59s
构建客户端 / Linux x64(deb + AppImage) (push) Failing after 10m45s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Skipped
触发:push 到 main(只认 desktop/ 与 protocol/ 的改动)、v* tag、PR、手动。
产物:Linux deb + AppImage、Windows NSIS 安装包、macOS 通用 dmg,各自传 artifact。

几个不是随手写的点:
- 三个平台都显式 --target / CARGO_BUILD_TARGET。desktop/.cargo/config.toml 里钉着
  aarch64-apple-darwin,不覆盖的话 Linux/Windows 的 runner 会去编 macOS 的目标,
  然后在依赖深处以 libc 找不到 MAP_FAILED 这类形式失败。
- protocol 的测试写 cargo +stable:protocol/ 没有自己的 rust-toolchain.toml,会被
  根目录那个 `esp` 接住,而 CI 上没有那个工具链(espup 要下几百 MB)。
- Windows 与 macOS 两个 job 默认不跑(本仓库目前只有 Linux runner),要用仓库变量
  ENABLE_WINDOWS / ENABLE_MACOS 打开;没有 runner 时它们只会一直排队。
- cargo 只缓存 registry、不缓存 target/:容器化的 runner 每次都是干净的,拉几 GB
  的 target 缓存常常比重新编译还慢。
- 守门 job 先跑 tsc + vite build + protocol/core 的单元测试,三个构建都 needs 它。

本地(Windows)实测:同一条 pnpm tauri build --target x86_64-pc-windows-msvc
--bundles nsis 真的编出了 src-tauri/target/x86_64-pc-windows-msvc/release/bundle/
nsis/cam-desktop_0.1.0_x64-setup.exe(2.97 MiB),也验证了 --target 确实盖住了
.cargo/config.toml;protocol 15 个测试、cam-core 80 个测试、tsc、vite build 都过;
三个 Cargo.lock 与 --locked 一致;workflow 本身过 actionlint(带 shellcheck)。
Linux 与 macOS 的打包只能在你们的 runner 上验,第一次跑完把日志贴回来。
2026-10-15 18:41:31 +08:00