Files
MailUI4Agents/client/electron/scripts/release-linux.sh
JianFeeeee 317f3265e3 fix(判据): 探针三值 + 发布候选标签 —— 顺带查出探针从写下那天起一次都没跑成过
pi 的两条"真实的洞",都落了,而且第一条当场抓到实证。

1. **探针三值**(可用 / 不可用 / 拿不准→红):`RESULT static=5 probe=ok|unknown`
   把"欠账余额"和"探针是否健康"拆成两个数字。
   **换完第一次运行就报 probe=unknown** —— 一查:探针调的是 `execFileSync`,
   而这个文件 import 的是 `spawnSync`,**名字根本没定义**。也就是说
   **探针从写下的那天起一次都没跑成过**,旧的两值设计把 `ReferenceError`
   和"没有设备"一起吞掉、统一报成"设备不可用":机制在、闸门从没开过,
   而它看起来完全健康。这正是 pi 描述的"恒不开闸",只是比预想更彻底。
   现在:命令在但跑不成 → unknown → 红;所有候选都不存在(本机没装 hdc)→ 可判的
   "没有设备工具" → false,避免没装 SDK 的机器天天假红。
   附 `--probe-selftest`(只跑分类器,不跑套件)+ 变异验证(把 unknown 当"不成立"→ 红)。

2. **releaseCandidate = !gitDirty**(从展示升成标签):BUILD_INFO 现在自报
   `releaseCandidate`,发布脚本在脏树时会打印"这个包不是发布候选"。
   判据 `build-stamp` 断言"标签与 gitDirty 必须一致"。
   **实证**:本轮我打的包正是这种情况 —— `gitDirty: true`(含着 gui-lab 未提交的
   NarrowStack/index.css),`releaseCandidate: false`,日志里明确说了"不是发布候选"。

3. 附带:`criteria-hygiene` 加一条"用到 `code/prose/bytes` 就必须真的 import"。
   理由是同一形状我这轮在三个文件里各犯过一次(最后一次是 `execFileSync`/`spawnSync`),
   而它表现为"判据红了"(ReferenceError 抛在判据自己身上),看起来像判据失败、
   不像判据写错。这条至少把最常写错的那几个名字变成明确的红。
2026-09-14 16:35:40 +08:00

53 lines
2.7 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
#
# 发布 Linux 包:**构建成功才打包**。
#
# 为什么要有这个脚本(而不是在命令行里手打两步):
# `npm run build 2>&1 | tail -4 && electron-builder …` 这种写法里,
# pipeline 的退出码取的是**最后一个命令**`tail`)的 —— 构建失败、`&&` 照走、
# 打包器拿**旧的 dist** 打了个新包,而所有判据都是绿的
# vitest 绿、packaging 绿:它比的是 dist 与包,两边都是旧的,自然一致)。
# 那是真实发生过的一次(见 test/build-stamp.test.mjs 与计划文档 §7.20)。
#
# 两道门,互不替代:
# - `set -euo pipefail` + 顺序调用:**构建失败就不打包**(喂退出码,真正的门);
# - `dist` 比 `src` 新那条判据:**探测器**,抓"src 改了而产物没跟上"。
# 注意它抓不到"构建失败但已经碰过 dist"—— 实测过,那种情况它是绿的。
#
# 构建只有一条路:走 `npm run build`= `gen:bg` + `vite build`)。
# 这里原来写的是裸 `vite build`,那会**跳过 gen:bg**(背景接管用的 CSS 生成步骤),
# 于是生成物缺失/过期时打包器照打不误。
#
# 两个环境变量是给判据用的接缝test/packaging.test.mjs 会注入一个失败的构建,
# 断言它**真的会停下**且不进入打包):
# AGENTMAIL_BUILD_CMD / AGENTMAIL_PACK_CMD
set -euo pipefail
BUILD_CMD="${AGENTMAIL_BUILD_CMD:-npm run build}"
PACK_CMD="${AGENTMAIL_PACK_CMD:-npx electron-builder --linux -c.electronDownload.isVerifyChecksum=false}"
mkdir -p .tmp
export TMPDIR="${TMPDIR:-$PWD/.tmp/${DSH_SESSION_ID:-$(id -un)-$$}}"
mkdir -p "$TMPDIR"
echo "[release] 构建:$BUILD_CMD"
bash -c "$BUILD_CMD"
echo "[release] 打包:$PACK_CMD"
bash -c "$PACK_CMD"
# 产物自报来源:把 BUILD_INFO 打进日志pi 提的"一个包要自带它对应哪个源码状态")。
# 出问题时先看这几行:包是在哪个提交、哪份源码指纹上构建的,以及当时树干不干净。
if [[ -f dist/BUILD_INFO.json ]]; then
# "脏树打的包"必须**看得见**pi §1共享树上脏是常态所以不做成红
# 但要在日志里明说这个包不是发布候选(含别人未提交的半成品时不能给人装)。
if grep -q '"releaseCandidate": *false' dist/BUILD_INFO.json 2>/dev/null; then
echo "[release] ⚠ 这个包不是发布候选releaseCandidate=false构建时工作树是脏的。"
fi
echo "[release] 产物来源:$(cat dist/BUILD_INFO.json | tr -d '\n' | sed 's/ */ /g')"
else
echo "[release] 警告dist/BUILD_INFO.json 不存在 —— 构建没走 npm run build判据会红" >&2
fi
echo "[release] 完成dist 与安装包同批(这一句只在两步都成功后才出现)"