Skip to content

ci(shadcn): 按失败类别把 shadcn:check 的退出码路由进 issue 通道 - #3497

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-5805-shadcn-check-exitcode
Aug 6, 2026
Merged

ci(shadcn): 按失败类别把 shadcn:check 的退出码路由进 issue 通道#3497
yinlianghui merged 1 commit into
mainfrom
claude/issue-5805-shadcn-check-exitcode

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes objectstack-ai/objectstack#5805

前提核验(在 origin/main 上逐条确认)

  1. 退出码确实被吞。 .github/workflows/shadcn-check.ymlcheck 步骤带 continue-on-error: true,pnpm shadcn:check 的退出码原样丢弃。

  2. 不只是"不标红"——告警通道从未跑过一次。 下游那个"发现更新就开 issue"的步骤条件是 if: failure()。被 continue-on-error 容错的步骤 conclusion 记为 success,job 状态不变,failure() 永远为假。也就是说 workflow 后半段的建 issue 逻辑自写下起就是死代码。旁证:仓库里从来没有过带 shadcn-sync 标签的 issue(label:shadcn-sync 搜索结果 0 条)。

  3. 退出码的真实语义(fix(components,i18n): Sheet/Dialog 关闭按钮接入 common.close,并让 shadcn 同步机制携带该补丁 (objectstack#5505) #3455 之后)。 scripts/shadcn-sync.js--check 分支只有一个非零来源:

    if (results.patchFailures > 0) { ...; process.exitCode = 1; }
    

    patchFailures = missingPatches(磁盘上的文件丢了声明式补丁的 marker)与 unappliablePatches(上游挪走锚点,下次 --update 无法重施加)的去重并集。普通漂移(outdated / modified / UNDOCUMENTED)按设计保持退出 0。

  4. registry 不可达本来就不会非零。 checkComponent 的两条错误路径都只把组件标成 status: 'error',并显式注释"gate 只能指控真实漂移"。所以"容忍 registry 不可达"不需要新写豁免——它本来就已经是退出 0,只要不再吞码即可。

前提成立,且比 issue 描述的更糟一档(建 issue 逻辑是死的)。

改了什么

只动 .github/workflows/shadcn-check.yml:

  • check 步骤去掉 continue-on-error,改为显式捕获退出码(set +e + PIPESTATUS[0]),步骤自身仍恒定退出 0,job 不会因为补丁失效变红——按 PM 裁定:周任务红没人看,进 issue 才进分诊流。

  • 三分类,顺序是"先看证据行,再看退出码":

    类别 判据 处置
    patch 输出含 component(s) with declared local patch failures 走既有建/评论 issue 逻辑,标签不变
    ok 退出 0 且无上述判据(含 registry 不可达) 容忍,不开 issue
    broken 其余任何非零退出(致命错误、调用失败) 也告警——跑不起来的检查不是通过的检查

    判据行优先于退出码是刻意的:消息是证据,退出码是脚本可以另行修订的策略。容忍面只覆盖已识别的良性类别,其余一律告警,免得再挖出一个和被吞退出码同形状的缝。

  • 输出去掉 ANSI(脚本无条件上色),artifact 和 issue 正文因此可读;剥离用的是 perl 自己的转义写法,仓库文件里没有任何裸控制字节(objectstack#4890)。

  • permissions: contents: read / issues: write。这条路径从没跑过,谁也没验证过默认 token 建得了 issue;显式声明后,组织级收紧默认权限也不会把唯一的告警通道悄悄变回空操作。

  • 建 issue 的步骤故意不加 continue-on-error:它就是告警本身,送不出去必须让 job 红。

  • $GITHUB_STEP_SUMMARY 写一段结论,ok 且有 registry 错误时另发 ::warning::——容忍不等于报平安。

analyze 步骤保持原样:component-analysis.js 只有一处非零退出(未捕获崩溃),没有可吞的判决,它的输出是报告的辅助上下文。

干跑证据

从 YAML 里解析出真正要发布的 run,配合桩 pnpm 跑 5 个真实产出的 fixture(不是手写文本)。方向在运行前先写死:

fixture 来源 退出码 预期 实测 outputs
全量种入 cache,46 个组件 identical 0 ok,无告警 class=ok registry_errors=0 alarm=false,无 annotation
本容器直连 registry 失败(46 个 Registry returned no usable file content) 0 ok,容忍但发 warning class=ok registry_errors=46 alarm=false + ::warning::
/tmp 副本里删掉 sheet.tsx 的两个 marker 1 patch class=patch registry_errors=46 alarm=true + ::error::
种入"上游把 Close 改成 Dismiss"的 cache,锚点找不到 1 patch class=patch registry_errors=45 alarm=true + ::error::
移走 manifest 触发 Error loading manifest 1 broken class=broken registry_errors=0 alarm=true + ::error::

5 例全部与预判一致;check.txt 中残留 ESC 字节数 0,临时文件已清理。补丁失效的两类都是在 /tmp 的一次性副本里模拟的,repo 树与 scripts/** 未被触碰。

github-script 的 payload 也做了离线渲染(桩 github/context):新建分支 title 随类别变化、labels 仍是 ['maintenance','shadcn-sync','dependencies']、去重查询仍按 shadcn-sync 标签找已开 issue 并改走 createComment —— 与原块行为一致。

YAML yaml.safe_load 通过;bash -n 通过;node scripts/check-control-bytes.mjs 通过,并额外做了越过该 gate 的自查(0x00-0x1f 与 0x7f 全扫)。本机没有 actionlint / shellcheck,这两项没跑。

**诚实的边界:**真实的定时运行只能由下周一的 cron 或一次手动 workflow_dispatch 证明——建议合并后手动触发一次,顺带验证 token 真的能建 issue。

已知限制(有意保留,未在本 PR 处理)

  • registry 不可达时,"上游挪锚点"这一半根本没执行,本次运行其实什么也没证明。按裁定容忍,只发 warning + summary;是否对"连续 N 周不可达"告警需要跨运行状态,超出本单。
  • job 没有 timeout-minutes:--check 是 46 次串行请求,挂住会静默烧满默认时限。与退出码无关,未在此改。

与 #5803 的关系

不依赖它。分类只读当前脚本已有的输出:Error fetching from registry: / Registry returned no usable file content / component(s) with declared local patch failures。已核对 #5803 在途分支未改动这三处字符串,它新增的 HTTP 状态码错误仍从 fetchUrl reject,落进同一条 Error fetching from registry: 消息里,分类不受影响。

CI-only,无 changeset。


Generated by Claude Code

`continue-on-error: true` 把 `pnpm shadcn:check` 的退出码整个丢掉;下游
"发现更新就开 issue" 的步骤又以 `if: failure()` 为条件,而被容错的步骤
永远不会让 job 变红——两者叠加使该通道从未执行过一次。

#3455 之后退出码只有一个含义:声明式本地补丁失效(磁盘上标记丢失,或上游
挪走锚点导致下次 --update 无法重施加)。普通漂移与 registry 不可达按设计
仍然退出 0。

现在显式捕获退出码并分三类:patch(告警)、ok(含 registry 不可达,容忍)、
broken(其余非零,也告警——跑不起来的检查不是通过的检查),把告警接进既有的
建/评论 issue 逻辑与标签。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectui Ignored Ignored Aug 6, 2026 1:25pm

Request Review

@yinlianghui
yinlianghui marked this pull request as ready for review August 6, 2026 13:51
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 6, 2026
Merged via the queue into main with commit ed03b95 Aug 6, 2026
17 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-5805-shadcn-check-exitcode branch August 6, 2026 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

objectui: shadcn-check.yml 用 continue-on-error 吞掉 shadcn:check 的退出码,该周期任务无法对任何失败告警

2 participants