mcpField
C
changelog

changelog

github.com/rheged-studio开发056 次安装2 周前更新
代码仓库

关于 changelog

changelog 是用于为当前分支创建、更新或修复变更日志条目的 Skill,面向需要按仓库约定记录分支变更的开发流程。它从 Git 信息和差异推导元数据,并提供确定性补全脚本与校验步骤。

主要功能

  1. 01从分支提交与差异提取元数据
  2. 02按包和类别分组生成正文
  3. 03支持幂等更新已有条目
  4. 04运行补全脚本添加链接等字段
  5. 05校验 frontmatter、文件名与内容

适用场景

  1. 01为当前功能分支撰写变更日志
  2. 02刷新已有分支对应的条目
  3. 03在提交推送前检查条目格式
  4. 04在单仓库或 monorepo 中记录变更

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rheged-studio/agent-skills --skill changelog

安装后在 Claude Code 中输入/changelog确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

config.example.json
package.json
README.md
references/
changelog-contract.md
scripts/
add-links.mjs
backfill-commits.mjs
check-changelog-completeness.mjs
enrich-changelog.mjs
finalise-changelog.mjs
preflight-changelog-ci.mjs
set-affected-packages.mjs
validate-changelog.mjs
scripts/lib/
changelog.mjs
cli-entry.mjs
commit-count.mjs
config.mjs
derive-packages.mjs
enrich.mjs
frontmatter.mjs
stamp.mjs
scripts/lib/vendor/
issue-keys.mjs

详细介绍

变更日志

为当前分支生成或更新变更日志条目,路径为 changelog/YYYYMMDD-HHMMSS-<slug>.md:从 git 和差异中推导元数据,编写 frontmatter 和分组分类后的正文,运行确定性的补充脚本,然后验证结果。

此技能是有效变更日志条目规范的唯一事实来源——包括 frontmatter 架构、字段归属边界、幂等更新与创建规则,以及验证关卡。下游的使用方仓库 CI 和合并后补充程序也会执行相同约定,由后者填充合并后字段(@rheged-studio/changelog-core,在仓库内通过 reusable-changelog-enrich.yml 运行——不再是中央发布编排器的步骤),因此编写规则只需在此处定义一次。

此技能有两种调用方式:

  • 独立运行(/changelog)——编写、刷新或修复此分支的条目,并将其保留为工作区中未提交的文件以供审核。不提交、不推送,也不创建 PR。
  • 在发布流程中运行(例如 /send-it)——在推送前执行的变更日志步骤;发布流程会提交条目、推送并创建 PR。

配置

配置位于此文件旁边的 config.json 中;随附脚本会自动读取它。请编辑你复制的 config.json,使其匹配使用方仓库(随附的中性 config.example.json 是一个模板)。issueKeys 和 linearWorkspaceSlug 是必填项——它们没有默认值,因此缺少 config.json 或缺少任一键都会导致脚本明确报错,而不会静默继承 ACME 的标识。其余配置项是结构性配置,具有通用且可覆盖的默认值:

键含义默认值
issueKeys用于识别分支和正文中问题 ID 的团队键前缀——仓库涉及的每个团队都要列出(例如,["R"];对于横跨 Cadogan 的仓库,可用 ["C", "R"])。问题 ID 正则表达式由这些前缀构建。必填
linearWorkspaceSlug用于构建问题链接的 Linear 工作区 slug(https://linear.app/<slug>/issue/<id>)。必填
baseBranch作为分支差异比较基准的主干分支(origin/<baseBranch>)。可通过每次运行的 BASE_REF 环境变量覆盖。"main"
changelogDir存放按日期命名条目的目录(由补充和验证脚本扫描)。"changelog"
packageRoots单仓库中用于将 <root>/<x>/… 映射为程序包 <x> 的目录前缀,推导 affected_packages 时使用。["apps", "packages", "services"]
fallbackPackage更改路径与任何 packageRoots 前缀都不匹配时使用的程序包名称。"infrastructure"
affectedPackages是否生成 affected_packages 字段。单程序包仓库请保留为 false(该字段只写入且冗余,省略可使条目保持简洁);真正的单仓库请设为 true。rheged-skills-setup 检测到工作区配置时会启用此项。false

所有随附脚本仅使用 Node 内置模块——无需 npm install,也无需构建步骤。它们会操作使用方仓库根目录下的 changelog/ 目录(请从仓库根目录运行)。

运行方式

步骤 1 — 检测现有条目(幂等性)

在 changelog/ 中搜索 frontmatter 包含 branch: "<current-branch>" 的文件。 如果恰好有一个匹配项,则进入更新模式:保留其 created_at 和文件名,重写其余内容。否则进入创建模式。

步骤 2 — 分析分支
  • git log origin/<base>..HEAD --pretty=full — 获取完整提交列表,包括正文和尾注。
  • git diff origin/<base>...HEAD --name-only — 获取更改文件,用于按程序包对正文分组。

<base> 是 config.json 中的 baseBranch(默认值为 main)。请先获取该分支(git fetch origin <base>),确保差异准确——如果调用方已执行此操作,则跳过获取(例如,发布流程会在预检步骤中获取分支)。

多提交和合并提交安全性(R-825)

在多提交功能分支和合并合并(以及压缩合并/变基合并)中,编写和合并后补充信息都是安全的:

  • 每个分支对应一个条目,而不是每个提交对应一个条目。 第 1 步会根据 frontmatter 中的 branch: 查找;在中间提交后重新运行 /changelog 会更新同一个带日期的文件,不会为同一分支创建第二个条目。
  • 分支分析涵盖整个 PR。 第 2 步使用 git log origin/<base>..HEAD(以及对称差异),因此无论合并前有多少个提交,功能分支上的每个提交都会参与元数据和正文内容的生成。
  • 合并后,commit 是主干合并 SHA。 完成/补充信息时,会将 commit 设为已合并 PR 的 mergeCommit.oid 的前 7 个字符,也就是实际进入主干的提交。对于合并合并,这是一个双父合并提交;对于压缩合并,这是一个单独的压缩提交(与功能分支的顶端提交不同)。
  • stats.commits 统计 PR 中编写的工作,不计合并产生的干扰。 系统会扫描 PR commits REST 端点,并排除父提交数超过 1 个的提交(分支 main 合并解决提交),因此即使多提交分支偶尔包含合并提交,统计结果也能正确反映编写的提交数。
步骤 3 — 推导元数据
字段推导方式
issues根据 issueKeys 推导:仅取分支的开头 ID(转为大写;extractBranchIssueId 会忽略 -c-2- 这类 slug 标记),并纳入提交主题/正文中符合 issue ID 正则表达式的所有匹配项(buildIssueRe)。去重。
authorgit config user.email。
co_authors解析分支所有提交中的 Co-authored-by: Name <email> 尾注。存储邮箱或 Name <email> 格式。若无,则为空数组。
category根据提交主题和 diff 推断:feature、fix、chore、docs、refactor、perf。如果无法明确判断,请用户确认。
breaking根据 BREAKING CHANGE: 尾注、符合 Conventional Commits 规范的提交主题中的 !,或公共接口的移除情况推断。如果不明确,请询问用户。默认值为 false。
release_note面向用户的一句话摘要,与 title 不同。可选;如果更改不会影响用户(如 chore、内部重构),则留空。

字段归属——此技能负责编写哪些字段、必须保留哪些字段,是契约的核心;完整规则请参阅 references/changelog-contract.md。 简而言之:

  • 由此处编写: title、release_note、category、breaking、issues、 co_authors、author,以及——仅当启用 affectedPackages 时—— affected_packages(由步骤 5 中的 enrichment 脚本写入,不要手动编辑)。单包仓库将 affectedPackages: false(默认值)保留不变,并完全省略该字段。
  • created_at 神圣不可改——创建时设置一次(首次运行的 UTC 时间);更新时,原样保留。
  • 此处绝不编写: stats(files_changed、loc_added、loc_removed、 commits)以及合并后字段 merged_at / commit / pr。合并后 enrichment 程序会在合并后根据 GitHub PR 的权威数据完成这些字段——包括 pr,它通过已合并 PR 的 branch: 解析得出(ship 流程绝不写入此字段)。commit 是 mergeCommit.oid 的短 SHA(主干落地提交);stats.commits 是 PR 分支上的非合并提交数(参见上文的多提交与合并提交安全性)。创建时,将合并后字段设为空白占位符;更新时,保留现有值不变。

此技能会输出推导得出的 issues 数组作为交接数据——ship 流程会将其用于 PR 正文和任何 Linear 回写(例如通过 linear-sync 技能)。

第 4 步——生成正文

按软件包分组列出要点,并归入 ## Added/## Changed/## Fixed。 只包含有条目的标题。涉及多个软件包时,使用 **<pkg-name>:** 作为子标题。

如果 breaking: true,正文必须以 ## Breaking 部分开头,说明 变更内容和迁移路径。

title、release_note 和正文描述应使用使用方仓库指定的 书面语言。本代码库范围内的语言为英式英语(colour、behaviour、 -ise/-yse)——仅限描述文字,标识符、依赖项名称或上游 API 字段名称除外。

第 5 步——编写或更新文件

文件名: changelog/YYYYMMDD-HHMMSS-<slug>.md,其中时间戳为 created_at(首次运行时的 UTC 时间),slug 根据 title 生成(小写, 非字母数字字符替换为 -,合并重复字符,长度约限制为 60 个字符,并在单词边界处截断)。

始终在 YAML 中为时间戳字符串加引号(created_at: "2026-04-26T13:24:00Z")。 不加引号的 ISO 时间戳会被解析为 Date 对象,并在往返写入时多出 .000Z 毫秒; 加引号可以保留原值。

**更新时:**保留 created_at 和文件名;重写 title、 release_note、category、breaking、co_authors、issues 和正文; merged_at/commit/pr/stats 保持不变(后合并增强器会填充这些字段,pr 由分支解析)。

使用 references/changelog-contract.md 中指定的 frontmatter 字段顺序。只有在启用 affectedPackages 时,才输出 affected_packages: [] 作为占位符——脚本会原位填充。关闭时(默认的单软件包模式),省略此字段;set-affected-packages.mjs 不执行任何操作。

然后从使用方仓库根目录运行两个确定性增强脚本(两者均可幂等运行;它们会根据条目的 branch: frontmatter 匹配条目,并保留合并后字段为空):

node skills/changelog/scripts/set-affected-packages.mjs   # writes affected_packages from the branch diff
node skills/changelog/scripts/add-links.mjs               # rewrites bare issue IDs in the current branch's entry to Linear URLs

如果你将技能安装到了其他位置,请相应调整路径前缀。

两个增强脚本也支持 --check(别名为 --dry-run)——只读预览,会报告将要进行的更改但不会写入任何内容;如果条目已是最新状态则以 0 退出,需要重写则以 1 退出(风格类似 prettier 的 --check,因此 CI 可据此进行检查):

node skills/changelog/scripts/set-affected-packages.mjs --check   # current branch's entry only
node skills/changelog/scripts/add-links.mjs --check               # ALL entries in the changelog dir

默认情况下,两个增强器都按分支范围执行(R-603):不带参数运行 add-links.mjs 时,只会重写 branch: frontmatter 与当前 git 分支匹配的条目,因此编写新条目时不会反复改动其他已合并条目。仍有两种模式会扫描整个目录:--all(有意重写整个目录)和 --check/--dry-run(完整性检查,可因历史条目而以 1 退出)。使用 --check 确认目录中的条目都已完成增强;针对某个分支的单条目 PR,则使用默认模式。(git 不可用时,默认模式会退回到全量扫描。)

第 6 步——根据约定进行验证

这是检查关卡:

node skills/changelog/scripts/preflight-changelog-ci.mjs   # optional: checks Node vs engines/.nvmrc, then pnpm install --frozen-lockfile
node skills/changelog/scripts/validate-changelog.mjs       # validates frontmatter schema, filename format, field types, ISO timestamps, Breaking section, issue IDs

preflight-changelog-ci.mjs 是可选的,且仅适用于 pnpm——如果使用方仓库不使用 pnpm,请跳过。失败时,请停止并修复条目后再继续——不要将格式错误的条目交给发布流程。

独立运行与在发布流程中运行

  • 独立运行(/changelog)会执行第 1–6 步,然后报告结果,并将条目留在工作树中且不提交,供用户审阅和提交。它不会推送或创建 PR。
  • 在发布流程中运行时,同样会在推送前执行这些步骤;之后发布流程会提交条目(docs(changelog): <title>)、推送,并创建或更新 PR。它会将 pr 留空——后合并增强器会根据合并后的 PR 解析分支并填充此字段。

实现

变更日志生命周期所需的所有脚本都位于此捆绑包的 scripts/ 目录下,并可直接在 Node 上运行(无需 npm 依赖,也无需构建步骤)。这些脚本覆盖了此捆绑包负责的整个生命周期——编写(由此技能运行)以及合并后的最终处理/CI 逻辑(下文注释说明了该逻辑现在的运行位置)。每个脚本都支持 --help(显示用法,退出码为 0)和 --self-test(对纯逻辑进行离线冒烟测试);会写入文件的脚本还支持 --check/--dry-run(报告结果,不写入任何内容)。

编写——由此技能运行(/changelog 流程):

  • scripts/set-affected-packages.mjs — 根据分支差异写入 affected_packages(仅适用于 monorepo 消费者;当 affectedPackages 关闭时不执行任何操作)。
  • scripts/add-links.mjs — 将正文中的裸问题 ID 改写为 Linear URL。
  • scripts/preflight-changelog-ci.mjs — 可选的 Node/锁文件 CI 一致性检查(pnpm)。
  • scripts/validate-changelog.mjs — 根据约定验证条目。

合并后的最终处理和 CI 门禁——现在由 @rheged-studio/changelog-core 运行。 最终处理/丰富/完整性逻辑已提取到已发布的 @rheged-studio/changelog-core 软件包中(CLI:validate | enrich | finalise | set-affected-packages | add-links | backfill-commits | check-completeness)。仓库内的合并后丰富处理通过 shared-workflows 的 reusable-changelog-enrich.yml 运行(npm 目标使用 mode: finalise,部署目标使用 mode: enrich),该工作流会调用 changelog-core 并以 road-runner-bot[bot] 身份写回结果;CI validate 和完整性门禁则会调用 changelog-core validate/changelog-core check-completeness。这取代了旧版 release-orchestrator 内联最终处理步骤和已停用的每日 enrich-changelogs.yml 定时任务(R-801)——现在没有任何中央编排器或定时任务会运行这些逻辑。

以下对应的捆绑脚本是原始的零依赖实现。它们仍是已发布的技能源代码(并且仍会在此处接受 --help/--self-test 测试),因此使用者可以直接接入;但使用共享工作流的消费者获取这些逻辑的来源是 changelog-core,而非这些文件:

  • scripts/finalise-changelog.mjs — 在发布时为 npm 目标补充信息并标注版本。对于每条尚未完成最终处理的条目,它会通过 gh/git 查找已合并的 PR,填入合并后的字段(merged_at / commit / pr / stats,其中 stats 包含通过 PR commits API 获取的、不含合并提交的 commits 计数),将 version 标注为刚更新的 package.json 版本,并为裸 Linear ID 添加链接。它组合了 lib/enrich.mjs(填入 PR 元数据)、lib/commit-count.mjs(获取不含合并提交的提交计数)和 lib/stamp.mjs(标注版本)。
  • scripts/enrich-changelog.mjs — 为 部署目标(octavo、shared-workflows)补充合并后信息。这些目标在发布流程中不会被检出,因此无法在发布时直接完成最终处理。它通过环境变量接口(BRANCH_NAME / MERGED_AT / MERGE_SHA / PR_NUMBER / ADDITIONS / DELETIONS / CHANGED_FILES)读取一个已合并 PR 的数据,根据 branch: 查找对应条目,并填入与最终处理脚本相同的合并后字段组(不含 version,因为部署目标由自身的标签流程负责标注版本;也不含 commits,因为补充信息流程不会获取该字段)。它是 lib/enrich.mjs 的轻量封装;只填充一次且具备幂等性,因此可安全地重复运行。若条目仍需补充信息,--check 会以状态码 1 退出;--dry-run 用于预览。
  • scripts/check-changelog-completeness.mjs — CI 完整性检查:触发发布的 PR 标题(feat/fix/breaking)必须包含带日期的 changelog/ 条目,否则构建会失败。
  • scripts/backfill-commits.mjs — 一次性回填现有 changelog/ 历史条目中的 stats.commits(用于事后补充提交计数)。它通过 gh 查找每条记录对应的已合并 PR,只插入 commits 行(不重新序列化),并且具备幂等性;--dry-run 用于预览。此脚本不属于编写或发布流程的一部分。

这些脚本共用 scripts/lib/ 下的辅助模块(changelog.mjs、derive-packages.mjs、 frontmatter.mjs、config.mjs、enrich.mjs、commit-count.mjs、stamp.mjs)。因此,这项技能本身只负责编写和验证,并将合并后字段留空;这些字段会在合并后由 changelog-core(通过 reusable-changelog-enrich.yml)填入,而不是由 /changelog 流程填入。

**采用者须知:**这些脚本的单元测试在 agent-skills 仓库中维护(未随技能打包)。请参阅该技能的 README。

评论

支持 Markdown