sloray
|
e6070f91ee
|
ci: Windows 改用 npm 装的 JS 版 pnpm(standalone 二进制在低完整性沙箱里必崩)
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m9s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 22s
构建客户端 / Linux x64(deb + AppImage) (push) Canceled after 1m14s
|
2026-10-15 23:27:06 +08:00 |
|
sloray
|
26731958ea
|
ci: Windows 的 pnpm install 加 corepack 退路(standalone 在低完整性沙箱里栈溢出)
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m10s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 40s
构建客户端 / Linux x64(deb + AppImage) (push) Canceled after 1m37s
|
2026-10-15 23:24:13 +08:00 |
|
sloray
|
de7263569c
|
ci: Windows 的 pnpm 安装目录改成每次运行都干净的路径
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m11s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 28s
构建客户端 / Linux x64(deb + AppImage) (push) Canceled after 1m36s
run 13 里 装 Rust 这次是好的(上次那个 panic 是两轮运行重叠、同时写 ci-rustup 造成的),
但 装 pnpm 挂了:
[Error: ENOTEMPTY: directory not empty, rmdir
'C:\Users\admin\runner\windows\cache\ci-pnpm\node_modules\.bin\store\v11\projects']
原因是这个 dest 是固定路径:pnpm 把自己算出来的 store 建在 dest 里面(就是之前日志里
那个很怪的 <dest>\node_modules\.bin\store\v11),下一轮 action 的自安装器要清掉旧目录
时,嵌套的 store\v11\projects 非空,rmdir 就失败了。
改成 ${{ github.workspace }}\..\ci-pnpm —— 落在本次运行的 work 目录里,每次都是干净的,
同时也还满足"低完整性只能写 runner 自己的工作目录"。机器上那个被污染的
cache\ci-pnpm 已经删掉。
|
2026-10-15 23:21:16 +08:00 |
|
sloray
|
c9ce7b64ef
|
ci: 删掉两段临时诊断(Windows 的坑已经查清并写进文件头第 5 条)
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m13s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 17s
构建客户端 / Linux x64(deb + AppImage) (push) Canceled after 1m1s
|
2026-10-15 23:18:53 +08:00 |
|
sloray
|
f3b09ca9a6
|
ci: Windows 的 pnpm 那步写死 shell: pwsh(免得 actionlint 拿 bash 规则挑反斜杠路径)
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m9s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 19s
构建客户端 / Linux x64(deb + AppImage) (push) Canceled after 2m1s
|
2026-10-15 23:15:36 +08:00 |
|
sloray
|
1cccc1aa00
|
ci: Windows job 给 pnpm install 明确指定 store 与导入方式
构建客户端 / 检查(类型 + 单元测试) (push) Canceled after 6s
构建客户端 / Linux x64(deb + AppImage) (push) Canceled after 0s
构建客户端 / Windows x64(NSIS 安装包) (push) Canceled after 0s
构建客户端 / macOS 通用(.app + .dmg) (push) Canceled after 0s
run 10 已经过了 store 操作锁那一关(pnpm 开始下载包了),但接着崩了:
Downloading @tauri-apps/cli-win32-x64-msvc@2.12.2: 0.00 B/7.98 MB
Content-addressable store is at:
C:\Users\admin\runner\windows\cache\ci-pnpm\node_modules\.bin\store\v11
thread '<unknown>' (6500) has overflowed its stack
##[error]Process completed with exit code 1.
两个可疑点:一是 pnpm 自己算出来的 store 路径很怪(挂在 pnpm 安装目录的
node_modules\.bin 下面,而且我在 env 里设的 npm_config_store_dir 它压根没用);
二是硬链接导入。所以这一步直接给 CLI 参数:显式短路径 store、copy 导入(不走硬链接)、
append-only 输出(默认 reporter 在 CI 日志里全是重画)。
|
2026-10-15 23:15:20 +08:00 |
|
sloray
|
f0538fa233
|
ci: Windows job 加 USERPROFILE 重定向 —— pnpm 的操作锁按它算路径
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m9s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 33s
构建客户端 / Linux x64(deb + AppImage) (push) Successful in 6m4s
run 9 的诊断2 已经把话说死了:
LOCALAPPDATA = C:\Users\admin\runner\windows\cache\ci-localappdata <- 重定向生效
OK ...\ci-localappdata\pnpm-store-operation-locks <- 目录能建
Error: ERR_PNPM_STORE_DIR_OPEN_OPERATION_LOCK
Failed to open the store operation lock at
"C:\Users\admin\AppData\Local\pnpm-store-operation-locks\all-stores.lock"
也就是说 LOCALAPPDATA 指走了,pnpm 还是去开原来那个路径。本机复现出真正的规则:
只改 USERPROFILE(LOCALAPPDATA 不动)、store 换成一个全新的空目录时,
<新 USERPROFILE>\AppData\Local\pnpm-store-operation-locks\all-stores.lock
<新 USERPROFILE>\AppData\Local\pnpm-store-operation-locks\<hash>.lock
立刻出现 —— pnpm 是按 <USERPROFILE>\AppData\Local 算的,跟 LOCALAPPDATA 无关。
所以在那一步里再建一个 ci-profile,把 AppData\Local / AppData\Roaming 先建好,然后
把 USERPROFILE 写进 GITHUB_ENV。文件头第 5 条同步更新。
|
2026-10-15 23:06:35 +08:00 |
|
sloray
|
47ef7c63dd
|
ci(diag): 再探一次 —— pnpm 眼里的目录到底是哪个
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m15s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 23s
构建客户端 / Linux x64(deb + AppImage) (push) Canceled after 2m38s
run 8 里 LOCALAPPDATA 已经在 job env 里指向 ci-localappdata,但 pnpm 仍然去开
C:\Users\admin\AppData\Local\pnpm-store-operation-locks\all-stores.lock(拒绝访问)。
所以要么这个变量没进到那一步,要么 pnpm 不是从环境变量推这个路径。加一步(在装完
pnpm 之后、装依赖之前)把它问清楚:LOCALAPPDATA/APPDATA 的实际值、pnpm 的路径与版本、
pnpm config list 的输出,以及"两个候选锁目录能不能建"。查完删。
|
2026-10-15 23:02:12 +08:00 |
|
sloray
|
b74c6654e5
|
ci: Windows job 再加 LOCALAPPDATA/APPDATA 重定向(pnpm 的 store 锁挂在这里)
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m7s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 22s
构建客户端 / Linux x64(deb + AppImage) (push) Successful in 5m54s
run 7 的 Windows job 已经过了 rustup / pnpm / node 三步 —— 低完整性那套重定向起效了
(诊断输出确认:RUSTUP_HOME / CARGO_HOME / RUNNER_TOOL_CACHE / npm_config_* 都指到了
runner 自己的工作目录)。新的失败在"前端依赖":
pnpm install --frozen-lockfile
... pnpm-store-operation-locks\all-stores.lock": 拒绝访问。(os error 5)
pnpm 12 的 store 操作锁与 cache/state 不在 store-dir 下面,而是挂在 %LOCALAPPDATA%
(本机实测:把 LOCALAPPDATA 指到别的目录后,pnpm 会在那里建 pnpm-cache / pnpm-state,
install 正常退出)。所以 job env 里再加两条:
LOCALAPPDATA: C:\Users\admin\runner\windows\cache\ci-localappdata
APPDATA: C:\Users\admin\runner\windows\cache\ci-appdata
顺带覆盖到 tauri 打包时下载 NSIS 的缓存目录(它也在 LOCALAPPDATA 下)。
|
2026-10-15 22:52:46 +08:00 |
|
sloray
|
ac3d639d6b
|
ci: Windows job 低完整性适配 —— 把 CI 的"家目录"挪到 runner 自己的工作目录
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m12s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 57s
构建客户端 / Linux x64(deb + AppImage) (push) Successful in 6m5s
诊断步骤(在 job 里跑的写探测)给出了确定答案:
whoami = timi\admin
integrity = Mandatory Label\Low Mandatory Level S-1-16-4096 <-- 低完整性
FAIL: C:\Users\admin\.rustup\tmp\probe.txt Access denied
FAIL: C:\Users\admin\.cargo\probe.txt Access denied
FAIL: C:\Users\admin\.cargo\registry\probe.txt Access denied
OK : C:\Users\admin\runner\windows
OK : C:\Users\admin\runner\windows\cache
OK : <work>\ci-probe
不是 ACL 问题(SYSTEM / Administrators / timi\admin 全 F,没有 Deny),是 Windows 的
"低完整性不能写中完整性"。同一个账户在交互式会话(Medium,实测 S-1-16-8192)里往
~/.rustup、~/.cargo 写得进去,job 里就全被拒。于是前面几个看起来毫不相干的错误都是
同一个原因:Git Bash /tmp 被拒(TEMP 不可写时它退回 <Git>\tmp)、rustup 建不了临时
文件。%TEMP%、%LOCALAPPDATA% 也一样中招。
处置(Windows job 内):
* env 增加 RUSTUP_HOME / CARGO_HOME / npm_config_cache / npm_config_store_dir /
RUNNER_TOOL_CACHE,全部指向 C:\Users\admin\runner\windows\cache\ci-*(探测过可写)
* pnpm/action-setup 的 dest 从默认 ~/setup-pnpm 改到同一个 cache 下
* TEMP/TMP/TMPDIR 上一版已经指到 workspace 同级的 ci-tmp
文件头第 5 条写清了这个坑、表现、以及从根上的解法(让 gitea-runner 以中完整性启动)。
临时诊断步骤暂时保留,等 Windows 真编出包来再删。
|
2026-10-15 22:44:05 +08:00 |
|
sloray
|
2ed16ff88d
|
ci(diag): 在 Windows job 里加一段临时诊断(查完删)
构建客户端 / 检查(类型 + 单元测试) (push) Successful in 1m8s
构建客户端 / macOS 通用(.app + .dmg) (push) Skipped
构建客户端 / Windows x64(NSIS 安装包) (push) Failing after 13s
构建客户端 / Linux x64(deb + AppImage) (push) Successful in 6m7s
run 5 里 bash 那两个坑都过去了,卡在第三处:rustup 建临时文件被拒
error: could not create temp file C:\Users\admin\.rustup\tmp\ajq4dt9h0_e7oonj_file
拒绝访问。 (os error 5)
同一个账户在这个交互式会话里能往那个目录写、ACL 也是正常的(SYSTEM/Administrators/
TIMI\admin 全 F,没有 Deny)。runner 进程属主是 TIMI\admin,计划任务 GiteaRunner-Windows
是 admin / Limited(非提权)。所以差异只在 job 内部的令牌/完整性级别上 —— 让 job 自己
报:whoami、Mandatory Label、TEMP/TMP、RUSTUP_HOME/CARGO_HOME,并对 6 个候选目录逐个
做"建目录 + 写文件 + 删文件"探测。这是临时步骤,拿到结论就删。
|
2026-10-15 22:31:56 +08:00 |
|
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 |
|