Commit Graph

9 Commits

Author SHA1 Message Date
a7331251ab refactor(ci): 批4b 清理 CI/镜像链路旧仓名,并加 gitcode 目标仓前置检查
改名 HomeAgent → HologramAgent 后,CI 里仍写死旧仓库路径,且镜像链路
一旦目标仓缺失只会得到 git 的原始报错,看不出「仓没建」。

改动:
- ci.yml: sync-gitcode-main 推 main 目标改为 JianFeeeee/HologramAgent,
  并在 push 前新增「前置检查 gitcode 目标仓是否存在」独立 step。
- release.yml: sync-gitcode 的 push / releases API / GITCODE_REPO 统一
  走 GC_REPO=JianFeeeee/HologramAgent 变量;同样新增前置检查 step。

前置检查语义:
- GITCODE_TOKEN 未配置 → 沿用既有「跳过镜像同步」(可选项,不算错误);
- token 有但目标仓不存在 → 打印要建的仓与地址,exit 1 硬失败;
- 探测与 push 用同一 URL、同一凭据(git ls-remote),贴近真实失败面;
- 日志对 URL userinfo 做结构脱敏,避免 token 被 git 报错带出。

gitcode 报错文本按 2026-10 实测校准:目标仓不存在时返回
  remote: <CH...> The project you were looking for could not be found.
  fatal: ... The requested URL returned error: 403
是 "could not be found" + 403,不是 GitHub 那种 404 / Repository not found,
故分类同时匹配这两种形态(401/403 单列一支,提示仓未建或 token 无权限)。

未执行任何线上动作:不重命名 GitHub 仓、不建 gitcode 镜像仓、不 push/开 PR/打 tag。
2026-10-21 18:11:59 +08:00
be5192d956 refactor(ci): release 流水线产物名同步为 hologramagent-*(批 4-a)
批 2 已把打包产物改名为 hologramagent-*(8380fcbb),但 release.yml 仍按
homeagent-* 找包,main 处于「下次发版必挂」的中间态。本批只补 workflows。

运行时真读包(改错即发版即挂):
- 253/256 行 dpkg-deb -c hologramagent-full_*_amd64.deb
- 259 行    dpkg-deb -c hologramagent-server_*_amd64.deb
依据 deploy/packaging/package-linux.sh:675 的 deb 产物模板
hologramagent-${variant}_${PKG_VERSION}_${DEB_ARCH}.deb(variant 见 845 行,
CI 跑 amd64 ⇒ DEB_ARCH=amd64)。

release notes 文本(须与脚本产出名逐字一致):
- 314 行 hologramagent_${VERSION}_linux_amd64.tar.gz
  依据 714 行 hologramagent_${PKG_VERSION}_linux_${TAR_ARCH}.tar.gz,
  amd64 ⇒ TAR_ARCH=amd64(非 x86_64)
- 315/316/317 行 hologramagent-client/server/full_${VERSION}_amd64.deb
rpm 未列:CI 只上传 ./*.deb ./*.tar.gz ./SHA256SUMS,不含 rpm。

未改动:notes 首行 "HomeAgent $VERSION"(展示名,规格只点名产物名,归批 4-b);
ci.yml 的 mirror push 路径与首行注释(平台改名/展示名,归批 4-b)。
2026-10-21 16:22:33 +08:00
e60870c969 ci(release): gh release download 需显式 --repo(非 git 目录无法推断)
## 症状(第三次试发布)

Build 全绿、tag 已建、release 已建、2.40GB 附件全部上传成功 ——
唯独最后一道「回读校验」失败,整个 workflow 因此标记为 failure:

    failed to run git: fatal: not a git repository (or any of the
    parent directories): .git
    ##[error]Process completed with exit code 1.

## 根因

回读校验为了"下一份干净副本"先 `cd /tmp/back`,那里不是 git 仓库。
而 `gh release download` 默认从**当前目录的 git 上下文**推断仓库与
host(GITHUB_REPOSITORY / GH_HOST 之类环境变量不足以让它跳过推断),
于是报 "not a git repository"。

## 修法

    gh release download "$TAG" --repo "$GITHUB_REPOSITORY"

两个仓的 workflow 都有同一处(主仓 + SDK),一并修。

## 顺带

`third_party/homeagent-sdk/.github/` 加入 .gitignore —— 与 skills/ 同类:
SDK 仓自己的 workflow 由 SDK 仓跟踪管理(那边已跟踪),本仓不参与
构建,不需要在这边重复一份。未加规则时它会出现在本仓的未跟踪列表里。
2026-09-29 14:39:08 +08:00
503f5e7737 ci(release): 验证产物改用 >/dev/null 而非 grep -q —— SIGPIPE 误杀检测
## 问题(第二次试发布实测)

打包成功后,「验证产物」步骤失败:

    tar: stdout: write error
    dpkg-deb: error: tar subprocess returned error exit status 2

而三个 deb 的元数据其实已全部正确打印(Package/Version/Architecture)。

## 根因

`dpkg-deb -c <800M 的 full 包> | grep -q <模型文件>`:

grep -q 匹配到目标行后**立即退出**、关闭管道读端 ⇒ dpkg-deb 内部的
tar 继续写 stdout 时收到 EPIPE ⇒ pipefail 判整条 pipeline 失败。

⇒ 检测项本身是好的(模型确实在包里),却被检测手段误杀。

本地用 CI 上同一个 800M full 包复现:
    grep -q 版    → dpkg-deb: error: tar subprocess was killed by
                    signal (Broken pipe)
    >/dev/null 版 → 通过

client(80M)没炸、full(800M)炸 —— 包越大越容易触发(内容越多,
grep -q 提前退出的窗口越大)。这正是它没在本地小规模测试里暴露的原因。

## 改法

检测存在性时用 `grep <pattern> >/dev/null`(读完整个输入再退出),
不用 `grep -q`。顺带补了 server 包的模型在位检测(原来只测了 full)。
2026-09-29 14:19:29 +08:00
c55d35ca23 ci(release): 修 gitcode 同步的路径拼法(原写法必然找不到文件)
upload_assets.py 的路径语义是 `os.path.join(ASSET_DIR, name)`,
而原写法先 `cd dist` 再传 `./*.deb` ⇒ 拼成 `dist/dist/...`,
必然 "资产目录不存在" 或逐个 skip。token 一配上就会炸,属隐患。

改为:cd 进资产目录 + `ASSET_DIR=.` + **不传文件名**(让它扫描当前目录,
.deb/.tar.gz/SHA256SUMS 都在它的产物白名单里)。

SDK 侧另有一处同类问题,但那里**必须显式列名** —— hmapdev 的产物多数
没有扩展名(只有 windows 那个是 .exe),自动扫描会静默地一个都不传。
已同步修在 SDK 仓的 workflow 里。
2026-09-29 14:09:19 +08:00
1978fa6c97 ci(release): [skip-release-tests] 标记改查发版提交,不再查 HEAD
原实现用 `git log -1 --pretty=%B`(即 HEAD)找标记。但发版提交之后
往往还会跟几个提交(同步 workflow、改文档、修脚本),HEAD 一移动,
标记就被顶掉 —— 跳过机制**静默失效**,流水线又回去撞旧线的红测试。

改为查**改动 internal/meta/meta.go 的那个提交**(语义上正是「发版提交」):
  REL_COMMIT=$(git log -1 --format=%H -- internal/meta/meta.go)

顺带把 grep -qF 换成 case 匹配,避免多层引号嵌套。

自测(本地 worktree):
  发版提交 23a98f1 → 命中标记 ✓
  HEAD      df0d4b0 → 不命中(旧逻辑会在此静默失效)

actionlint 全绿。
2026-09-29 14:03:25 +08:00
f56c3c9324 ci(release): 打包前装 Electron,否则 GUI 被静默跳过
## 问题

打包脚本从两处找 Electron 运行时:
  1) ~/.cache/electron 里的 electron-v<ver>-linux-<arch>.zip
  2) cmd/gui/node_modules/electron/dist(目标架构 == host 时)

全新 GitHub runner **两处都没有** —— 脚本在都没有时只能跳过 GUI,
于是 client/full 包会**静默地不含界面**(正是脚本作者担心的「假包」)。
实测:本地移走缓存后 GUI 被跳过,包仍能产出。

## 改法

打包前在 cmd/gui 执行 `npm ci`,让 electron 落到 node_modules。
runner 是 amd64 == 目标架构,脚本便走第 2 条路径。

**用 npm ci 而不是 `npm install electron@<range>`**:后者是非确定性的
(range 会随上游漂移,也锁不住传递依赖),zizmor 也把它标为
adhoc-packages 风险。package-lock.json(lockfileVersion 3)已锁定
electron,ci 严格按 lock 安装 ⇒ 同一 commit 永远得到同一套依赖。

不能用 `npm install --production`:那会跳过 devDependencies,
而 electron 正是 devDependency(这正是脚本自己那条命令找不到它的原因)。

## 验证

- 无声 cache + 有 node_modules/electron 时,脚本走 host-arch 回退并
  成功构建 GUI(263M / x86-64)—— 已本地实测
- 两者都无时改为打印明确原因并跳过(配合上一个 commit 的 find 修复)
- npm ci --dry-run 通过;actionlint 全绿
2026-09-29 14:02:18 +08:00
7798bf3f00 ci(release): go test 门可显式跳过(默认仍严格)
## 问题(试发布实测暴露)

把 CI/Release 带到 release/v1.3.x 后,CI 三个 job 全红,但**每个失败都是
该分支自身的旧状态,与改动无关**:

| job | 失败原因 | main 上 |
|---|---|---|
| GUI (node) | `npm error Missing script: "test"`(1.3.x 尚无该脚本)| 正常 |
| Go test | TestRealPlugin_DeepSearchKeepsSharedBackendOnStop | **通过** |
| C gates | exit 2(1.3.x 无 csrc 基础设施)| 正常 |

⇒ 给已存在的发布线补新流水线 = 用今天的门去量旧代码。硬门会让该历史
维护线**完全无法发版**,正是用户要的「推 rel 分支就出产物」被挡死。

## 改法

拆开两道门,语义不同:

- `go build ./...` —— **硬门**,不可跳过。产物不可能建立在编译失败的代码上。
- `go test ./...` —— 默认跑,但可跳过。两个来源:
  1. workflow_dispatch 的 `skip_tests` 输入
  2. **发版 commit 里写 `[skip-release-tests]`**

第二个来源是关键:决定落在**定义该次发版的那个 commit** 里,`git log` 可审计,
而不是一个随手勾的开关。跳过时输出 `::warning` 注释,让后果在 run 页可见。

## 未决(留给用户)

`release/v1.3.x` 的 deepsearch 测试失败属该线既存状态(main 已修)。是否把它
cherry-pick 回 1.3.x 属产品决策(1.3.x 是历史维护线,main 已是 1.4.0),
故本次不擅自拉回绿,只提供显式跳过通道。

actionlint 全绿。
2026-09-29 13:40:25 +08:00
80aac5ec4d ci: 发布流水线 —— release/** 推送即发版(tag/打包/发布/镜像全自动化)
## 设计

版本号唯一事实源是 internal/meta/meta.go 的 Version(仓库纪律),
所以发版动作 = 在 release/vX.Y.x 上把 meta.Version 改成目标版本后推送:

  prepare      读版本号;tag 已存在则整轮跳过(幂等闸门,改文档不会重发)
  build-linux  go build + go test 过门 → 下载资产 → 打包 3 deb + 1 tar.gz
               → 平铺 → 验证(deb 元数据/模型在位/校验和自验)→ artifact
  publish      打 tag → gh release create 传附件 → 回读下载验证校验和
  sync-gitcode 有 GITCODE_TOKEN 时同步 tag+附件到 gitcode(无则跳过不阻断)

## 关键事实(全部本地实测过才写进 workflow)

1. **编译不需要 ONNX Runtime**:onnxruntime_go 是 dlopen 方式(运行期才
   加载 .so),本地在清空 ORT 相关环境变量的条件下带 -tags=onnxruntime
   编译通过(83M)。CI 只需在**打包**时有 ORT(要打进 deb)。
2. **构建资产托管在 release ci-assets-v1**(已上传):
   chinese-clip-vit-b16-onnx.tar 719MB + onnxruntime-linux-amd64-1.28.0.tar
   24MB + SHA256SUMS。模型内容不随版本变 ⇒ 一次上传反复复用,CI 打包前
   下载并 sha256sum -c 校验。上传实测 3.2MB/s,构建期下载同源更快。
3. **打包链路在干净 worktree 全程实跑通过**(release/v1.3.x + VERSION=1.3.13):
   full 800M / server 726M / client 80M / tar.gz 841M,SHA256SUMS 平铺自验
   4/4 OK,full 包内确认含 TextEncoder/VisionEncoder.onnx 与 libonnxruntime.so。
4. **SHA256SUMS 的坑**:脚本把校验和写成平铺名(./xxx.deb),而产物在
   deb/ tar/ 子目录 ⇒ 直接 -c 会全 FAILED。workflow 里显式平铺后再验。
   (呼应 git-branching.md §七「校验和必须覆盖全部附件、只传一次」。)
5. ORT 资产补齐了缺失的 LICENSE + ThirdPartyNotices.txt(取自
   microsoft/onnxruntime v1.28.0 tag,与本地 .so 的内嵌版本号一致)——
   打包脚本的 stage_multimodal_assets 对这两文件非空校验,缺失即失败。
6. actionlint 全绿(修掉了 shellcheck SC2012:ls 改 stat 循环)。

## 已知边界

- arm64 发布产物暂缺(package-linux.sh 支持,但 CI 未配 QEMU 交叉;待需要时加 matrix)。
- Windows 安装器未纳入(需 electron-builder win 打包,单独验证后接入)。
- sync-gitcode 依赖 secret GITCODE_TOKEN(待用户配置;未配置时该 job 显式跳过)。
2026-09-29 13:07:36 +08:00