fix(sync): 保护 addon 修改过的上游文件,并把静默跳过改为显式报告 - #5
Merged
Merged
Conversation
added 3 commits
September 15, 2026 13:42
Build Add-on Image 在合并后首次运行即失败:
##[error]Can't find 'action.yml', 'action.yaml' or 'Dockerfile'
for action 'home-assistant/builder/actions/prepare-multi-arch-matrix@7.2.0'.
根因:home-assistant/builder 存在两条版本线。
- 7.x(7.0 / 7.1 / 7.2.0):旧版 builder,**仓库内没有 actions/ 目录**
- 2026.x(2026.09.0 等):新版,含 actions/{build-image,
prepare-multi-arch-matrix,publish-multi-arch-manifest,cosign-verify}
实测对比(两个 tag 各自的 clone):
tag 7.2.0 → azure-pipelines.yml builder.sh build.json Dockerfile ...
actions/ 不存在
tag 2026.09.0 → actions/ action.yml ...(4 个子 action 齐全)
官方 README 示例中的 @[version] 指的是 releases 页面上的 tag,
即日历版本(2026.09.0),而非 7.x 那条线。此前取了 7.2.0 属实误判。
Build Add-on Image 第二次运行实际进入构建阶段,buildx 报错:
##[error]buildx failed with: ERROR: failed to build:
invalid tag "ghcr.io/C3H3-AI/amd64-ai-proxy:1.1.0b13":
repository name must be lowercase
根因:HA 官方 builder 的 prepare-multi-arch-matrix 与
publish-multi-arch-manifest 两个 action,其 registry-prefix 默认值均为
ghcr.io/${{ github.repository_owner }},而本仓库 owner 是 "C3H3-AI"(含大写)。
Docker/OCI 规范要求 repository name 必须全小写。
改动(3 处,统一为 ghcr.io/c3h3-ai):
- prepare-multi-arch-matrix: 显式传 registry-prefix
- publish-multi-arch-manifest: 显式传 registry-prefix
- verify job: 手写的 IMAGE 变量由 github.repository_owner 改为字面量
与 config.yaml 的 image: "ghcr.io/c3h3-ai/ai-proxy" 保持一致。
注:上一轮的 tag 引用修复(7.2.0 -> 2026.09.0)已生效——
本次 init job(Resolve version & matrix)全部步骤通过,
build job 也真正进入了 buildx 构建阶段,不再是 Set up job 失败。
## 问题
sync_vendor.sh 是「按文件」覆盖的复制式同步。addon 对上游文件做的改动会被
静默覆盖,实测跑一次 sync 后项目**直接编译失败**:
internal/svc/svc.go:69: wbPool.SetLowCredits undefined
internal/svc/svc.go:69: cfg.LowCreditThreshold undefined
(traework / qoder 两处同样)
根因:`svc.go` 在 PROTECT_FILES 里(受保护),但它依赖的 `pool` /
`config` 扩展**不在**保护名单里 —— 保护了一半,反而制造出
「独有代码引用被覆盖掉的符号」这种最坏组合。
同时会丢失本次新增的修复:
- server/handler.go TraeWork 预刷新窗口按平台区分
- upstream/client.go 流式请求改用无总时长上限的 client
## 为何这四处无法移到 addon 独有包(已逐项验证)
- pool.go : 改了 Pick()/pickExcluding() 的**内部实现**。
Go 不支持方法覆写 —— 同名函数放同包新文件会直接编译冲突;
而所需状态 lowCredit/lowCredits 是**私有字段**,
外部包(Go 语言规则)无法访问。
- config.go : LowCreditThreshold 是 config.Config 的字段,被 svc.go 引用。
- server/handler.go: 改 chatCompletions 内部逻辑。
- upstream/client.go: 改 Client 结构体与方法。
结论:这四个文件**注定要被 addon 修改**,只能 PROTECT。
## 改动
1. PROTECT_FILES 分为 A 类(addon 独有文件)/ B 类(addon 修改过的上游文件),
B 类新增 pool/config/server/upstream 四个文件,并注明各自不可外移的原因。
2. 新增 B 类受保护文件的**上游差异检查**:sync 结束时逐个比对,
若上游自基线(BASELINE_COMMIT)后改动过,打印 `[WARN] ... 需人工 merge`
并汇总。目的是让 PROTECT **不成为黑洞** —— 上游的改动不会被永久静默忽略。
3. 比较时对上游做 `tr -d '\r'`:上游文件是 CRLF、addon 是 LF,
不去掉会让全文件都显示为有差异而失去意义(这个坑已实测踩到)。
## 代价(已在 SYNC.md 载明)
这四个文件**不再跟随上游自动更新**,上游改了需人工 merge。
该代价**目前为零**:经核对,上游自基线 c62d0bc 起对
pool/config/server/upstream 的改动提交数为 0。
## 验证
完整链路实测(干净副本,未污染工作区):
sync_vendor.sh exit=0
go build ./... exit=0 ← 改造前此步失败
go test ./... 7 包通过 / 0 失败
六处改动在 sync 后全部幸存:TZ、TraeWork 预热、StreamHTTP、
is_custom_model、SetLowCredits、LowCreditThreshold。
WARN 路径亦实测:把基线改为 13e7b64 后正确输出
「pool.go 上游改动了 1 次 / handler.go 改动了 2 次」。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description / 变更描述
修复
sync_vendor.sh的一个结构性缺陷:addon 对上游文件的改动会被静默覆盖,实测跑一次 sync 后项目直接编译失败。
失败现象(实测)
根因
sync_vendor.sh是按文件覆盖的复制式同步。而现状是:internal/svc/svc.go(依赖扩展)internal/pool/pool.go(提供扩展)SetLowCredits消失internal/config/config.goLowCreditThreshold消失保护了一半,反而制造出最坏的组合:独有代码引用了被覆盖掉的符号。
同时会丢失本轮新增的两个修复:
server/handler.go— TraeWork 预刷新窗口按平台区分upstream/client.go— 流式请求改用无总时长上限的 client为何这四处无法移到 addon 独有包(已逐项验证)
pool/pool.goPick()/pickExcluding()的内部实现。Go 不支持方法覆写(同名函数放同包新文件会编译冲突);所需状态lowCredit/lowCredits是私有字段,Go 规则下外部包无法访问config/config.goLowCreditThreshold是config.Config的字段server/handler.gochatCompletions内部逻辑upstream/client.goClient结构体与方法结论:这四个文件注定要被 addon 修改,只能 PROTECT。
改动
PROTECT_FILES分两类并扩充pool/pool.go、config/config.go、server/handler.go、upstream/client.go,并逐条注明不可外移的原因新增上游差异检查(核心)
sync 结束时逐个比对 B 类文件,若上游自基线
BASELINE_COMMIT后改动过,打印
[WARN] ... 需人工 merge并汇总。目的:让 PROTECT 不成为黑洞 —— 上游的改动不会被永久静默忽略,
而是当场告知。
比较时对上游
tr -d '\r'上游文件是 CRLF、addon 是 LF;不去掉会让全文件都显示为「有差异」而失去意义
(这个坑已实测踩到,曾因此得出「traework 差异 199%」的错误结论)。
代价(已在
SYNC.md载明)这四个文件不再跟随上游自动更新,上游改了需人工 merge。
该代价目前为零:经核对,上游自基线
c62d0bc起对pool/config/server/upstream的改动提交数为 0。验证(干净副本实测,未污染工作区)
sync 后六处改动全部幸存:TZ、TraeWork 预热、StreamHTTP、
is_custom_model、SetLowCredits、LowCreditThreshold。
[WARN]路径亦实测:把基线改为13e7b64后正确输出「pool.go 上游改动了 1 次 / handler.go 改动了 2 次」。
Type of change / 变更类型
Testing / 测试
WARN 路径亦构造场景实测
Checklist / 自检清单