fix(packaging): find 在 set -euo pipefail 下致命退出 —— 任何无 electron 缓存的机器都打不出包

## 症状

CI 发布在「打包」步骤失败,输出停在:

    >>> Building GUI directory for linux/amd64...
      npm install...
      electron 版本取自 package.json 依赖声明: 33.0.0(非精确)
    >>> Restoring original go.mod...
    ##[error]Process completed with exit code 1.

没有错误信息,看不出真因。build_go 之前已全部成功(homed 80M 带 onnxruntime)。

## 根因(本地精确复现 + bash -x 追踪)

    + zip=$(find "$HOME/.cache/electron" -name "electron-v33.0.0-linux-x64.zip" | head -1)
    + zip=
    + restore_all          ← 直接退出

脚本是 `set -euo pipefail`。`find` 对**不存在的目录**返回退出码 1,
pipefail 让 pipeline 返回该 1,而 `set -e` 对**赋值语句里的命令替换**同样生效
⇒ 整个脚本当场退出。

实测退出码对照:
    x=$(find /不存在 | head -1)               → 1(脚本死)
    x=$(find /不存在 | head -1 || true)       → 0(存活)
    x=$(find /不存在)                          → 1(无管道也死)

⇒ 任何**没有 ~/.cache/electron 的机器**(全新克隆、CI runner、其他开发机)
都会撞上。本机一直「能打包」只是碰巧有那份 646M 缓存。

## 修法

给 4 处 find 加 `|| true` 兜底(214/217 electron 缓存、623/625 rpm_deb)。
另修 206 行 `[ -n "$ever" ] && echo ...`:`ever` 为空时该列表返回 1,
在 set -e 下同样会杀死脚本 —— 改为 if 形式。

★ 注意 608 行(fpm 查找)**早就有** `|| true`,说明这个模式被意识到过,
只是漏了这几处。属同一类缺陷的补全,不是新引入的写法。

## 验证

- 复现:移走 ~/.cache/electron 后 `package-linux.sh amd64 build` → 修复前 exit=1
  (输出与 CI 逐行一致),修复后 exit=0 且打印明确原因:
  `WARNING: electron binary not found at ... GUI will be skipped.`
- 有 electron 时仍正常构建:GUI 263M / x86-64(走 host-arch 回退路径)
- bash -n 与 shellcheck -S error 均通过
This commit is contained in:
JianFeeeee
2026-09-29 13:59:47 +08:00
parent 472d908862
commit ae53299ad3

View File

@ -203,18 +203,28 @@ spec = (d.get('devDependencies', {}) or {}).get('electron') or (d.get('dependenc
m = re.search(r'(\\d+(?:\\.\\d+)*)', spec)
print(m.group(1) if m else '')
" 2>/dev/null || true)
[ -n "$ever" ] && echo " electron 版本取自 package.json 依赖声明: $ever(非精确)"
if [ -n "$ever" ]; then
echo " electron 版本取自 package.json 依赖声明: $ever(非精确)"
fi
fi
mkdir -p "$gui_out"
# 优先:缓存里的目标架构 zip(~/.cache/electron/<hash>/electron-v<ver>-linux-<arch>.zip)
#
# ★ 这里必须 `|| true`:`find` 对**不存在的目录**返回退出码 1,而本脚本是
# `set -euo pipefail`,命令替换里的失败会让整个脚本当场退出。
# 后果:任何**没有 ~/.cache/electron 的机器**(全新克隆、CI runner、
# 其他开发机)跑到这里就死,且只留下一行「electron 版本取自 package.json」
# 作为最后的输出,看不出真因。实测(2026-09-29,GitHub runner 与本地
# 移走缓存后均复现):build_go 全部成功,然后卡在这里静默退出。
# 本机历史上之所以一直「能打包」,只是因为碰巧有那份缓存。
local zip=""
if [ -n "$ever" ]; then
zip=$(find "$HOME/.cache/electron" -name "electron-v${ever}-linux-${ELECTRON_ARCH}.zip" 2>/dev/null | head -1)
zip=$(find "$HOME/.cache/electron" -name "electron-v${ever}-linux-${ELECTRON_ARCH}.zip" 2>/dev/null | head -1 || true)
fi
if [ -z "$zip" ]; then
zip=$(find "$HOME/.cache/electron" -name "electron-v*-linux-${ELECTRON_ARCH}.zip" 2>/dev/null | head -1)
zip=$(find "$HOME/.cache/electron" -name "electron-v*-linux-${ELECTRON_ARCH}.zip" 2>/dev/null | head -1 || true)
fi
if [ -n "$zip" ]; then
@ -620,9 +630,11 @@ build_rpm() {
if [ ! -f "$rpmbuild_dir/usr/bin/rpmbuild" ]; then
# try to extract from cached deb packages
local rpm_deb
rpm_deb="$(find /tmp -name "rpm_*.deb" -type f 2>/dev/null | head -1)"
# 同 build_gui:`find` 对不存在/无命中会返回 1,`set -euo pipefail` 下
# 会让脚本当场退出(`|| true` 是给命令替换兜底,不是忽视错误)。
rpm_deb="$(find /tmp -name "rpm_*.deb" -type f 2>/dev/null | head -1 || true)"
if [ -z "$rpm_deb" ]; then
rpm_deb="$(find "$PROJECT_ROOT" -name "rpm_*.deb" -type f 2>/dev/null | head -1)"
rpm_deb="$(find "$PROJECT_ROOT" -name "rpm_*.deb" -type f 2>/dev/null | head -1 || true)"
fi
if [ -n "$rpm_deb" ]; then
mkdir -p "$rpmbuild_dir"