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)都用它。
This commit is contained in:
2026-10-15 22:21:36 +08:00
parent 4667d94c45
commit 6f83ebbe3c
+23 -7
View File
@@ -343,20 +343,36 @@ jobs:
# (dtolnay/rust-toolchain 就是),都会在 0 秒内失败。
# Git for Windows 自带 bash,把它的 bin 前置到 PATH —— GITHUB_PATH 的语义就是
# **前置**插入,所以它会盖过 System32 那个 —— 后面这些步骤才跑得起来。
# 2026-10-15 第一次真跑 Windows job 时踩出来的(本地这样改完,dtolnay 要跑的
# rustup toolchain install / target add / rustc / cargo 全部 exit 0)。
- name: 让 bash 指向 Git for Windows(不是 WSL)
#
# 换掉 bash 之后还有第二个坑:这个 job 的环境里 TEMP/TMP 是空的,而 Git Bash 的
# /tmp 是从 TEMP 推出来的;没有 TEMP 它会退回 <Git 安装目录>\tmp
# (C:\Program Files\Git\tmp),那个目录普通权限写不进去,于是 dtolnay 里那句
# log=$(mktemp) 直接挂掉:
# mktemp: failed to create file via template '/tmp/tmp.XXXXXXXXXX': Permission denied
# 所以顺手给 job 指定一个自己建的可写目录(workspace 的同级 ci-tmp)。
# 两个坑都是 2026-10-15 真跑 Windows job 时踩出来的,本地按这样改完后
# mktemp、rustup toolchain install、rustup target add 全部正常。
- name: 让 bash 指向 Git for Windows,并给 job 一个可写的临时目录
shell: pwsh
run: |
if (-not $env:GITHUB_PATH) { throw '这个 runner 没提供 GITHUB_PATH,没法给后续步骤改 PATH' }
if (-not $env:GITHUB_ENV) { throw '这个 runner 没提供 GITHUB_ENV,没法给后续步骤加变量' }
if (-not $env:GITHUB_WORKSPACE) { throw '这个 runner 没提供 GITHUB_WORKSPACE' }
$gitBash = 'C:\Program Files\Git\bin'
if (-not $env:GITHUB_PATH) {
throw '这个 runner 没提供 GITHUB_PATH,没法给后续步骤改 PATH'
}
if (-not (Test-Path (Join-Path $gitBash 'bash.exe'))) {
throw "找不到 $gitBash\bash.exe:这台机器上没装 Git for Windows,bash 会落到 WSL 上"
}
Add-Content -Path $env:GITHUB_PATH -Value $gitBash -Encoding ascii
"后续步骤的 bash = $(Join-Path $gitBash 'bash.exe')"
$tmpRoot = Join-Path (Split-Path -Parent $env:GITHUB_WORKSPACE) 'ci-tmp'
New-Item -ItemType Directory -Force -Path $tmpRoot | Out-Null
Add-Content -Path $env:GITHUB_ENV -Value "TEMP=$tmpRoot" -Encoding ascii
Add-Content -Path $env:GITHUB_ENV -Value "TMP=$tmpRoot" -Encoding ascii
Add-Content -Path $env:GITHUB_ENV -Value "TMPDIR=$($tmpRoot -replace '\\', '/')" -Encoding ascii
"bash = $(Join-Path $gitBash 'bash.exe')"
"TEMP/TMP/TMPDIR = $tmpRoot"
- name: 装 Rust(stable)
uses: dtolnay/rust-toolchain@stable