Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

Bundle Analysis:被取消的运行会发出一条 ❌ FAIL 评论,三项指标全为空——每个连推两次的 PR 都会收到假警报 #3152

Closed

Description

@os-zhuang

.github/workflows/performance-budget.yml 在运行被 取消 时,仍会向 PR 发一条写着 ❌ Console Performance Budget / Status: FAIL 的评论,而实际上预算从未被测量过。

复现

在一个 PR 上连续推两次提交(间隔短于一次完整构建)。工作流设了:

concurrency:
  group: bundle-analysis-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

第二次推送取消掉第一次运行;被取消的那次仍会发出 FAIL 评论。

实例

PR #3150 收到的评论:

## ❌ Console Performance Budget

| Metric | Value | Budget |
|--------|-------|--------|
| Main entry (gzip) | ** KB** |  KB |
| Entry file | `` | — |
| Status | **FAIL** | — |

对应运行 30699128418(head 006886f4),其 conclusion 是 cancelled,不是 failure。同一分支上取代它的运行是 30699202638。main 上该工作流最近 8 次连续 success,其中包含本 PR 的 base efd77672。

机制

budget 步骤有三条退出路径,其中只有「超预算」那条会先写 output 再 exit 1:

echo "gzip_kb=$GZIP_KB" >> "$GITHUB_OUTPUT"
echo "budget_kb=$MAX_ENTRY_GZIP_KB" >> "$GITHUB_OUTPUT"
echo "entry_file=$(basename $ENTRY_FILE)" >> "$GITHUB_OUTPUT"
# ... 之后才判断是否超预算并 exit 1

另外两条(dist 目录不存在、找不到 JS 文件)以及被取消的情况,都不会写任何 output。

发评论的步骤是 if: ... && always(),于是在这些情况下照常执行,而渲染逻辑把「空」等同于「失败」:

const status = '${{ steps.budget.outputs.budget_status }}';   // ''
const icon = status === 'pass' ? '✅' : '❌';                   // ❌
| Status | **${status === 'pass' ? 'PASS' : 'FAIL'}** | — |    // FAIL

三项指标同时为空,正是「从未测量」的可判别信号——真正的超预算必然带着数字。

影响

一条断言 FAIL 的评论,其正文自身就证明它什么都没测到。读者要么被误导去追一个不存在的体积回归,要么——更糟——学会无视这个门禁发出的 FAIL,那么真正的预算超标也会被一并无视。

size-report.md 那半部分能正常生成(它读 packages/*/dist,包构建早已完成),使这条评论看起来更像一份可信的完整报告。

建议方向

区分「测量到了且超标」与「压根没测到」,不要让后者渲染成 FAIL。可选:发评论步骤跳过 budget_status 为空的情况;或在取消/构建失败时改发一条说明未测量的中性文案。两者都不应削弱真实超标时的 FAIL。

(发现于 v17 验收批次;#3150 本身不受影响,权威运行另有其一。)

Activity

  1. os-zhuang commented on Aug 1, 2026

    @os-zhuang
    ContributorAuthor

    补一组对照证据——同一个 PR、同一份代码,两次运行给出相反的结论:

    运行 30699128418(cancelled) 运行 30699202638(success)
    Status ❌ FAIL ✅ PASS
    Main entry (gzip) (空) 28.1 KB / 350 KB
    Entry file (空) index-BRKCVm_4.js

    实测值 28.1 KB,只用掉预算的 8%——离超标差着一个数量级。那条 FAIL 与体积毫无关系。

    还有一处佐证被取消运行是半途截断的:它附带的 size report 少了 7 个包(app-shell、plugin-calendar、plugin-designer、plugin-gantt、plugin-kanban、plugin-report、plugin-view),完整运行里它们都在。Generate package size report 那步是 if: always(),于是在取消时对着一个只构建了一部分的 packages/*/dist 跑完并输出——报告看起来完整,实际不是。这让那条假 FAIL 更可信,也更难被识破。


    Generated by Claude Code

  2. self-assigned this
    on Aug 2, 2026
  3. os-zhuang commented on Aug 2, 2026

    @os-zhuang
    ContributorAuthor

    认领:PM 循环第 1 轮(分片:objectui 整仓)
    会话:session_01PRJtkgUAaVG11FsJQbvZWA
    分支:claude/issue-3152-bundle-analysis-cancelled-fail
    Worktree:objectui-issue-3152

    分诊补充:按正文建议方向执行——「测量到且超标」才渲染 FAIL;budget_status 为空(取消/构建失败/未测量)时不发 FAIL 评论(跳过或改发中性说明,以不削弱真实超标信号为准);评论中的对照证据(半截 size report)一并处理:if: always() 的报告步骤在未完整构建时不应输出看似完整的报告。


    Generated by Claude Code

  4. os-zhuang commented on Aug 2, 2026

    @os-zhuang
    ContributorAuthor

    验收:ACCEPT → PR #3198(CI 全绿,进入合并)。

    交付内容:① 发评论/生成报告的步骤 always() → !cancelled(),被取消的运行不再发任何评论;② FAIL 只在「测量到且超标」时渲染——budget_status 白名单 + gzip/预算/入口文件三项数字齐全,缺任何一项按「未测量」处理;③ 「未测量」改发中性说明(明确写 This is not a budget violation,附两步 outcome 与原因);④ 半截 size report 修复:仅在包全部构建成功后生成,缺失时明说而不是静默省略;⑤ 渲染逻辑搬进 scripts/render-budget-comment.mjs,17 个单测覆盖,其中 6 个 pin test 钉住工作流本身(禁 always()、env 契约、budget_status 三态)。

    流程备注:开发 agent 在容器重启中丢失了最终报告通道,但 PR 与验证证据完整,按「对 GitHub 实况验收」通过。越界发现已核实:#3197(ci-cd-pipeline.md 三处与工作流脱节),已入本地队列。


    Generated by Claude Code

  5. added 2 commits that reference this issue on Aug 3, 2026
    4f66d83
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions