- 三分支表更新:custom 是 default branch + 持有 workflow,ci 降级为过渡态历史分支 - 改写"为什么 workflow 在 custom 不在独立分支"段,记录设计决策 演进的真实理由(runs 列表 UX 优于 meta/code 分离的设计美感) - workflow 清单从 5 项缩到 3 项,记录 docker-release/snapshot 已删的事实 - "给后续 Claude" 提示中"不要把工作流提交到 custom" 改为相反 方向(直接在 custom 改 workflow) - 同步历史补555ecc1a(workflow 迁移) 与75b4d78d(numpad fix)
8.5 KiB
CLAUDE.md
本项目是 mayswind/ezbookkeeping 的个人 fork。
本文件:仓库分支模型、上游同步流程、CI 故障排查 —— meta 层
FORK.md:fork 相对上游的具体改动清单(feature 维度 + 进度状态) 个人笔记:通用 fork 工作流决策框架在fork-工作流决策框架.md(不入库)
本文件只记录这个仓库的具体事实,避免 Claude 会话误判。
仓库拓扑
github.com/mayswind/ezbookkeeping (上游)
│ Gitea pull mirror(后台异步)
▼
git.zhengchentao.win/mirror/ezbookkeeping (只读镜像)
│ CI workflow 拉过来
▼
git.zhengchentao.win/dev/ezbookkeeping (origin,本地唯一 remote)
本地 git remote -v 只有 origin 一项,没有手工配 upstream。上游同步通过 ci 分支上的 workflow 在服务端完成,不是本地操作。
三个分支的职责(必须先理解,否则会改错地方)
| 分支 | 职责 | force push? |
|---|---|---|
main |
锚定上游 release tag(当前 v1.4.0)。被 .gitea/workflows/sync-upstream.yml git reset --hard <tag> 覆写 |
是(由 CI 做) |
custom |
所有个人改动 + workflow 文件都在这:信用额度功能、UI 调整、个人需求清单、.gitea/workflows/*.yml 等。具体改动清单见 FORK.md。日常开发分支,default branch |
是(rebase 后人工做) |
ci |
历史 default branch,2026-05-02 已让位给 custom。.gitea/workflows/ 暂保留作过渡,验证稳定后清理 |
否 |
⚠️ 2026-05-02 起 default branch 是 custom。git clone 默认 checkout custom,直接是开发分支。
为什么 workflow 在 custom 不在独立分支(2026-05-02 演进)
最初 workflow 单独放 ci 分支以"meta/code 分离",但 Gitea Actions runs 列表显示的 commit 是 workflow 文件所在 commit(即 ci 的 HEAD),不是被构建的代码 commit,UX 误导性强。改放 custom 后:
- runs 列表的 commit 字段 = 真实代码 commit ✅
- workflow_dispatch UI 直接从 default branch(custom)发现 workflow ✅
- rebase 上游时 workflow 跟 custom 一起平移,无需额外处理 ✅
- 代价:失去"workflow 与代码完全独立"的设计美感 —— 但实际上 workflow 本来就是为构建当前代码服务的,这个分离原本就是过度设计
不要再把 workflow 文件提交到 ci 分支。要改 .gitea/workflows/*.yml 直接在 custom 上改、commit、push。
custom 分支 workflow 清单
.gitea/workflows/ 当前有 3 个 workflow(2026-05-02 起精简,删了上游残留的 docker-snapshot/docker-release):
| 文件 | 触发 | 干什么 | 状态 |
|---|---|---|---|
sync-upstream.yml |
手动(workflow_dispatch,可填 tag) |
服务端把 dev/main 强制 reset 到 mirror 上的指定 release tag(默认最新),然后 push --force-with-lease + 推 tags |
✅ 在用 |
build-image.yml |
手动(可填要打包的分支 + 镜像 tag) | checkout 指定分支(默认 custom)→ 装 buildkit v0.13.2(钉版本)→ 登录 Gitea registry → 构建镜像(带 OCI 标签 source/revision,Gitea 自动关联包到 repo)→ push 到 git.zhengchentao.win/dev/ezbookkeeping:<hash> 与 :latest,build-args: BUILD_PIPELINE=1 跳过活 API 测试 |
✅ 在用,是日常发布通道 |
deploy.yml |
手动 | 跑 repo Variables 里 CUSTOM_DEPLOY_SCRIPTS 这条自定义脚本(通用钩子,可拼"build 完触发 NAS 端 docker compose pull/up"等) |
🟡 通用钩子,按需配 |
已删:docker-snapshot.yml(push main 自动触发,未配 secrets.DOCKER_REPO 永远失败)、docker-release.yml(push tag 同样问题)。需要时再从 git 历史 cherry-pick 回来。
同步发布流程(rebase 模型)
- 上游出新 release(如 v1.4.0)→ Gitea pull mirror 自动把 tag 同步到 mirror
- 人工触发
Sync from upstreamworkflow → 服务端把 dev/main reset 到该 tag - 本地
git fetch && git checkout custom && git rebase origin/main - 解冲突(如有)→ 验证 →
git push --force-with-lease origin custom - 在 Gitea Actions UI 手动触发 build-image workflow,构建新镜像
为什么 rebase 不 merge:个人项目,无团队协作语义要保留,线性历史更清爽。
给后续 Claude 会话的明确提示
- 用户说"我的分支" / "切换到我的分支" → 指
custom - 用户说"rebase main" → 指
git rebase origin/main,目标是把 custom 的改动叠到最新上游 tag 之上 - 不要在
main分支上提交任何东西(会被 CI 覆写) - workflow 文件改动直接在 custom 上做(2026-05-02 起,不再是 ci 分支)
- force-push custom 是常规操作,但每次用
--force-with-lease,不直接--force - 如果发现本地配了 upstream remote,那是历史遗留,不要依赖;以 origin/main 为准
.claude/在.gitignore里(个人本地配置不入库),但CLAUDE.md本身入库
同步历史
- 2026-05-01:rebase custom → origin/main (v1.4.0)。22 个 custom-only 提交(含一个旧的
Merge branch 'main' into myrequirementcommit)压平为 21 个线性提交。已 force-push origin/custom(08c69042→fe265259)。 - 2026-05-02:修 Gitea Actions
Build Docker Image工作流。三层故障,全部不在本仓库代码里:- TLS 雷:
docker login走 host 进程不命中 PREROUTING REDIRECT,且 v6 撞 DSM nginx 的 CF Origin Cert。NAS 侧修:iptables 补 OUTPUT 对称规则 +/etc/hosts显式 v4 兜底。详见 obsidian vault NAS/notes/内网证书路径 §三.5/§三.6 - buildkit 内核兼容:runc 1.2+ 撞 DSM 4.4 内核。
.gitea/workflows/build-image.yml钉moby/buildkit:v0.13.2(commitacdbb5bf) - backend 单元测试撞活 API:
pkg/exchangerates/的TestExchangeRatesApiLatestExchangeRateHandler_*跑活 API(加拿大银行 / 乌兹别克央行),国内访问超时。upstream Dockerfile 已设ARG BUILD_PIPELINE,测试代码看到BUILD_PIPELINE=1 && CHECK_3RD_API!=1时早退。修:workflow 加build-args: BUILD_PIPELINE=1(commit2dd8f099),对齐上游 GH Actions
- TLS 雷:
- 2026-05-02 (后续):workflow 文件从 ci 分支迁到 custom,default branch 切到 custom(commit
555ecc1a)。原因:Gitea Actions runs 列表的 commit 字段一直显示 ci 的 workflow commit,不是被构建的代码 commit,UX 误导性强。挪到 custom 后列表直接显示真实代码 commit。同时清理上游残留的docker-release.yml/docker-snapshot.yml(依赖未配的secrets.DOCKER_REPO,永远失败) - 2026-05-02 (numpad fix):FORK.md #11 定位 + 修复。小键盘点击卡顿真因是
.numpad-button的touch-action: none(上游e178a079引入)与 F7 tap 处理叠加,改为touch-action: manipulation(commit75b4d78d)
给后续 Claude 会话:CI 故障排查路径
如果 Gitea Actions build 又炸,按 NAS 域问题 vs 仓库代码问题分别排查:
| 现象 | 大概率位置 | 文档 |
|---|---|---|
Login to Gitea Container Registry 步骤报 x509: certificate signed by unknown authority |
NAS 网络层(iptables / dnsmasq / DSM nginx 占 443) | obsidian vault NAS/notes/内网证书路径.md + NAS/notes/IPv6 设计.md |
Build and push 步骤里 RUN ... 在第二条之内就炸 unsafe procfs detected 之类 |
buildkit/runc 与 DSM 内核版本 | .gitea/workflows/build-image.yml 的 driver-opts |
Failed to pass unit testing / Failed to pass lint checking(build.sh 报) |
先看 Dockerfile 顶部 ARG,多半是 CI 跳过开关没传(如 BUILD_PIPELINE / CHECK_3RD_API / SKIP_TESTS)。不要先去改测试代码 |
Dockerfile 顶部 ARG + .gitea/workflows/build-image.yml 的 build-args |
actions/checkout 报 fetch 失败 |
Gitea SSH/HTTPS 路径或 token 权限 | gitea-runner 的 GITEA_RUNNER_REGISTRATION_TOKEN + NPM git.zhengchentao.win 的 Advanced 配置 |
| Dockerfile 里某条指令业务逻辑报错 | 真正的代码问题 | 本仓库 Dockerfile |
通用排查原则:build.sh 报的"测试失败 / lint 失败"先看是不是上游已经设计了 CI 跳过路径。Dockerfile 的 ARG + build.sh 内的 os.Getenv() 检查通常成对出现(如 BUILD_PIPELINE=1 → 跳过 3rd API 测试,SKIP_TESTS=... → 跳过指定测试名)。对齐上游 .github/actions/ 下的传参,绝大多数情况能直接对齐。