Storybook 规范化 PR 实战:标题格式、Category/CI/QA 三类标签体系与 Draft PR 工作流
本文基于 Storybook 仓库中的 PR 创建技能文档(.claude/skills/pr/SKILL.md 指向 pr/SKILL.md)及其配套的 PR 模板(.github/PULL_REQUEST_TEMPLATE.md),完整拆解 Storybook 社区提交 Pull Request 的规范:[Area]: [Description] 标题约定、Category / CI / QA 三组标签的选择规则、必须"逐字复制"的 PR 正文模板与手工测试(Manual testing)要求,以及 gh pr create 的 Draft 提交命令。读完你可以按 Storybook 维护者的标准流程,写出一个能正确触发沙箱 CI、满足发版 QA 要求的规范 PR。
技能定位:为 Agent 与贡献者定义的 PR 规范
.claude/skills/pr/SKILL.md 本身只有一行指针内容:
@../../../.agents/skills/pr/SKILL.md
即 Claude 侧的技能文件直接引用了 pr/SKILL.md,其 Frontmatter 声明了技能的使用时机与允许的工具:
name: pr
description: Creates a pull request following Storybook conventions. Use when creating PRs, opening pull requests, or submitting changes for review.
allowed-tools: Bash, Read
从仓库结构看,这是一套面向 AI Agent 的"技能(skill)"体系,pr 技能定义了 PR 的核心规范,周围还有若干协作技能:
- open-pr/SKILL.md:从当前分支发起 Draft PR 的完整工作流(探测 base 分支、交互式询问三类标签、填充模板、创建 PR);
- canary/SKILL.md:为 PR 触发 canary 版本发布;
- update-pr-description/SKILL.md:将 PR 标题/描述与其实际改动做比对并迭代修正;
- handle-pr-comments/SKILL.md:逐条处理 PR 评审意见。
pr 技能是这一族技能中"规范本体"——例如 open-pr 技能明确写道:"Title: [Area]: [Description] — see the pr skill for format and examples."。下面按原技能文档的四个部分(Title format、Labels、PR body、Command)逐一展开。
PR 标题格式:[Area]: [Description]
技能文档对标题的约定非常严格:
[Area]: [Description]
- Area 首字母大写,且不含空格(允许使用连字符);
- 官方给出的示例:
CSFFactories: Fix type exportNextjs-Vite: Add supportCLI: Fix automigrate issue
Area 对应的是仓库内的功能域(如 CSF Factories、Nextjs-Vite 框架适配器、CLI 等),Description 用一句话概括改动意图。这种格式的实战价值在于:标题前缀让维护者在 PR 列表里即可按模块过滤问题,也便于 changelog 聚合与检索。
标签体系:Category / CI / QA 三组标签各选其一
Storybook 要求每个 PR 必须打上三组标签,每组只选一个。这对应了模板中 "Checklist for Maintainers" 的要求:PR 必须包含其中一个类别标签,并通过 ci:* 标签声明要跑哪套沙箱,通过 qa:* 标签声明发版期是否需要人工 QA。
Category(必填,9 选 1)
| 标签 | 含义 | 是否进入 changelog |
|---|---|---|
bug |
修复错误行为 | 是 |
maintenance |
面向用户的维护性改动 | 是 |
dependencies |
升级/降级依赖 | 是 |
build |
内部构建/测试工具更新 | 否 |
cleanup |
小型代码清理 | 否 |
documentation |
纯文档改动 | 否 |
feature request |
新功能 | 是 |
BREAKING CHANGE |
破坏兼容性 | 是 |
other |
以上均不适用 | — |
其中 build / cleanup / documentation 三类的共同特征是"不出现在发布 changelog 中"——这一信息直接来自 PULL_REQUEST_TEMPLATE.md 的 Available labels 折叠区,技能文档与其逐字对应。
CI(必填,选 1)
| 标签 | 含义 |
|---|---|
ci:normal |
标准沙箱集合,绝大多数代码改动的默认选择 |
ci:merged |
合并后的更大沙箱集合 |
ci:daily |
每日沙箱集合;当改动影响 prerelease 沙箱、或钉在较旧框架/React 版本的沙箱时使用 |
ci:docs |
纯文档改动(配合 documentation 类别使用) |
这组标签不是凭空设定的,它与仓库源码直接挂钩。PR 模板的 Maintainers 检查项写明:
make sure to add
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.ts
在 sandbox-templates.ts 中可以看到三套集合的真实定义:
export const normal: TemplateKey[] = [ ... ] // L1251
export const merged: TemplateKey[] = [ // L1283
...normal, ...
]
export const daily: TemplateKey[] = [ // L1295
...merged, ...
]
export const templatesByCadence = { normal, merged, daily }; // L1320
从源码结构看,三套集合是逐层包含关系(merged 展开 normal,daily 再展开 merged),因此"默认 ci:normal、影响面扩大到 prerelease/旧框架版本沙箱时升级到 ci:daily"的规则与源码中集合的嵌套设计完全吻合。
QA(必填,选 1):qa:needed / qa:skip
这两个标签告诉发版团队在下一个 minor 版本发布前是否需要针对该 PR 做人工 QA:
qa:needed— 发布前必须有人工验证;qa:skip— 无需逐 PR 人工 QA。
技能文档给出了一套明确的启发式判断规则(这是该规范中最具经验价值的部分):
- 用户明确要求发版前人工 QA →
qa:needed - 属于一个整体 QA 的大项目的一部分(不按 PR 逐个验证)→
qa:skip - 触碰路径处理、文件系统、或任何在 Windows 上可能出问题的代码 →
qa:needed - 横跨多个模块、必须协同工作的复杂改动 →
qa:needed - 位于中心/共享代码、高副作用风险的小改动(例如共享 UI 的布局 CSS)→
qa:needed - 简单直接的小改动 →
qa:skip - 拿不准 → 直接询问用户是否需要发版前人工 QA
PR 正文:逐字复制模板,保留全部 HTML 注释
技能文档对 PR body 的要求只有一句话,但执行细节很关键:
Read
.github/PULL_REQUEST_TEMPLATE.mdfrom the repository root. Copy that template EXACTLY, including all HTML comments (<!-- ... -->). Fill in the relevant sections based on the changes, but keep all comments intact.
也就是说,正文必须基于 .github/PULL_REQUEST_TEMPLATE.md 原样复制,包括所有 HTML 注释占位,然后只填写对应小节。该模板的完整骨架如下:
Closes #
<!-- If your PR is related to an issue, provide the number(s) above; ... -->
## What I did
<!-- Briefly describe what your PR does -->
## Checklist for Contributors
### Testing
#### The changes in this PR are covered in the following automated tests:
- [ ] stories
- [ ] unit tests
- [ ] integration tests
- [ ] end-to-end tests
#### Manual testing
> [!CAUTION]
> This section is mandatory for all contributions. ...
### Documentation
- [ ] Add or update documentation reflecting your changes
- [ ] If you are deprecating/removing a feature, make sure to update MIGRATION.MD
## Checklist for Maintainers
- [ ] ... add `ci:normal`, `ci:merged` or `ci:daily` GH label ...
- [ ] Declare whether manual QA will be needed ... through `qa:needed` or `qa:skip`
- [ ] Make sure this PR contains **one** of the labels below: ...
### 🦋 Canary release
<!-- CANARY_RELEASE_SECTION -->
...
<!-- CANARY_RELEASE_SECTION -->
<!-- BENCHMARK_SECTION -->
<!-- BENCHMARK_SECTION -->
几个填写要点:
Closes #开头:关联 issue 编号,多个 issue 用 "closes #1000, closes #1001" 分开写;- 模板注明所有 PR 提交到
next分支(除非仅针对当前发布分支)——维护者会在发版流程中把 bug 与文档修复 cherry-pick 进main,贡献者不必操心; - 自动测试勾选:在 stories / unit / integration / end-to-end 四个复选框上勾选实际覆盖的类型;
- Documentation 小节:若改动涉及文档更新、或废弃/移除功能需同步 MIGRATION.md,则勾选对应项;
- Maintainers 检查项保持不勾选:
ci:*、qa:*和类别标签是通过 PR 标签体现的,模板中的维护者检查框留给维护者操作(配套的 update-pr-description/SKILL.md 也要求"更新复选框状态时不要删除 canary release 小节")。
Manual testing:必填项,写给另一位维护者看
技能文档对 Manual testing 小节的要求最为具体:
- 必填,绝不允许留空。模板中甚至用
> [!CAUTION]强调:"This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly." - 写给另一位维护者看,而不是记录你自己是怎么测的。模板注释原文:"Do not describe how YOU tested the PR code, but how a separate maintainer should do so."
- 每一步应当:
- 清晰、易跟随;
- 尽量给出可直接复制粘贴的 shell 命令;
- 明确说明要检查的预期行为(而不是"check it works"这种空话);
- UI 改动要链接到具体的 story;
- 列出最可能回归、值得重点关注的区域。
- 先自己跑一遍这些步骤("Verify your own steps first — run through them locally before opening the PR")。
模板注释中给的标准示例风格:
1. Run a sandbox for template, e.g. `yarn task --task sandbox --start-from auto --template react-vite/default-ts`
2. Open Storybook in your browser
3. Access X story
附:Chromatic 预览链接格式
需要展示 UI 效果时,可以在 CI 完成后链接已发布的 Chromatic Storybook(技能文档特别提示:CI 跑完之前链接不可用,PR 刚打开时不要急着贴)。两种常用入口的 URL 模板:
- 内部 UI(Internal UI):
https://<branch>--635781f3500dd2c49e189caf.chromatic.com/?path=/story/<story_id> - React Vite TS 沙箱:
https://<branch>--630511d655df72125520f051.chromatic.com/?path=/story/<story_id>
其中 <branch> 要替换为 Chromatic 归一化后的 slug(特殊字符替换为连字符,如 feature/foo → feature-foo),<story_id> 为 story 路径(如 example-button--primary)。
关于 635781f3500dd2c49e189caf 这个内部 UI 项目 ID,可以从仓库中印证:code/chromatic.config.json 里声明了 "projectId": "Project:635781f3500dd2c49e189caf",与技能文档中的链接前缀一致。
提交命令:始终以 Draft 模式创建 PR
规范的最后一步是命令本身——PR 必须始终以 draft 模式创建:
gh pr create --draft --title "<Area>: <Description>" --body "<FILLED_TEMPLATE>" --label "<category>,<ci>,<qa>"
其中 <FILLED_TEMPLATE> 是上文"逐字复制并填写"后的模板内容,--label 的值是三组标签各选一项、以英文逗号拼接(如 bug,ci:normal,qa:skip)。配套的 open-pr/SKILL.md 给出了等价的完整工作流版本:先 git fetch origin 并运行 detect-base-branch.sh 探测 base 分支(支持栈式 PR,回退到 next),再用 heredoc 方式传多行 body、追加 --base 与 --assignee @me:
gh pr create \
--draft \
--base "<detected-base>" \
--title "<Area>: <Description>" \
--body "$(cat <<'EOF'
<FILLED_TEMPLATE>
EOF
)" \
--assignee @me \
--label "<type>,<ci>,<qa>"
PR 创建后,open-pr 技能还会询问是否需要触发 canary 发布;canary/SKILL.md 说明了触发方式(gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>)及 canary 版本号的预测格式 0.0.0-pr-<PR_NUMBER>-sha-<SHORT_SHA>——这与 PR 模板中 "🦋 Canary release" 小节的说明一致。
速查清单
- 标题:
[Area]: [Description],Area 首字母大写、无空格(连字符可用); - 类别标签(9 选 1):
bug/maintenance/dependencies/build/cleanup/documentation/feature request/BREAKING CHANGE/other,注意build、cleanup、documentation不进 changelog; - CI 标签(1 选 1):默认
ci:normal;影响 prerelease 或钉住旧框架/React 版本的沙箱用ci:daily;纯文档用ci:docs。对应沙箱集合定义见 sandbox-templates.ts; - QA 标签(1 选 1):按"路径/文件系统/Windows 风险、跨模块复杂改动、共享代码高副作用 →
qa:needed;简单改动、整体 QA 的大项目 →qa:skip"判断,拿不准就问用户; - 正文:从 .github/PULL_REQUEST_TEMPLATE.md 逐字复制(含 HTML 注释),勾选自动测试类型,Manual testing 必填且写给别的维护者,自己先跑通一遍;
- 命令:
gh pr create --draft --title ... --body ... --label "<category>,<ci>,<qa>",永远 draft 起步; - 目标分支:提交到
next分支(除非仅针对当前发布)。
这套规范的本质,是把"CI 触发策略、changelog 归类、发版 QA 排期"三个发版流程关注点前移到了 PR 创建时刻——贡献者打的三个标签,恰好就是后续 CI 选择沙箱集合、release 流程筛选 changelog 条目、QA 团队排定人工验证任务的直接输入。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00