前端UI组件【免费下载链接】handsontableJavaScript Data Grid / Data Table with a Spreadsheet Look Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡项目地址https://gitcode.com/gh_mirrors/ha/handsontable点击查看免费下载Handsontable 是一个用 JavaScript 编写的电子表格风格数据网格组件仓库中同时维护着handsontable核心包与 React、Vue、Angular 三大框架封装wrappers/。在这样一个多包、多 PR 并行开发的仓库里数百个开发者同时修改同一个CHANGELOG.md极易产生合并冲突。为此Handsontable 采用了一套「临时 JSON 条目 脚本编译 CI 门禁」的 changelog 管理机制每个 PR 先在 .changelogs/ 目录下生成一个独立的.json条目文件发布前再由 bin/changelog 统一编译进根目录的CHANGELOG.md。读完本文你将掌握这套机制的完整规则、条目 JSON 的六字段格式、bin/changelog的entry/consume/sync三个命令的用法以及 GitHub Actions 如何用两道检查强制「一个 PR 只能有一个条目」。为什么需要.changelogs目录CHANGELOG.md是仓库根目录下的一份单一文件任何版本迭代都要往里追加内容。当大量 PR 并行推进时多个 PR 同时编辑同一份文件Git 几乎必然报出合并冲突解决起来既费时又容易出错。Handsontable 的解法是把「编写」与「合并」两件事分离。PR 作者不再直接修改CHANGELOG.md而是在 .changelogs/ 目录下新建一个简单的.json文件作为临时条目。每个条目文件对应一个独立的 GitHub 编号issue 或 PR 号文件之间互不重叠从根源上避免了并发写同一文件的冲突。等到正式发布新版本时再由脚本统一把目录里的所有条目编译进CHANGELOG.md并清空目录。强制的 PR 检查Changelog Gate何时必须提交 changelog 条目条目并不是可选的。仓库通过一个 GitHub Actions 工作流定义在 .github/workflows/checks.yml 的changelogjob 中强制执行如下规则当 PR 修改了可发布源码shippable source——即handsontable/src/**或wrappers/**下的任何内容测试文件与 Markdown 除外——时必须新增一个.changelogs/*.json文件否则检查失败。以下类型的 PR自动通过既不需要添加条目也不需要任何豁免声明仅修改文档docs/仅修改测试仅修改 CI 与工具链配置此外如果推送的提交没有关联 PR例如直接推送到分支检查会被整体跳过。[skip changelog]源码变更的豁免标记对于「改了源码但确实没有用户可见影响」的少数场景例如纯内部重构可以在PR 描述PR description中、任何 HTML 注释之外写入以下字符串来豁免[skip changelog]写入后需要从 PR 的 checks 标签页重新运行失败的 Changelog 检查或者推送任意一个新提交git commit --allow-empty也可以。原因是检查脚本在运行时实时读取 PR 描述——仅编辑描述本身不会重新触发检查这一点在 .github/scripts/check-changelog.js 的源码中体现得很明确脚本通过 GitHub API 拉取实时的PR body而不是使用事件负载里冻结的旧值这样作者补充标记后重跑即可让检查通过。豁免并非无声无息[skip changelog]生效时检查日志会把被「放行」的源码文件逐一列出供评审者判断这个豁免是否合理。一个 PR 只有一个条目核心规则一个 PR 添加一个条目。只有引用了不同的 GitHub 编号时才允许第二个条目。这条规则的含义是即使一个 PR 修复了多个 issue、涉及多个包、包含多个不同的用户可见变更仍然只写一个条目用一个标题概括整体变更如果一条标题实在无法承载 PR 的全部内容正确的做法是拆分 PR而不是拆分条目——否则同一个变更会以两行出现在同一版本的 release notes 里读者无法分辨它们来自同一个变更不同的type不能作为添加第二个文件的理由不同的framework也不能。一个同时修改了 API 的修复仍然是一个变更把两者写进同一条标题让最关键的type决定它落在哪个 section一个横跨 React、Vue、Angular 三个封装的修复也只是一个变更用framework: none提交一次即可。唯一常规的第二个条目场景是PR 在完成自身变更的同时顺带关闭了一个公开的 GitHub issue。此时写两个文件——一个引用 issue 编号一个引用 PR 编号——每个文件引用各自的编号因此每一行描述的仍是不同的事情。由什么强制实施两条检查都是阻塞性的blocking且都不依赖评审者的人工把关检查位置断言内容条目文件名bin/changelogconsume与sync命令以及 pre-push 钩子每个.changelogs/*.json都以issueOrPR.json命名——纯数字且与条目引用的编号一致条目数量.github/scripts/check-changelog.js一个 PR 最多添加两个条目文件其中文件名检查是承重墙load-bearing一个编号只拥有一个文件因此磁盘上不可能同时存在引用同一编号的两个条目——这正是让13442-changed.json与13442.json并存变得「不可能而非仅仅不被鼓励」的机制。它在每个 PR 上都会通过checks.yml的changelogjob 中的consume --date 2050-01-01 --dry-run步骤运行并且不需要 diff所以通过重命名文件也绕不过去。从源码看这条不变量实现在 bin/lib/entry-filenames.js 中ENTRY_BASENAME_PATTERN /^\d$/锚定、纯数字13442-changed、13442 (copy)、entry都会被拒绝。值得注意的是文件名比较是字符串比较而非数值比较——Number(013442)会等于13442若用数值比较就会把013442.json当作 #13442 的第二个文件放行恰好制造出本机制要阻止的冲突。文件名断言在consume和sync中都是**fail-closed默认拒绝**的过期的或命名错误的文件没有任何绕过途径发布编译必须停下来直到文件被重命名、合并、删除或修正。这意味着develop分支上一个游离的错误文件可能连累无关 PR 失败、甚至阻止一次发版——但换来的保证是无效的 release notes 永远不会被悄悄发布。命令会列出每一个违规文件并打印安全的补救方案可直接重命名者给出git mv命令因编号冲突而不可重命名者给出合并标题 git rm的建议。由于bin/changelog entry写出的文件名永远是编号.json、不可能写成别的保持两条检查都通过的最简单方式就是使用它而不是手写 JSON。[multiple changelogs]超过两个条目的唯一途径只有一种 PR 需要超过两个条目维护性 PR 为其他 PR 回溯补填条目back-filling。此时在 PR 描述中HTML 注释之外写入[multiple changelogs]然后重新运行失败的 Changelog 检查。这个标记与[skip changelog]是刻意分开的两个标记后者回答「这个变更到底需不需要条目」它永远不解除条目数量上限。提交前的自检命令在提交条目之前文档建议先执行以下命令核对git fetch origin develop git diff --name-only --diff-filterA origin/develop...HEAD -- .changelogs/*.json输出超过两个路径即为错误两个路径引用同一编号的情况不可能出现。如果 PR 目标分支是某个 release 分支把develop换成该分支名即可。条目格式六字段 JSON.changelogs/目录下的每个.json文件都只含一条条目包含六个必填字段{ issuesOrigin: private, title: Fixed the cell editor closing unexpectedly on scroll., type: fixed, issueOrPR: 12345, breaking: false, framework: none }字段可接受值含义issuesOriginprivate、publicissueOrPR是否为公开 GitHub issue 编号详见下文title非空字符串对变更的用户可见描述以句号结尾typeadded、changed、deprecated、removed、fixed、security条目落在CHANGELOG.md的哪个 sectionissueOrPR数字引用的 GitHub 编号同时必须是文件名——严格为issueOrPR.json不允许任何后缀变体由前面的一 PR 一条目规则断言breaking布尔值破坏性变更会在所属 section 内排在最前frameworknone、react、vue、angular给条目加上框架名前缀none表示核心包这些字段的取值在 bin/changelog 源码中与常量数组一一对应changelogEntryTypes [added, changed, deprecated, removed, fixed, security]、changelogFrameworkTypes [none, react, vue, angular]、changelogIssuesOriginTypes [private, public]且assertChangelogEntryFormat会对每个字段做类型与取值校验例如title必须是非空字符串、issueOrPR必须是非 NaN 数字、breaking必须是布尔值校验失败会抛出错误无法生成条目。issuesOrigin字段详解这个字段只回答一个问题**issueOrPR里的编号是不是一个公开的 GitHub issue**它与 PR 无关也与仓库是否公开无关。它决定生成CHANGELOG.md时采用的链接路径而bin/changelog又依据issueOrPR命名文件因此两个字段是联动的issuesOriginissueOrPR文件名渲染出的链接private默认几乎总是正确的拉取请求编号PR-number.jsonhttps://github.com/handsontable/handsontable/pull/npublic少见公开 GitHubissue编号issue-number.jsonhttps://github.com/handsontable/handsontable/issues/n在私有 ClickUp 任务中跟踪的工作一律属于private——这覆盖了所有带DEV-xxxID 的变更。只有当条目引用的是一个真实的公开 GitHub issue 编号时才用public。值得注意的细节即使issuesOrigin填错也不会破坏已发布输出——因为 GitHub 会把/issues/n重定向到/pull/n。但错误值会让 release notes 发布错误的链接路径同时让这个字段失去信息量。因此交互式创建条目时bin/changelog entry会检测「选了public但编号实际对应一个 PR」的情况并发出警告见 bin/changelog 中的warnWhenPublicNumberIsPullRequest。该警告需要网络访问离线时会被静默跳过而且它无法检查手写的条目文件。使用bin/changelog辅助脚本仓库提供了统一的 changelog 辅助脚本用于创建条目并把它们编译进最终的CHANGELOG.md。查看命令列表与选项bin/changelog bin/changelog command --help所有命令除了交互式问答外都接受命令行参数。具体参数见各命令的--help。仓库的 package.json 中注册了快捷方式changelog: bin/changelog因此也可以写npm run changelogCI 报错信息中提示的也是npm run changelog entry。脚本内部通过yargs定义了三个子命令entry、consume、sync每个都支持--dry-run等选项。entry添加新条目bin/changelog entry该命令会通过交互式问答收集issuesOrigin、title、issueOrPR、breaking、type、framework六个字段校验后自动以编号.json为文件名在.changelogs/目录下创建文件。它始终按issueOrPR命名文件不可能产生其他命名。创建前会预览该条目编译成 Markdown 后的样子例如### Fixed - Fixed the cell editor closing unexpectedly on scroll. [#12345](https://github.com/handsontable/handsontable/pull/12345)type的交互默认值会尝试从标题中猜测例如标题含 Fixed 默认选fixed含 Added 默认选added否则默认changed。命令还内置了「防覆盖保护」如果编号.json已存在说明该编号已有条目会明确提示「一个 PR 只能有一个条目」并拒绝在无终端非 TTY环境下覆盖既有条目——因为静默覆盖会丢失已有标题这正是这套检查要防止的损失。所有字段也可以通过命令行参数直接传入如--type fixed --issue 12345 --breaking --framework react非交互环境CI 或 Agent下会直接采用参数值。你不需要为了条目有效而修改CHANGELOG.md——编译时会统一处理。consume编译条目发布新版本时需要把.changelogs/*.json编译成人类可读的CHANGELOG.mdbin/changelog consume该命令会「消费」所有 changelog 条目断言它们全部有效字段校验 文件名断言 重复发布断言、按类型格式化分组并把结果插入CHANGELOG.md中!-- UNVERSIONED --标记之后见 CHANGELOG.md 第 10 行然后删除所有.changelogs/*.json文件。版本号与发布日期取自 hot.config.js 的HOT_VERSION当前为18.1.0与HOT_RELEASE_DATE也可用--date覆盖。编译输出按type分组为### Added、### Changed、### Deprecated、### Removed、### Fixed、### Security六个 section顺序即上文changelogEntryTypes数组顺序每组内破坏性变更breaking: true排最前再按 framework 排序条目渲染为- [**Breaking change**: ] [React|Vue|Angular: ]标题 #编号的形式。consume是副作用安全的——它不会修改本地仓库副本之外的任何东西想撤销只需用git checkout恢复.changelogs与CHANGELOG.md的旧版本命令完成后终端会打印这行撤销命令。建议发布前先试跑bin/changelog consume --dry-run--dry-run只校验与预览、不写入不删除。consume支持--date YYYY-MM-DD指定发布日期非交互环境下直接使用该值或hot.config.js中的默认值。sync同步条目到既有版本段sync [version]命令用于把.changelogs/*.json条目合并进CHANGELOG.md中已存在的某个版本 section默认取CHANGELOG.md中第一个## [版本号]标题对应的版本。它会先解析目标 section 已有的类型分桶跳过其中已发布的条目再把新条目按type合并进对应桶并重新序列化整个 section随后同样删除已消费的.json文件。sync同样支持--dry-run并在写入前执行文件名断言与重复发布断言——因为 release 分支由维护者直接管理cherry-pick 到分支上的条目可能从未经过checks.ymlsync必须在本地兜底。发布到文档站的 changelog 页面consume与sync写入的是根目录的CHANGELOG.md而 release 工作流会把当前版本的 section 复制到 docs/content/guides/upgrade-and-migration/changelog/changelog.md。注意没有任何脚本写入按大版本划分的页面docs/content/guides/upgrade-and-migration/changelog-N/changelog-N.md仓库中现存changelog-6至changelog-18等目录——这个页面由人工把对应版本 section 复制过去并把###降级为####。文档站与版本对比 UIversion-comparison读取的正是这个按大版本划分的页面。这条人工步骤拥有一条编辑规则也是本节存在的意义每条Added条目中提及的新选项option、钩子hook、方法method与插件plugin都必须链接到其 API 参考页面。这一实践从 10.0.0 延续到 14.2.0却从未被写成文档并在 14.3.0 时因负责人离开而中断DEV-2790。链接采用方括号形式锚点为小写- Added an Enter key handler and a new searchMode option to the Filters plugin. [#11871](https://github.com/handsontable/handsontable/pull/11871)命名的东西链接目标配置选项/api/options.md#选项名全小写钩子/api/hooks.md#钩子名全小写核心方法/api/core.md#方法名全小写插件或插件方法/api/插件名.md、/api/插件名.md#方法名全小写锚点就是纯小写的成员名参考页会把成员名原样渲染为标题所以#minRowHeights永远解析失败而#minrowheights可以。没有任何参考页的东西不要加链接主题令牌theme tokens与 CSS 类名、TypeScript 类型名、Intl.NumberFormat这类外部 API、非 API 成员的对象键、封装包名——链接到一个不文档化该名称的页面比不加链接更糟。npm run docs:validate-changelog-links --prefix docs命令会列出候选者并标记无法解析的/api/文件或锚点链接。该检查只报告、不阻塞在每个文档 PR 上都会运行且其候选集合是启发式的一个恰好与选项名同名的反引号单词并不证明该条目引入了那个选项需要人工判断每条发现。它能识别选项、钩子、插件类与Core成员但不能识别插件方法——例如裸的collapseAll()同时属于CollapsibleColumns和NestedRows两个插件只有句子上下文才能说明是哪个这类链接需要人工处理。为什么链接不能放进条目titlebin/changelog会把title原样渲染到四个目的地根CHANGELOG.md、GitHub release body、文档 changelog 页面、版本对比 UI。其中只有文档页面能解析/api/链接在 GitHub 上同样的文本会把/api/...渲染成指向字面路径的链接并 404版本对比 UI 则会丢弃链接只保留文本。因此需要文档链接的条目标题应使用绝对 URLhttps://handsontable.com/docs/...链接解析留到文档页面的渲染阶段。防止条目重复发布No entry may be published twiceconsume与sync都会把待处理的条目与CHANGELOG.md中已经发布的内容做比对匹配到确凿结论时拒绝编译匹配不确凿时仅警告。没有这道检查同一个变更可能会在连续两个版本里被宣布两次——这种情况在 18.1.0 之前的大多数版本中发生过。问题根源两种 merge 形状待处理的.json文件可能在 release 分支消费完条目后、release 合并回develop时存活下来产生两种不易察觉的 merge 形态变更在 release 分支和develop上各提交一次两个提交之间没有祖先关系。相对于 merge baserelease 一侧显示为「先增后删」因此develop上的新增成为两侧唯一的变更merge 会静默保留它不产生任何冲突.json文件在develop上被消费后又被人编辑过形成 modify/delete 冲突很容易以错误的方式解决。与其试图识别这两种形态bin/lib/published-entries.js 直接断言两者共同的产物一个CHANGELOG.md已经携带的待处理条目。匹配基于两个键且严重性不同匹配结果issueOrPR已在CHANGELOG.md中被引用且issuesOrigin为private失败errorissueOrPR已被引用issuesOrigin为public且标题也匹配失败errorissueOrPR已被引用issuesOrigin为public但标题不匹配警告warning仅标题已发布任何编号下警告warning推理如下一个 PR 编号不可能发布两次所以private编号命中即为确凿一个公开 issue 编号可能被两个版本合法地引用先部分修复、后完整修复但部分修复会得到新标题所以「public编号命中且标题也匹配」不属于这种情况按private命中同样失败而一个标题例如被 backport 到多个 release 线可能合法地出现在两个 section 中因此仅标题命中始终只是警告。两个键缺一不可编号键会漏掉以错误链接发布的情况如 #12727 曾以[#0]发布标题键会漏掉在某个分支上被改写标题的情况如 #13243。sync只针对一个版本 section且已跳过其中存在的条目因此检查对象是所有其他section。由于consume --dry-run在每个 PR 上都会运行见 .github/workflows/checks.yml这条规则在 PR 阶段与发布阶段都被强制执行。失败时会逐一列出违规文件并打印清除它们的git rm命令。解决方式删除命令点名的条目文件其变更已经发布若其中确有真正的新变更只是复用了已发布的 PR 编号则把条目改编号以引用它自己的 PR。没有跳过标记——已经发布的条目没有剩余内容可宣布。release 合并回 develop 之后、推送之前建议先运行bin/changelog consume --date 2050-01-01 --dry-run2050-01-01是 CI 中使用的固定未来日期确保校验不依赖真实发布日--dry-run让它只校验不写入。总结一套自洽的 changelog 工作流Handsontable 的 changelog 机制可以概括为四个环环相扣的层次编写层PR 作者用bin/changelog entry生成六字段 JSON 条目或npm run changelog entry文件名恒等于引用的 GitHub 编号门禁层GitHub Actions 在 .github/workflows/checks.yml 中通过check-changelog脚本强制「改源码必须有条目、一 PR 至多两条目」通过consume --dry-run强制「文件名必须等于引用编号」这一仓库级不变量并提供[skip changelog]与[multiple changelogs]两个互不替代的 PR 描述标记作为受控豁免编译层发布时bin/changelog consume或面向既有版本段的sync断言全部有效后把条目按类型分组、破坏性变更置顶、framework 加前缀插入!-- UNVERSIONED --标记处并清空目录bin/lib/entry-filenames.js 与 bin/lib/published-entries.js 提供底层的文件名与重复发布检测逻辑分发层consume/sync写根CHANGELOG.mdrelease 工作流把当前版本 section 复制到 docs/content/guides/upgrade-and-migration/changelog/changelog.md人工降级标题后落到changelog-N/按大版本页面由docs:validate-changelog-links校验其中的/api/参考链接。这套机制把「合并冲突」问题转化为「文件系统不变量」问题把「评审者把关」转化为「CI 断言」既保证了 release notes 的质量底线也让每个 PR 作者有了清晰、可自动化的操作路径。赞分享前端UI组件【免费下载链接】handsontableJavaScript Data Grid / Data Table with a Spreadsheet Look Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡项目地址https://gitcode.com/gh_mirrors/ha/handsontable点击查看免费下载相关推荐Handsontable 仓库 Changelog 条目创建规范从 PR 编号到 .changelogs/*.json 的完整指南Handsontable 仓库 Changelog 条目创建规范从 PR 编号到 .changelogs/ .json 的完整指南 本指南围绕 Handson前端UI组件Grafana Tempo 的 chloggen 变更日志工作流从 .chloggen YAML 条目到 CHANGELOG.md 的自动化发布流水线Grafana Tempo 的 chloggen 变更日志工作流从 .chloggen YAML 条目到 CHANGELOG.md 的自动化发布流水线 Tem后端可观测性链路追踪Prime Agent 的 Changelog Fragments 机制从 PR 条目到发布说明的自动化流水线Prime Agent 的 Changelog Fragments 机制从 PR 条目到发布说明的自动化流水线 导读 本文讲解 Prime Agent 仓库AI Agent人工智能代码智能体自主智能体工具调用Agent 记忆创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考