ci: 修 Windows job 第二个坑 —— TEMP/TMP 为空,Git Bash 的 mktemp 写不进 <Git>\tmp
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user