|
|
91fc5093d1
|
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 |
|
|
|
5afe8be432
|
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 |
|
|
|
87f8fc1485
|
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):
发版提交 472d908 → 命中标记 ✓
HEAD fa5b1b4 → 不命中(旧逻辑会在此静默失效)
actionlint 全绿。
|
2026-09-29 14:03:25 +08:00 |
|
|
|
1acc933dc8
|
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 |
|
|
|
9beb3b558e
|
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 |
|
|
|
8cdcbf70fb
|
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 |
|
|
|
6d7de92bbd
|
ci: 建立 GitHub Actions 流水线(六个 job,全部命令已本地实测)
## 为什么现在做
这次排查「QQ 收不到回复」花了大半程才定位到根因,途中我犯了两类错:
先断言「提示词没写 output_send 规则」(实际 buildSystemPrompt:48-52 写了),
又断言「适配器丢了内容」(实际两版等价、直连上游正常)。
两次都是**在无自动化判据的情况下凭局部证据外推**。
仓库已有 60 个 Go 包、`go build ./...` 仅 2.2 秒,成本极低却无人强制跑。
AtomGit 停用流水线后更无兜底,故迁到 GitHub 补齐。
## 设计原则:CI 里每条命令都是本地已实测通过的
不写「可能有用先试试」的步骤 —— 未验证的 CI 步骤会把假红灯变成常态,
最后所有人都学会忽略它。本文六个 job 的每条命令都本地跑过:
go build ./... ✓
go vet ./... ✓
go test ./... -count=1 ✓(干净克隆亦通过)
make check-client-versions ✓
go test -race core + waiter ✓
waiter/initconfig/mock-server 交叉 ✓(5 平台)
npm test(cmd/gui) ✓
make check-csrc ✓(告警/ABI/ASan+UBSan/跨架构)
## 六个 job
| job | 覆盖 |
|-------|----------------------------------------------------------|
| go | build + vet + test + **跨平台客户端版本一致性** |
| race | 并发核心的竞态检测 |
| cross | linux/darwin/windows × amd64/arm64(仅可纯交叉的 3 个 cmd)|
| gui | Electron 仓的 Node 测试 |
| csrc | C 基础设施门禁 |
| docs | 站点配置可解析 |
## 关键事实(都由实测确立,不是推断)
1. **只有 waiter/initconfig/mock-server 能纯交叉编译**。homed、memgc、
homed-kb-migrate 依赖 cgo(gojieba / onnx),必须原生构建 ⇒ 不进 cross matrix。
2. **CGO 必须为 1**:gojieba 需要 cgo,`CGO_ENABLED=0` 下 internal/memory
直接编译失败(实测)。
3. **`go test ./...` 不会碰到 cmd/gui**。该目录是纯 Electron(0 个 .go、
无 go.mod),`./...` 只匹配含 Go 文件的包;只有显式 `go test ./cmd/gui`
才报 "no Go files"。这不是缺陷,是 Go 的包匹配语义 —— 之前把它当
[setup failed] 是误读。
4. **cmd/gui 的 npm test 零依赖**:三个 .mjs 只 import node: 内置模块
(fs/url/path/vm)⇒ 不需要 npm ci、不需要 electron,秒级完成。
5. **测试自足,CI 上不会因缺本地服务而红**:webui 测试用 httptest 与
`127.0.0.1:0`,真实 LLM 测试带 t.Skip 守卫。
6. **action 版本已核实存在**:checkout/setup-go/setup-node/setup-python 均用
v7(经 GitHub API 逐个确认 tag 存在,避免「版本不存在 ⇒ 立刻红」)。
## 明确不进 CI(依赖真机/密钥/内网,否则只会变 flaky 噪音)
deploy-*.sh、waiter 真机(192.168.2.x)、`npm run test-live`(需真 Electron
+ Xvfb + 真后端)、scripts/kernel-stress/*、需 DEEPSEEK_API_KEY 的真实 LLM 测试。
|
2026-09-29 10:23:21 +08:00 |
|