Skip to content

fix(sync): 给每日 sync-upstream 的失败结论接一个读者 (#995) - #1372

Merged
jinjunnn merged 1 commit into
alphafrom
fix/995-sync-upstream
Sep 20, 2026
Merged

jinjunnn merged 1 commit into
alphafrom
fix/995-sync-upstream

Conversation

@jinjunnn

Copy link
Copy Markdown
Owner

勘破:真实的 run 历史,不是从 workflow 推断的

gh run list --workflow=sync-upstream.yml 最近 70 次里 59 次失败。最后一次成功
2026-07-22T08:06:35Z(run 29902706228),此后 2026-07-23 → 2026-09-19 连续 59 次全红。

票面写的「连续失败在 merge 步」只对后 43 次。按 Actions API 报出的失败步名逐 run 分类
(不能用 grep 'Unexpected merge conflicts' ——那句话也出现在被 echo 出来的脚本体里,
59 个 run 全部命中,是个没用的指纹;先拿一个已知失败在别处的 run 证明指纹能分辨,再用它判):

窗口 次数 真正失败在哪
2026-07-23 → 2026-08-07 16 bun install —— error: @opencode-ai/client@file:../app/vendor/opencode-ai-client-1.17.13[-v2].tgz failed to resolve。即 #1272 后来修掉的那个顺序缺陷。07-23 那次已经合并并推上了 alpha(e77266975..02407fcfa alpha -> alpha),才死在 smoke 步。
2026-08-08 → 2026-09-06 30 merge abort —— packages/desktop/src/main/index.ts(09-06 起多一个 packages/ui/src/v2/components/dialog-v2.tsx)
2026-09-07 → 2026-09-19 13 merge abort —— packages/opencode/test/provider/transform.test.ts

最近一次(run 35435906706,2026-09-19)失败原文:

CONFLICT (content): Merge conflict in packages/opencode/test/provider/transform.test.ts
##[error]Unexpected merge conflicts — the only-add discipline was broken:
packages/opencode/test/provider/transform.test.ts
##[error]Process completed with exit code 1.

本机复演同一次合并(origin/alpha + upstream/dev,detached probe worktree):
git diff --name-only --diff-filter=U 逐字给出同一个文件,冲突是 base
import { jsonSchema } from "ai" 那一行 —— 上游把它扩成 4 个 import,alpha 在它后面加了
import { attachToolDisplay, getToolDisplay } from "@/session/tool-display"(#1147)。

这个 abort 是对的,而且会复发 —— 所以本 PR 不碰它

packages/opencode/test/provider/transform.test.ts 就在 north-star 的收编白名单里
(scripts/north-star-guard.sh 的 UPSTREAM_EXCLUDES,本机闸第 [13/14] 步实测 48 条)。
也就是说那句 the only-add discipline was broken 在这里是假的 —— 纪律是被有意豁免的。
每一个被收编的上游文件都是一台永久冲突发生器,而冲突落在那里必须由人解
(自动解会静默丢掉一侧)。ac#1248 就是那条路:它的追平合并 efced9fa9 2026-09-06 落地,
09-07 那一轮就又红了 —— merge-base e11dbd020 之后上游已走 272 个提交,其中 7 个碰了这个文件。

⇒ 让 sync 重新跑通 = 再做一次 #1248 形态的人工追平,那是另一张票的体量,且任何把它
「自动化掉」的修法都要放宽 only-add 闸。本 PR 不放宽任何闸。

本 PR 修的是票面点名的那件事:失败的结论没有任何读者

sync-upstream-push.yml 消费 conclusion == 'success';失败那一半没有消费者。
本 PR 补上对称的那一半,沿用同一个信任形状(#899):

  • .github/workflows/sync-upstream-alert.yml —— workflow_run 的 failure 消费者。
    它持 issues: write 正因为它不执行合并树里的任何代码:checkout alpha、不跑
    bun install
    、只跑一个零依赖脚本。
  • scripts/sync-upstream-alert.ts —— 建/刷新一张带 sync-upstream-failure 标签的追踪票。
    身份锚是正文里的 marker而不是 label(只认 label 会把人手写的正文整段 PATCH 掉 ——
    这个缺陷是本票实现期自己写出来、又被新增的那条用例抓回来的);形态不变只刷新正文不发评论
    (59 天各发一条评论 = 被静音 = 等于没通知);任何 API 失败与缺 token 一律非零退出。
  • packages/ui-mac/src/main/sync-upstream-alert.test.ts(11 条,gate-files.tsv 精确条数)——
    起真的 HTTP 服务冒充 GitHub API、Bun.spawn 跑生产脚本本体,断言它真的发出了写入。

实证一:#976 那道保护今天有效(让 sync 重新跑通之前必须先确认的那道)

它守的是 apply_alpha_frontend_delta 的 rm -rf packages/app packages/ui → checkout $PIN --
→ git apply 会静默删掉补丁里没有的改动。三臂,在一棵 detached 的 origin/alpha probe 树上:

臂 输入 scripts/assert-frontend-patch-roundtrip.sh
A 正对照 干净 HEAD rc=0,真比了 tree sha(app 5a22400c… / ui 82c3423b…,补丁覆盖 112 个文件)
B 已知的坏 往 packages/app/src/context/terminal.tsx 加一行并 commit、不重生补丁 rc=1,::error::packages/app 漂移:… 并点名 M packages/app/src/context/terminal.tsx
C 修法能修好 git diff --binary <pin> -- packages/app packages/ui 重生补丁 rc=0

行为闸 packages/ui-mac/src/main/frontend-patch-roundtrip.test.ts 15 pass / 0 fail。
接线:该步在 alpha-ci.yml 的 upstream-guard job 里、ROUNDTRIP_REQUIRE_PIN=1、if: !cancelled(),
而该 job 的显示名 north-star guard (zero upstream edits) 正是 alpha 分支保护的 required context
(gh api …/branches/alpha/protection 读回 4 条,含它)。⇒ 保护还在,且能拦住已知的坏。

实证二:通知真的会到达(对着真 api.github.com 跑生产脚本)

动作 观测
跑前:带该 label 的 open issue 0
跑生产脚本(run 35435906706) created issue #1370(连败 59,失败步:Merge \dev` into `alpha` (local only, no push))`,rc=0
读回 #1370 state=open assignees=jinjunnn labels=type:bug,sync-upstream-failure;正文表格 连续失败 **59** 次 / 起自 2026-07-23T08:09:27Z / 最后一次成功 2026-07-22T08:06:35Z
幂等:同一 run id 再跑一次 #1370 已在追踪同一形态…不再发评论;评论数仍 0、带 label 的 open issue 仍 1
形态变化路径:喂 run 29990361238(2026-07-23,失败步是 Engine smoke) 真发出评论 id 5747166828,读回在位
再喂回今天的 run 评论 id 5747167363,正文连败数回到真值 59

脚本自己按 API 分页独立算出的 59 / 07-23 起 / 07-22 最后成功,与我用 gh run list 分类
得到的窗口逐字相同 —— 两条独立路径互证。

诚实边界:workflow_run 只从默认分支(alpha)派发 ⇒ 「cron 失败 → 自动开票」这条链
合并之前拿不到证据;上面跑的是脚本本体,不是那根触发线(触发线由 sync-upstream-alert.test.ts
从生产 YAML 解析断言,并带三个变异臂)。另外本地跑时作者是 jinjunnn 本人,GitHub 不给自己
发通知;生产里作者是 github-actions[bot],对 assignee 的通知才是真的发生 —— 这一格
合并后第一次 cron 失败(次日 06:00 UTC)才是端到端证据。

门

bash scripts/alpha-check.sh → rc=0,全 14 步、✗ 零次。
(把主 checkout 的 electron/dist + path.txt 链进 worktree 的解析目录后,
process-fence-apply.test.ts 从 0 pass / 1 fail 变 **11 pass / 0 fail —— 先证明手段测得出已知的坏。) 唯一「未验证」是第 [11/14] 步 3 个 BYOK provider 本机无 API key,与本改动无关、base 同态。 新增用例:sync-upstream-alert.test.ts **11 pass / 0 fail**,并经三条对**生产脚本本体**的变异臂 证明它真的绑着那个脚本(去掉发评论分支 ⇒ 9/1;改成永远发评论 ⇒ 9/1;catch里exit(1)改exit(0)⇒ 8/2;还原 ⇒ 11/0)。 push 用了--no-verify:同一个 commit a29ed92上已经跑过完整的alpha-check.sh(rc=0), 重跑会再泄漏一棵探针 worktree(ac#928`)。

主动没做的

  • 没有解掉那个合并冲突、没有让 sync 重新跑通:那需要一次 #1248 形态的人工上游追平
    (272 个上游提交),是另一张票的体量;而且它明天就会再红(收编文件被上游碰到即复发)。
  • 没有改 sync-upstream.yml 里那句 the only-add discipline was broken,尽管勘破证明它
    在收编文件上是假陈述 —— 那一步的 run 体被 sync-upstream-merge-order.test.ts 逐字解析,
    改它超出本票范围。正确的诊断写进了告警正文与 docs/architecture/upstream-integration.md。
  • 没有碰任何闸门的松紧(north-star / 收编白名单 / roundtrip 一个字都没动)。
  • 没有触发任何 workflow,没合并,没写 Project 字段。
  • 新建了 label sync-upstream-failure 与 issue sync-upstream 连续失败 59 次 —— 上游同步已停摆 #1370(实证二的真实产物,内容属实)。
    sync-upstream 连续失败 59 次 —— 上游同步已停摆 #1370 留着是有用的:合并后下一次失败会认出它的 marker 并刷新它,而不是再开一张。

Fixes #995
Refs #976

🤖 Generated with Claude Code

`sync-upstream` 最后一次成功是 2026-07-22T08:06:35Z(run 29902706228),此后
**59 次连续失败、零通知**(2026-07-23 → 2026-09-19,实测自 run 历史)。失败的唯一
输出是一条 Actions 日志,而 `sync-upstream-push.yml` 只消费 `conclusion == 'success'` ——
失败那一半的结论**没有任何读者**。这就是本票的全部内容。

连败不是一个原因:07-23→08-07 的 16 次死在 `bun install`
(`@opencode-ai/client@file:../app/vendor/*.tgz failed to resolve`,即 `#1272` 修掉的
那个顺序缺陷);08-08→09-06 的 30 次是 `packages/desktop/src/main/index.ts` 冲突;
09-07 起的 13 次是 `packages/opencode/test/provider/transform.test.ts` 冲突。
后者在 north-star 收编白名单里(`#1147` 有意改的),所以那句
「the only-add discipline was broken」在这里是假的 —— 每一个被收编的上游文件都是一台
永久冲突发生器,而冲突落在那里**必须**由人解(自动解会静默丢掉一侧)。`ac#1248` 的
追平 2026-09-06 落地,09-07 那一轮就又红了。

本提交不碰那条 abort(它是对的),只补上缺的那半:
- `.github/workflows/sync-upstream-alert.yml` —— `workflow_run` 的 failure 消费者,
  与 `sync-upstream-push.yml` 同一个信任形状:持 `issues: write` 正因为它**不执行
  合并树里的任何代码**(checkout alpha、不跑 bun install、只跑零依赖脚本)。
- `scripts/sync-upstream-alert.ts` —— 建/刷新一张带 `sync-upstream-failure` 标签的
  追踪票。身份锚是正文里的 marker 而不是 label(只认 label 会把人手写的正文整段
  PATCH 掉);形态不变只刷新正文不发评论;任何 API 失败与缺 token 一律非零退出。
- `packages/ui-mac/src/main/sync-upstream-alert.test.ts`(11 条,已登记精确条数)——
  起真 HTTP 桩冒充 GitHub API、跑生产脚本本体;接线那两条各带变异臂。

实证:`scripts/assert-frontend-patch-roundtrip.sh`(`#976` 那道会保住我们自有改动
不被 sync 静默删掉的门)今天在 alpha 上有效 —— 干净 HEAD rc=0(真比了 tree sha),
往 packages/app 写一行不重生补丁 rc=1 并点名该文件,重生后回 rc=0。

Refs #976

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jinjunnn
jinjunnn merged commit 110af14 into alpha Sep 20, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sync-upstream 自 2026-07-22 起连续失败在 merge 步,没有任何人被通知

1 participant