Files
MailUI4Agents/plugins/homeagent-mail-bridge/build.sh
JianFeeeee 357662ed08 fix(homeagent): 不再把 SDK 版本钉在源码里;构建期按内核的依赖表校验对齐
崩溃循环的根因不是"忘了重编",是**把 SDK 版本钉死**:

- `plugin.json`/`plg.json` 写死 `"sdk": "1.3.0"`(本机已装 21 个插件里只有 3 个声明该字段);
- `go.mod` 的 replace 指向 `/root/.homeagent/hmapdev/sdk/v1.3.0`(绝对路径 + 具体版本目录)。

于是"照原样重编"只会再造一个装上去就崩的包。实测本机内核链的是**另一条 SDK 血脉**:

    $ go version -m /usr/local/bin/homed
    dep gitcode.com/JianFeeeee/homeagent-sdk v0.9.2
    =>  ./third_party/homeagent-sdk (devel)

所以判据改成**两个二进制的依赖表一致**,而不是"版本号看起来像":

- `build.sh`:读内核的 SDK 依赖(`go version -m`)→ 据此解析 SDK 源码目录 →
  用 `-modfile` 临时替换(不改动受版本管理的 go.mod)→ 构建 → **回头验产物**:
  产物与内核链的 SDK 版本不一致就报错退出,绝不产出"装上去就崩"的包。
- `manifest_sdk_test.go`:① 清单不许写死 `sdk`;② go.mod 的钉子不得偏离构建机指针
  (取不到基准就红,不许默默放过);③ `build.sh` 必须在(它是与内核对齐的硬校验点)。
  三条都做过变异验证(写死 sdk / 钉子漂到 v1.2.0 / 删掉 build.sh → 各自红)。

顺带查出一个比"重编"更根本的事实:本机 `build.sh` 跑到编译就失败 ——

    ./plugin.go:217:18: sett.DataDir undefined (type sdk.SettingsAPI has no field or method DataDir)

即本插件源码用的是 **1.3.0 SDK 的 API**,而本机内核链的是 0.9.x 血脉:**重编解决不了**,
要么内核改成链 1.3.x 的 SDK,要么把插件移植到内核那份 SDK(这是 HomeAgent 侧的决定)。
2026-09-14 16:27:02 +08:00

83 lines
4.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
# 构建 homeagent-mail-bridge —— 必须与**内核链在同一个 SDK 上**,构建前后都校验。
#
# # 为什么2026-09-14 事故 + 当天复发 + 今天查出的真根因)
#
# · 08:09 事故:内核升级,插件二进制还是旧 SDK 编的 → 启动即 SIGSEGV握手失败
# 5 分钟内崩 4 次后熔断「停止自动重启,需人工介入」;
# · 当天处置:重编成 0.2.2 / sdk=1.3.0
# · 现在又崩:`go version -m /usr/local/bin/homed` 显示**本机内核**链的是
# dep gitcode.com/JianFeeeee/homeagent-sdk v0.9.2
# => ./third_party/homeagent-sdk (devel)
# 而插件 go.mod 钉的是 `/root/.homeagent/hmapdev/sdk/v1.3.0` ——
# **两条完全不同的 SDK 血脉**。所以"照原样重编"不但没用,还必然再造一个崩的包。
#
# 结论:判据不该是"版本号看起来一样",而该是**两个二进制的依赖表一样**。
# 这个脚本就用 `go version -m` 把内核的 SDK 依赖读出来,按它构建,再回头验产物。
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
KERNEL_BIN="${HOMEAGENT_KERNEL_BIN:-/usr/local/bin/homed}"
SDK_MODULE="gitcode.com/JianFeeeee/homeagent-sdk"
die() { echo "构建失败:$*" >&2; exit 1; }
# cron/非登录 shell 里 HOME 可能没设Go 会因此拒绝工作(曾经在这里栽过)
export HOME="${HOME:-/root}"
export GOPATH="${GOPATH:-$HOME/go}"
export GOCACHE="${GOCACHE:-${TMPDIR:-/tmp}/go-build-agentmail}"
mkdir -p "$GOCACHE"
[[ -x "$KERNEL_BIN" ]] || die "找不到内核二进制 $KERNEL_BIN(用 HOMEAGENT_KERNEL_BIN 指定)"
# ── 1. 读内核链的 SDK模块版本 + 本地替换目录 ──────────────────────
KERNEL_INFO="$(go version -m "$KERNEL_BIN" 2>/dev/null)" || die "读不出 $KERNEL_BIN 的构建信息go version -m"
KERNEL_SDK_VER="$(awk -v m="$SDK_MODULE" '$1=="dep" && $2==m {print $3}' <<<"$KERNEL_INFO" | head -1)"
KERNEL_SDK_PATH="$(awk -v m="$SDK_MODULE" '/^[[:space:]]*=>/ {print $2}' <<<"$KERNEL_INFO" | head -1)"
[[ -n "$KERNEL_SDK_VER" ]] || die "内核没有链 $SDK_MODULE —— 这不对,先人工看一眼"
echo "[build] 内核 $KERNEL_BIN 链的 SDK${KERNEL_SDK_VER}${KERNEL_SDK_PATH:+(替换目录 $KERNEL_SDK_PATH}"
# ── 2. 找到内核用的那份 SDK 源码 ───────────────────────────────────
SDK_DIR="${HOMEAGENT_SDK_DIR:-}"
if [[ -z "$SDK_DIR" && -n "$KERNEL_SDK_PATH" ]]; then
# 内核里的路径是**构建时**的相对路径,本机按候选根目录找同名子树
for root in /root/ha-test /root /home/program; do
cand="$root/${KERNEL_SDK_PATH#./}"
if [[ -f "$cand/go.mod" ]]; then SDK_DIR="$cand"; break; fi
done
fi
if [[ -z "$SDK_DIR" ]]; then
# 退路:本机 SDK 指针hmapdev 那套)。**这里必须出声** —— 它与内核血脉是否一致
# 由第 4 步的依赖表比对来判,不靠人猜。
ptr_root="${HOMEAGENT_SDK_ROOT:-/root/.homeagent/hmapdev/sdk}"
[[ -f "$ptr_root/current" ]] || die "既找不到内核的 SDK 源码,也没有 $ptr_root/current"
SDK_DIR="$ptr_root/$(tr -d '[:space:]' <"$ptr_root/current")"
echo "[build] 警告:没找到内核的 SDK 源码目录,改用本机指针 $SDK_DIR" >&2
fi
[[ -f "$SDK_DIR/go.mod" ]] || die "$SDK_DIR 不是一个 Go 模块(没有 go.mod"
SDK_VER="$(grep -m1 -oE 'Version = "[0-9]+\.[0-9]+\.[0-9]+"' "$SDK_DIR/meta/meta.go" 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || true)"
echo "[build] 本次用 SDK 源码:$SDK_DIRmeta.Version=${SDK_VER:-未知}"
# ── 3. 用临时 modfile 替换,**不改动**受版本管理的 go.mod ──────────
cd "$HERE"
TMP_MOD="$(mktemp -d)/go.local.mod"
cp go.mod "$TMP_MOD"
go mod edit -modfile="$TMP_MOD" -replace "$SDK_MODULE=$SDK_DIR"
export GOFLAGS="${GOFLAGS:-} -modfile=$TMP_MOD"
go build ./...
hmapdev build
# ── 4. 产物自检:依赖表必须与内核一致(这才是"对齐"的定义)────────
echo "[build] 校验产物:"
BIN="build/plugin.bin"
[[ -f "$BIN" ]] || die "没找到产物 $BIN"
OUT_SDK_VER="$(go version -m "$BIN" | awk -v m="$SDK_MODULE" '$1=="dep" && $2==m {print $3}' | head -1)"
echo " 产物链的 SDK${OUT_SDK_VER:-(无)} 内核链的 SDK$KERNEL_SDK_VER"
if [[ -z "$OUT_SDK_VER" ]]; then
die "产物没有链 $SDK_MODULE —— 装上去必然握不上手"
fi
if [[ "$OUT_SDK_VER" != "$KERNEL_SDK_VER" ]]; then
die "产物与内核链的 SDK 版本不同($OUT_SDK_VER vs $KERNEL_SDK_VER)—— 这正是握手失败/崩溃循环的形状。装上去之前必须先对齐。"
fi
echo "[build] 完成:$BIN 与内核链在同一 SDK 上($OUT_SDK_VER"