news 2026/9/7 3:34:27

ClickHouse「CH Inc sync」CI 检查失效诊断与修复:fix-sync 技能驱动的私有仓库同步实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ClickHouse「CH Inc sync」CI 检查失效诊断与修复:fix-sync 技能驱动的私有仓库同步实战

ClickHouse「CH Inc sync」CI 检查失效诊断与修复:fix-sync 技能驱动的私有仓库同步实战

【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse

本文以 ClickHouse 仓库内置的 Claude 技能 fix-sync 为主体,完整讲解公共 PR 上「CH Inc sync」提交状态检查的三种失败类型(conflicts foundbuild failedtests failed)是如何产生的、如何用ghCLI 精准诊断,以及对应每一类失败的标准修复流程(合并冲突解决、私有代码适配、失败任务重跑)。读完本文,你将掌握 ClickHouse 公共仓库与私有仓库clickhouse-private之间的同步机制、同步分支sync-upstream/pr/<PR_NUMBER>的生命周期,以及一套可直接复制执行的 CI 排障命令序列。

一、「CH Inc sync」检查是什么:公私仓库同步机制

当有人在ClickHouse/ClickHouse上打开一个 PR 时,系统会自动在私有仓库ClickHouse/clickhouse-private中创建一个名为sync-upstream/pr/<PR_NUMBER>分支的同步 PR。公共 PR 上的「CH Inc sync」提交状态(commit status)实时反映这个私有同步 PR 的状态:同步 PR 一旦与私有master产生冲突、构建失败或测试失败,公共 PR 上的检查就会保持 pending 或 failing。

这个机制在仓库源码中有多处可直接验证的锚点:

  • 检查名称常量定义在 ci/defs/defs.py:SYNC = "CH Inc sync",整个 CI 体系都引用这个字符串;
  • set_sync_status_awaiting_hook.py 在Code Review任务(每个 PR 必然运行)完成时,若该状态尚不存在,就向公共 PR 的 commit 写入一个pending状态、描述为awaiting,作为「同步流程可以开始」的标记;
  • set_dummy_sync_commit_status.py 在 Merge Queue 工作流中写入一个success状态的 dummy 状态(描述为dummy status to enable merge),以便 PR 能先入队合并——真正的同步验证在合并后的私有 CI 中继续;
  • check_sync_pr_mergeable.py 在 CI 中做合并前的硬校验:用gh pr list --state open --head sync-upstream/pr/<N> --repo ClickHouse/clickhouse-private --json number找到同步 PR,再查询其mergeable字段。逻辑上有几个值得注意的工程细节:
    • 找不到任何 open 的同步 PR 时放行(视为跳过检查);
    • 找到多个同步 PR 时判定为错误并返回失败(ERROR: Expected at most one open Sync PR ...);
    • mergeableUNKNOWN时会sleep(5)秒后重试一次,仍为UNKNOWN则放行,为CONFLICTING才判定失败——这正是 fix-sync 技能中「conflicts found」状态的来源之一;
  • merge_sync_pr.py 负责在公共master前进时把对应同步 PR 合入私有仓库。它从 GitHub push 事件的GITHUB_EVENT_PATHpayload 中解析出本批次的 merge-queue 合并提交:由于 GitHub 的 merge queue 可能把多个 PR 合并在同一次推送中,脚本不只看 head 提交,而是扫描整个commits数组,用锚定在行首的正则^Merge pull request #(\d+)提取每个 PR 号(锚定可排除Revert "Merge pull request #..."这类干扰),并按 payload 中从旧到新的顺序逐个执行gh pr ready+gh pr merge --merge,保证同步顺序与公共 master 的合并顺序一致。

此外,quick_sync.py 提供了一个仅对特定内部账号开放的快捷通道:手动触发私有仓库的private_quick_sync.yml工作流,并把公共 PR 的状态直接置为pending(描述sync started)或error(描述failed to start the sync)。

需要说明的是,SKILL.md 中提到的ci/jobs/private_sync_pr.pyci/jobs/scripts/workflow_hooks/private_sync_complete_check.py(分别负责写conflicts foundbuild failed/tests failed状态描述)位于私有仓库clickhouse-private中,本公共仓库里看不到,这是文档给出的事实边界。

二、三类失败类型与状态语义

根据 SKILL.md 的定义,私有 CI 会把失败写成三种描述,各自对应不同的修复手段:

状态描述含义修复动作
conflicts found同步 PR 无法与clickhouse-privatemaster合并(mergeable == CONFLICTING解决合并冲突并推送(步骤 4A)
build failed同步 PR 能干净合并,但私有 CI 的构建任务失败;通常是上游改动重命名/移动/改了符号签名,而私有仓库中引用了这些符号的私有代码没跟上适配私有代码并推送(步骤 4B)
tests failed能合并、能构建,但测试任务失败;可能是 flaky/基础设施问题(重跑即可),也可能是真实回归(需调查)分类后重跑或调查(步骤 4C)
testing(state 为pendingCI 仍在运行等待,不要操作
completed(state 为success无异常无需操作

fix-sync 技能是一个 Claude Agent 技能,其 frontmatter 声明了argument-hint: <pr-number-or-url>,并限定工具白名单为Task, Bash(gh:*), Bash(cd:*), Bash(git:*), Bash(ls:*), Bash(pwd:*), Bash(mktemp:*), Read, Grep, Glob, AskUserQuestion——即整个诊断修复过程只允许用ghgit与文件读取类工具,保证操作可审计、不越权。

参数

  • $0(必需):公共 ClickHouse PR 的编号或完整 URL(例如96005或 PR 的/pull/96005形式完整地址)。若未提供参数,技能会通过AskUserQuestion向用户询问。

三、标准诊断流程(第 1–3 步)

1. 解析 PR 编号

$ARGUMENTS中提取 PR 编号;若传入的是完整 PR URL,则从 URL 中解析编号。

2. 定位同步 PR

在私有仓库中搜索对应同步分支的 PR:

gh pr list --repo ClickHouse/clickhouse-private --head sync-upstream/pr/<PR_NUMBER> \ --json number,url,state,mergeable,mergeStateStatus,headRefName,headRefOid
  • 找不到同步 PR:向用户报告并停止;
  • 找到:向用户报告同步 PR 的编号与 URL。

这个「一个分支至多一个 open 同步 PR」的假设与 check_sync_pr_mergeable.py 中的len(sync_pr_numbers) > 1报错逻辑完全一致。

3. 诊断失败类型(关键步骤)

首选路径:读取公共 PR 上「CH Inc sync」状态的 description,它直接给出失败类型:

# 先拿到 HEAD SHA gh pr view <PR_NUMBER> --repo ClickHouse/ClickHouse --json headRefOid # 再过滤该 context 的提交状态 gh api repos/ClickHouse/ClickHouse/commits/<HEAD_SHA>/statuses \ --jq '.[] | select(.context == "CH Inc sync") | {state, description}'

映射关系:

  • conflicts found→ 走步骤 4A;
  • build failed→ 走步骤 4B;
  • tests failed→ 走步骤 4C;
  • testing(state 为pending)→ CI 还在跑,报告后停止;
  • completed(state 为success)→ 无需操作,停止。

兜底路径:状态描述缺失或有歧义时,直接检查同步 PR

  • mergeableCONFLICTING(或mergeStateStatusDIRTY)→ 归为Conflicts found(4A);
  • 否则用gh pr checks <SYNC_PR_NUMBER> --repo ClickHouse/clickhouse-private查看私有 CI:失败的 job 名称以Build开头 →Build failed(4B);只有测试 job 失败 →Tests failed(4C)。

诊断结论必须先报告给用户,再执行任何修复动作。

四、第 4 步前置:定位本地私有仓库

4A 与 4B 需要本地可写的私有仓库工作副本,查找顺序为:

  1. ../ClickHouse_private
  2. ../clickhouse-private
  3. 校验目录存在且是 git 仓库、remote 中包含ClickHouse/clickhouse-private

都找不到时用AskUserQuestion请用户提供路径,并在后续步骤中复用该路径。

五、4A:处理conflicts found

在私有仓库目录中执行:

# 拉取最新并获取同步分支 cd <private_repo_path> && git fetch origin && git fetch origin sync-upstream/pr/<PR_NUMBER> cd <private_repo_path> && git checkout sync-upstream/pr/<PR_NUMBER>

若分支上有未提交的本地改动,先询问用户再继续。

然后合并私有master并解决冲突:

cd <private_repo_path> && git merge origin/master

冲突处理规范:

  1. 列出冲突文件
    cd <private_repo_path> && git diff --name-only --diff-filter=U
  2. 逐个文件解决:SKILL 建议使用subagent_type=general-purpose的 Task 子代理,读取文件内容、分析冲突标记(<<<<<<<=======>>>>>>>),按以下原则确定解法,用 Edit 工具落盘后git add <file>
    • 大多数同步冲突,上游(公共仓库)改动优先
    • 仅存在于私有仓库的文件,原样保留;
    • CI/workflow 类文件要特别小心,保留私有仓库专属配置;
    • 若冲突复杂或有歧义,展示冲突内容并用AskUserQuestion请用户裁决,不得猜测。
  3. 完成合并
    cd <private_repo_path> && git commit --no-edit

最后按需更新子模块:

cd <private_repo_path> && git submodule update --init --recursive

子模块更新失败时报告错误但继续流程。之后进入第 5 步。

六、4B:处理build failed

「能干净合并但构建失败」几乎总是意味着:上游改动重命名、移动或变更了某个符号,而私有独占代码还在依赖旧符号;也可能是冲突解决时漏掉的代码适配。

  1. 拿到构建日志,定位确切的错误:
    gh run list --repo ClickHouse/clickhouse-private --branch sync-upstream/pr/<PR_NUMBER> \ --json databaseId,name,conclusion,headSha

    有报告 URL 时优先用公共仓库自带的 CI 报告工具 fetch_ci_report.js(见 CLAUDE.md 中的用法说明,例如node .claude/tools/fetch_ci_report.js "<PR_URL>" --failed --download-logs),或直接gh run view --log-failed查看失败 job 日志。

  2. 定位构建错误(编译错误、链接错误、缺失符号),用 general-purpose 子代理分析日志,只返回相关错误片段与涉及的文件/符号。
  3. 在私有仓库中复现并修复:checkout 同步分支(若尚未合并则先 fetch + mergeorigin/master),然后修改有问题的私有代码以匹配上游改动。原则是适配私有代码去迁就新的上游 API,而不是回退上游改动。
  4. 可选:本地重新构建验证(见第 5 步)。

七、4C:处理tests failed

合并与构建都正常,测试失败。首要任务是区分flaky/基础设施问题真实回归

  1. 获取失败详情
    gh pr checks <SYNC_PR_NUMBER> --repo ClickHouse/clickhouse-private gh run list --repo ClickHouse/clickhouse-private --branch sync-upstream/pr/<PR_NUMBER> \ --json databaseId,name,conclusion
  2. 判定为 flaky/基础设施的判据:失败与 PR 改动无关,例如Cannot start clickhouse-serverTimeout、网络/磁盘错误,或失败测试触及 PR 根本不修改的区域。SKILL 中给出了一个真实案例注记(pr-89842-sync-rerun):某个只改src/IO/*的 PR 出现了Cannot start clickhouse-server/Timeout失败,显然与本 PR 无关。
    • 动作:只重跑失败的任务,且不要做 merge:
      gh run rerun <RUN_ID> --repo ClickHouse/clickhouse-private --failed
    • 报告已触发重跑后停止。
  3. 否则视为真实回归:用子代理抓取并总结失败测试日志,向用户报告失败用例与最可能的原因。未经确认不得推送猜测性修复——用AskUserQuestion决定下一步。

4C 路径通常不推送(除非真的提交了修复),因此除非有代码变更,否则跳过第 5 步。

八、第 5–6 步:推送与验证(4A / 4B,以及 4C 提交了修复时)

可选构建验证

推送前用AskUserQuestion询问用户:

  • 选项 1「Yes, build」:在私有仓库 build 目录中运行 ninja,输出重定向到构建日志文件,用子代理总结结果;
  • 选项 2「No, skip build」:跳过构建直接推送。

推送

cd <private_repo_path> && git push origin sync-upstream/pr/<PR_NUMBER>

验证同步 PR

推送(或重跑)之后:

gh pr view <SYNC_PR_NUMBER> --repo ClickHouse/clickhouse-private --json mergeable,mergeStateStatus gh pr checks <SYNC_PR_NUMBER> --repo ClickHouse/clickhouse-private

按失败类型分别汇报:

  • Conflicts foundmergeable变为MERGEABLE则报告「同步 PR 现在可合并,CH Inc sync 检查应很快通过」;仍冲突则报告需要进一步调查;
  • Build failed:报告构建任务是否通过(CI 启动可能需要一些时间);
  • Tests failed:报告重跑是否在进行中,或修复是否已推送。

最后附上同步 PR 的 URL 供用户自行查看。

九、技能内置的工程约定(Notes)

这些约定值得单独列出,它们解释了为什么流程必须「先诊断、再动作」:

  • 永远先诊断失败类型再操作。对一个已经是MERGEABLE的同步 PR 跑 merge 没有任何收益——构建/测试类失败的修复方式完全不同(pr-89842-sync-rerun案例:没有合并冲突时应重跑失败任务,而不是无脑跑/fix-sync);
  • 同步分支命名固定为sync-upstream/pr/<PR_NUMBER>
  • 私有仓库工作副本通常位于公共仓库的上一级目录;
  • 大多数冲突都很直接,遵循「上游改动优先」即可解决;
  • 切换分支前必须先 fetch,确保拿到最新状态;
  • 禁止 rebase 或 amend,只能新增提交——这与 CLAUDE.md 中的项目级约定("When working with a branch, do not use rebase or amend - add new commits instead")完全一致;
  • 推送后 GitHub 检查状态的刷新可能有几分钟延迟,属正常现象。

十、典型用法示例

  • /fix-sync 96005—— 对 PR #96005 做同步诊断与修复;
  • /fix-sync <PR 完整 URL>—— 使用完整 URL 作为参数触发同样的流程。

小结

ClickHouse 的公私仓库同步体系把「同步是否健康」压缩成了「CH Inc sync」这一个提交状态的 description 字段:conflicts found指向 git 层面的合并冲突(修法是 mergeorigin/master并按「上游优先」原则解冲突),build failed指向私有代码对上游符号的引用失效(修法是适配私有代码而非回退上游),tests failed则要求先区分 flaky 与真实回归(前者gh run rerun --failed,后者先报告再决定)。fix-sync 技能正是把这套「诊断三分法 + 分路径修复 + 推送验证」沉淀成了可复现的 Agent 工作流,其命令序列与 ci/jobs/scripts/workflow_hooks/ 下各 hook 脚本的检查逻辑一一对应,可直接作为团队排障手册使用。

【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 3:33:11

红米K80不root优化指南:用澎湃OS系统设置提升性能与续航

在红米K80系列用户群里&#xff0c;最常见的诉求就是“性能再强一点、充电再快一点、续航再久一点”。很多人第一反应是去找 root 工具、刷模块&#xff0c;觉得不 root 就不算优化。实际上&#xff0c;对于大多数日常使用场景&#xff0c;红米K80系列搭载的澎湃OS本身就提供了…

作者头像 李华
网站建设 2026/9/7 3:31:13

FPGA网络通信实战:从MAC到PHY,打通以太网数据通路

呼&#xff0c;终于写到网络通信这章了。从点灯、按键、串口一路走过来&#xff0c;到这一章&#xff0c;前面学的时序概念、状态机、FIFO、异步处理&#xff0c;全都得拿出来用一遍。很多朋友到这一步会慌&#xff1a;网络通信听起来太系统级了&#xff0c;又是MAC又是PHY&…

作者头像 李华
网站建设 2026/9/7 3:30:48

AI应用开发工程实践:从Agent编排到模型部署的落地指南

做AI应用开发最怕的一件事&#xff0c;不是模型效果不够好&#xff0c;而是demo跑通之后不知道该往哪个方向用力。最近很多项目都顶着AI的名头&#xff0c;实际卡住的点都在Agent编排、模型部署、测试回归和批量任务这些工程环节。我打算把日常会反复用到的AI工程实践整理成一套…

作者头像 李华