
Qwen Code 用户向发布说明 v2主题化双语摘要与 PR 截图的工程实践【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code导读本文基于 Qwen Code终端 AI 编程代理仓库中的设计文档 2026-08-15-user-facing-release-notes.md剖析其发布说明体系的第二次重构把按变更类型堆砌的 PR 列表升级为按用户可见主题组织的双语摘要Themed Digest并安全附加 PR 正文截图。读完本文你将掌握这套发布说明流水线的完整链路GitHub Actions → 模型调用 → Markdown 渲染 → CHANGELOG 同步、v2 的 JSON 契约与校验规则、图片提取的安全边界以及逐级降级的容错设计。背景为什么 v1 发布说明对用户不友好Qwen Code 的稳定版发布说明此前由 .github/workflows/finalize-release.yml 中的finalize-release.yml驱动调用 scripts/generate-release-notes.js 生成。其结果是典型的开发者视角 PR 墙按变更类型分组而非按用户关注领域分组条目被归入 Features / Bug Fixes / Performance / Documentation / Internal Changes 等 commit-type 区块用户更关心的 Web Shell、Desktop、多智能体、模型支持等产品领域被拆散风格混杂模型生成的一句话摘要如 Adds standard OpenTelemetry…与 raw conventional-commit 标题如feat(serve): bound daemon ACP NDJSON buffers并存——后者是摘要校验失败时的回退读起来像未经编辑的工具输出高亮重复全文Highlights 几乎逐字重复完整列表中的条目只增加篇幅没有形成第二层抽象没有中文版尽管存在大量中文用户UI 变更无图PR 正文已有 Before/After 截图但发布说明不展示。设计文档给出了当时的实测基线2026-08-15v0.21.11 共列出 49 个 PR其中仅 2 个 PR 正文包含图片约 4%最近 60 个已合并 PR 中有 3 个。这一数据直接决定了后续设计取向图片支持是尽力而为的装饰绝不是结构。目标与非目标设计文档明确划定了这次重构的边界目标用主题化摘要取代按类型分组的 PR 列表——模型将变更归入用户可见主题每个主题带简短导语和条目增加中文摘要与英文亮点和主题镜像对应PR 级列表保持英文PR 标题按惯例就是英文尽可能从 PR 正文附加截图到摘要条目缺失时静默降级不丢失信息、不牺牲健壮性——完整 PR 列表仍以可折叠附录存在模型的每条失败路径都保留今日输出。非目标不把完整 PR 列表翻译成中文不改变 nightly/preview 说明它们从不走 AI 路径不从不属于已合并 PR 正文的其他来源取图不修改release.yml中创建 GitHub Release 的步骤它仍立即发布 GitHub 自动生成说明finalize 稍后重写。发布流水线总览从 .github/workflows/release.yml 与 .github/workflows/finalize-release.yml 可以看到整条链路分为三段release.yml通过gh api …/releases/generate-notes以上一 tag 为锚点生成 GitHub 自动说明 → .github/scripts/cap-release-notes.mjs 截断 →gh release create。此时发布的是 GitHub 原生说明finalize-release.yml触发条件为release事件的published或手动workflow_dispatch仅处理形如vX.Y.Z的稳定 tag运行 scripts/generate-release-notes.js解析 GitHub 生成条目 → 通过 GraphQL 拉取 PR 正文与 labels → 调用模型每批 8 条生成摘要再生成高亮→ 渲染 Markdown →gh release edit原地更新。产物以!-- qwen-release-notes:v1 --标记开头npm run changelog即 scripts/generate-changelog.js从 GitHub Releases API 重建 CHANGELOG.md凡正文以该标记开头的版本整体内嵌标题降一级。finalize 工作流中还包含给已合并 PR 打 released-in 评论、重新生成 CHANGELOG.md 并提交、创建 release 分支合回 main 的 PR 等步骤。v2 设计明确不改动workflow、package.json 与cap-release-notes.mjs正文体量远低于 120,000 字符上限脚本 CLI 契约不变。模型内容扩展摘要双语化与新增 themes 调用v2 的核心是让模型输出从一句话摘要升级为三层结构。设计文档规定 scripts/generate-release-notes.js 保持原有的批量摘要调用与高亮调用新增一次themes调用。摘要summaries响应升级{summaries:[{pr:8780,summary:…,summaryZh:…}]}summary英文规则不变≤180 字符、纯文本summaryZh简体中文≤120 字符命令、设置、产品名等技术标识符保留英文某条summaryZh无效时回退为该条目的英文摘要并输出警告——中文区块不会整段丢失。高亮highlights增加 textZhtextZh与summaryZh限制相同≤120 字符缺失时同样回退英文。新增 themes 调用输入为每条条目的编号、类别、中英文摘要响应格式{ themes: [ { title: Web Shell, titleZh: Web Shell, intro: …≤200 chars, optional…, introZh: …, items: [8780, 8973] } ] }校验规则与现有 summary/highlight 防护一致源码 validateThemes≤8 个主题MAX_THEMES主题标题 ≤40 字符THEME_TITLE_MAX_LENGTHitems只能引用已知 PR且一个 PR 至多出现在一个主题中重复分配直接抛错模型未分配的主题被收集进确定性的兜底主题渲染在最后Other Changes / 其他变更源码中的CATCH_ALL_THEME_TITLE常量见 generate-release-notes.js。三个调用共享同一套 retry/backoff/deadline 机制。值得注意的 token 预算设计源码 promptForsummaries 与 highlights 固定 4096 token——为每批最多 8 条 ×英文中文留足余量themes 调用按条目数线性增长maxTokens min(8192, max(4096, 1024 entries.length * 96))。源码注释解释了原因主题输出以散文为主加裸 PR 编号预算增长缓慢设置上限是为了防止大版本请求超过常见模型输出上限——过大的max_tokens会触发不可重试的 HTTP 400从而丢掉整个摘要。模型调用侧 createOpenAiCompleter 还实现了AbortSignal.timeout单次超时默认 180s、指数退避重试默认 2 次、基延迟 2s、30 分钟总 deadline且只有 429/5xx/网络级错误才重试内容校验类错误确定性失败直接抛出避免重复相同 prompt 浪费预算。v2 渲染布局设计文档给出了 v2 的完整骨架源码 renderReleaseNotesV2 逐行实现!-- qwen-release-notes:v2 -- ## Highlights ## Breaking Changes ← 存在时双语英文条目 缩进中文行 No known breaking changes. 保持纯英文 ## Theme title ← intro 条目条目下可附截图 ## Theme title … --- ## 中文摘要 ### 亮点 ← 中文高亮 ### theme titleZh ← introZh 中文条目 detailssummaryComplete Change List (N pull requests)/summary ### Features - web-shell: improve compact tool activity (#8973) by ytahdn … /details ## New Contributors **Full Changelog**: …compare/v0.21.11...v0.21.12四个关键决策块状布局而非交错布局英文摘要整体在上一条---分隔线然后是## 中文摘要。每种语言的读者各读一个连续区块GitHub 目录与发布页保持可扫读主题用##与现有章节同级中文主题在## 中文摘要之下用###附录使用规范化原始标题而非模型摘要剥离type(scope):前缀得到scope: description与 generate-changelog.js 的formatEntry同规则保留by author与 co-author 署名。这确定性地消灭了风格混杂问题也让附录不再依赖模型可用性。类别子标题Features / Bug Fixes / …保留——附录仍是开发者视图高亮保持 v1 形态文本 PR 链接不做加粗技巧因为高亮文本本身已点名能力作者署名只留在附录摘要条目只显示文本 PR 链接保持行短。源码还处理了一个微妙问题displaySummary会在摘要等于原始标题即校验回退时走normalizeAppendixTitle规范化让降级条目与附录保持统一外观Breaking Changes 条目只在双语专区内渲染即使模型把它们分进主题也会被 renderReleaseNotesV2 过滤掉避免重复。PR 截图提取确定性解析与安全白名单图片提取完全不涉及模型是确定性的源码 extractImages来源PR 正文已由 GraphQL 查询取回Markdownalt、img srcurl、裸图片 URL 三种语法宿主白名单仅 httpsgithub.com/user-attachments/、user-images.githubusercontent.com、private-user-images.githubusercontent.com以及raw.githubusercontent.com——但必须固定到40 位十六进制 commit-SHA。设计文档的解释很关键分支 ref 在发布后仍可变其所有者可以在已发布的 release 中偷换图片任何其他宿主一律忽略——发布正文绝不能成为 hotlinking 载体。camo 图片代理被刻意排除尽管 GitHub 也托管它但其 HMAC 能签名任意外部 URL 且与仓库无关放行它就等于重新放行所有被排除的宿主数量上限每条目最多 2 张MAX_IMAGES_PER_ENTRY、每个 release 最多 8 张MAX_IMAGES_PER_RELEASE在渲染时按条目顺序消耗全局预算渲染位置图片只出现在摘要条目之下绝不出现在折叠附录里。源码 isAllowedImageUrl 的安全细节值得单独指出它在解析后的 URL上做判定而非字面字符串——GitHub 的 fetcher 会把%2F解码为路径分隔符并在服务前解析点段CommonMark 渲染时会剥离\/转义所以这些形态在段匹配前就被拒绝URL 带用户名/密码/端口、路径含空段/./..、含%2f或反斜杠一律拒绝。raw.githubusercontent.com要求路径形状为owner/repo/40-hex-SHA/…且 SHA 段严格匹配[0-9a-f]{40}。实测覆盖率约 4% 的 release PR 含图因此提取器必须廉价、缺席必须不可见无图时输出与无图情形完全一致。降级阶梯每级失败都有明确结果设计文档用一张表定义了完整的容错策略源码 generateAiContent 逐项实现失败场景结果无模型配置今日的 v1 渲染仅标题摘要批失败与今日相同的熔断使用标题高亮调用失败摘要不含高亮区块themes 调用失败整篇说明回退到 v1 渲染单条summaryZh无效该条目在中文摘要中显示英文主题 intro 无效丢弃 intro保留主题本身任何地方都没产出中文完全省略中文摘要区块图片提取无结果无图片行实现细节上批量摘要连续失败maxConsecutiveBatchFailures默认 3次后打开熔断circuit breaker剩余条目直接用 PR 标题、并跳过后续高亮与 themes 调用——注释解释这是模型侧宕机而非变慢不应再为剩余批次逐个付费。中文区块的开关不是看原始模型输出而是由实际渲染出的内容推导renderReleaseNotesV2只在存在非回退中文文本时才输出## 中文摘要避免中文标题下重复英文摘要的误导。每一级降级都会通过::warning::注解输出经 escapeWorkflowCommand 转义%/CR/LF防止模型文本伪造 runner 命令在 Actions 运行中可见但不会让发布失败同时 appendDegradedStepSummary 会把警告写入 GITHUB_STEP_SUMMARY 辅助文件。CHANGELOG.md 同步v2 正文的变换规则scripts/generate-changelog.js 现在接受v1与v2两种标记CURATED_RELEASE_MARKER_RE。v1 正文保持今日的逐字内嵌v2 正文在 transformCuratedLine 中做三层处理解开detailssummary…/summary为普通标题并丢弃闭合标签——纯文本 changelog 没有折叠能力标题以##级别发出经过统一降级后落在###与 v1 的## Complete Change List降级后同级保证同一文件内 v1/v2 版本骨架一致丢弃图片行和中文摘要前的---分隔线属于 release 页面装饰其余行照常执行既有标题降级##→###等。文件影响面与测试覆盖设计文档列出的改动面很小、边界清晰文件变更scripts/generate-release-notes.jsprompts、themes 调用、图片提取、v2 渲染scripts/generate-changelog.jsv2 标记 details/图片变换scripts/tests/generate-release-notes.test.js新增覆盖scripts/tests/generate-changelog.test.jsv2 内嵌覆盖不涉及 workflow、package.json 或cap-release-notes.mjs的改动。仓库中 scripts/tests/generate-release-notes.test.js 对 v2 主题、summaryZh/textZh/titleZh回退、图片白名单isAllowedImageUrl、中文摘要开关等路径均有覆盖相关匹配 144 处是验证这套设计行为的最佳入口。结语v2 发布说明是一次典型的为读者重构模型从工具化摘要器升级为内容组织者主题划分 双语图片从 PR 内嵌资产升级为发布页可视信息且严格限定宿主降级阶梯保证任何一步失败都不阻塞发布。对于任何维护面向终端用户的开源项目、希望改进 Release Notes 体验的团队本文的契约设计JSON 响应 严格校验、安全边界图片白名单 commit-SHA 固定与容错思想逐级降级 warning 可见性都可以直接借鉴在 Qwen Code 仓库内从 .github/workflows/finalize-release.yml 的调用入口到 scripts/generate-release-notes.js 的 v2 渲染与 scripts/generate-changelog.js 的变换规则均可按上述路径深入阅读验证。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考