Skip to content

ci(showcase-smoke): 诊断产物按真实 outputDir 上传,失败无产物即报错 (#4931 第 2 缺陷) - #5913

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-4931-smoke-artifacts
Aug 6, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/issue-4931-smoke-artifacts

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Part 2 of #4931(第 1 缺陷待本修复产出的 trace 到位后另行诊断)

Showcase Smoke 的诊断产物从未上传成功。本 PR 只修这一条(#4931 的第 2 缺陷),
不碰第 1 缺陷:探测条件与 e2e/showcase-smoke.spec.ts 一行未动。

实测到的真实成因(比 issue 描述更糟一层)

issue 说「路径写偏了:配的是 playwright-report/,Playwright 实际写在
test-results/」。按 origin/main 实测,前半句成立,但错配的性质不是「偏了一层
目录」,而是指向一个在 CI 下永远不会被创建的产物:

事实 测法 结果
outputDir 未声明 → 取默认 test-results/,按 config 所在目录解析 playwright test --list --reporter=json,读 config.projects[].outputDir /…/examples/app-showcase/test-results
CI 的 reporter 列表里没有 html reporter CI=1 求值 playwright.config.ts [["github"],["list"]] —— 两个都只写 stdout
retries 在 CI 下为 1 同上 1(⇒ 存在「重试后才绿」的状态)
path 按仓库根解析,不受 working-directory 影响 失败 run 的 warning 原文回显了整条 examples/app-showcase/… 见下
if-no-files-found 缺省即 warn,可取 error actions/upload-artifact@v7 的 action.yml warn(default)/ error / ignore

也就是说:playwright-report/ 是 html reporter 的输出目录,而 CI 从来不加载 html
reporter,所以那个目录不是「装错了东西」,而是空气。叠上 if-no-files-found
的缺省 warn,错配只降成一条 warning —— run
30796529117
(2026-08-03,3 failed)的日志:

##[warning]No files were found with the provided path: examples/app-showcase/playwright-report/. No artifacts will be uploaded.

同一 run 的 artifacts 总数 0,而「Upload report on failure」这一步的
conclusion 是 success。而同一份日志里 Playwright 自己把落点报得很清楚:

attachment #3: trace (application/zip)
test-results/showcase-smoke-surface-renders-cleanly-Command-Center-chromium-retry1/trace.zip

于是每一次失败的截图 / trace / error-context 都随 runner 回收丢掉 —— 这正是一个
半数失败的探针长期无从定位的直接原因。

改动(仅 .github/workflows/showcase-smoke.yml)

  1. 上传路径对齐真实 outputDir:examples/app-showcase/test-results/。
    没有把 playwright-report/ 一并列上:它今天不可能有内容,列上等于留一条
    永远为空的死声明,还会让下一个读者以为存在一份可浏览的 HTML 报告。补 html
    reporter 属 playwright.config.ts 面的改动,超出本单文件面,已按
    Prime Directive chore: version packages #10 另行立单(见下)。
  2. 失败路径 if-no-files-found: error,且前提从宽泛的 failure() 收窄到
    failure() && steps.smoke.outcome == 'failure'(给 smoke 步骤加了 id: smoke)。
    理由是两侧都要成立:smoke 失败就一定留下了证据,空的 test-results/ 本身
    就该报警;但若倒在更早的步骤(pnpm install / vendor Console),这里本来就
    无物可收,不该再叠一条误导性的红。条件里保留 failure() 不是装饰 ——
    GitHub 会给任何不含状态函数的 if: 套一层隐式 success(),写成
    if: steps.smoke.outcome == 'failure' 会让条件永远为假。这条推理正是
    scripts/check-workflow-status-functions.mjs 写下的规则(该 gate 的 scope 有意
    只覆盖 job 级,step 级在其射程外,所以这里靠人写对 + 注释留证)。
  3. 新增一条绿色路径上传(if: success() + if-no-files-found: ignore,永远
    不会把夜跑弄红):CI 下 retries: 1,「重试后才绿」的 run 会在
    test-results/…-retry1/ 留下第一次尝试的 trace,而那恰是第 1 缺陷(图表面板
    时红时绿)最需要的证据。只在 red 时收会永远错过 flaky-green —— 而最近三次
    夜跑(08-04/05/06)都是绿,下一次是绿的概率不低,所以这条不是锦上添花:
    它决定了「下一次夜跑产出 artifacts」这个重启条件在绿色路径上也能满足。

产物名一并从 showcase-smoke-report 改为 showcase-smoke-diagnostics /
showcase-smoke-flaky-diagnostics:收的是原始诊断件,不是 report。全仓无任何
消费方引用旧名(仅本 workflow 自身出现过)。

验证与验证边界

workflow 无法本地执行,所以把能测的都测了,不能测的写清边界:

  • 仓内没有 actionlint(which actionlint 空,node_modules/.bin 无),故以
    YAML 解析 + 步骤级断言替代:11 个 step 全部解析,两条上传步骤的
    if / path / if-no-files-found 逐字回读一致。
  • pnpm check:workflow-status-functions:✓ --self-test: 34 assertions +
    OK (scanned 22 workflow file(s), 39 job(s), 21 job-level if: …)。
  • pnpm check:nul-bytes:OK (scanned 5704 tracked text file(s));另对改动文件
    做了控制字节自扫,clean。
  • 路径与 reporter 结论全部来自 Playwright 自身求值(上表),不是照抄 issue 的
    猜测,也不是照抄文档。
  • 边界:workflow_dispatch 触发器本就存在,但手动跑一次要 14 分钟并且只有
    在 smoke 恰好失败时才能验证 error 分支;真实产物验证发生在下一次夜跑
    (每日 07:00 UTC)。若那次是绿,验证的是第 3 条(flaky 分支或静默跳过);若是
    红,验证的是第 2 条(artifacts 非空)。
  • 无 changeset:改动只在 .github/,不发布任何东西 ⇒ 打 skip-changeset。

范围与后续


Generated by Claude Code

Showcase Smoke 的上传步骤配的是 examples/app-showcase/playwright-report/,
而这个目录在 CI 下从来不会被创建 —— examples/app-showcase/playwright.config.ts
的 reporter 是 `[['github'], ['list']]`(实测 CI=1 求值),两个都只写 stdout,
没有 html reporter。于是不是「路径写偏了一层」,而是「路径指向一个不存在的
产物」。加上 upload-artifact 的 `if-no-files-found` 缺省为 warn,错配只降成
一条 warning:run 30796529117(2026-08-03,3 failed)的日志里是

  ##[warning]No files were found with the provided path:
  examples/app-showcase/playwright-report/. No artifacts will be uploaded.

该 run 的 artifacts 总数为 0,上传步骤自身仍判绿 —— 每一次失败的截图、trace、
error-context 都随 runner 回收丢掉,这正是一个半数失败的探针长期无从定位的
直接原因。

改动(仅本 workflow 文件):

- 上传路径改为 examples/app-showcase/test-results/ —— 由 Playwright 自己解析
  确认的 outputDir 绝对路径落点(config 未声明 outputDir,取默认值并按 config
  所在目录解析);upload-artifact 的 `path` 按仓库根解析,故保留完整前缀。
  未把 playwright-report/ 一并列上:它今天不可能有内容,列上等于留一条永远
  为空的死声明。补 html reporter 属 config 面改动,已另行立单。
- 失败路径 `if-no-files-found: error`,并把前提从宽泛的 `failure()` 收窄到
  `steps.smoke.outcome == 'failure'`:smoke 失败就一定留下了证据,空的
  test-results/ 本身该报警;而更早的步骤倒下时本就无物可收,不该再叠一条
  误导性的红。条件保留 `failure()` 是因为不含状态函数的 `if:` 会被套上隐式
  `success()`,那样条件永远为假。
- 新增一条绿色路径上传(`ignore`,不会把夜跑弄红):CI 下 `retries: 1`,
  「重试后才绿」的 run 会在 test-results/…-retry1/ 留下第一次尝试的 trace,
  而那恰是第 1 缺陷最需要的证据 —— 只在 red 时收会永远错过 flaky-green。

验证边界:workflow 无法本地执行。已做 YAML 解析 + 步骤断言、
pnpm check:workflow-status-functions、pnpm check:nul-bytes,并用 Playwright
自身求值确认 outputDir/reporter/retries;真实产物验证发生在下一次夜跑。

本 PR 只修第 2 缺陷,不动探测条件与 spec 文件,故不 Close 本单。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GX3sL71LFq8m2usg6VqTSE
@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)
objectstack Ignored Ignored Aug 6, 2026 11:30am

Request Review

@os-zhuang os-zhuang added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed ci/cd labels Aug 6, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review August 6, 2026 11:38
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 6, 2026
Merged via the queue into main with commit 18d0695 Aug 6, 2026
27 of 28 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-4931-smoke-artifacts branch August 6, 2026 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants