一键导入
generate-changelog
补扫已合入 main 的 PR 并更新 public/changelog.json(侧边栏"更新日志"面板的数据源)。触发时机:每次提 PR 前的收尾动作(在功能分支上跑一遍补扫,把此前已合入 main 的 PR 收录进日志、随本 PR 一起提交),或用户喊"更新日志"。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
补扫已合入 main 的 PR 并更新 public/changelog.json(侧边栏"更新日志"面板的数据源)。触发时机:每次提 PR 前的收尾动作(在功能分支上跑一遍补扫,把此前已合入 main 的 PR 收录进日志、随本 PR 一起提交),或用户喊"更新日志"。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | generate-changelog |
| description | 补扫已合入 main 的 PR 并更新 public/changelog.json(侧边栏"更新日志"面板的数据源)。触发时机:每次提 PR 前的收尾动作(在功能分支上跑一遍补扫,把此前已合入 main 的 PR 收录进日志、随本 PR 一起提交),或用户喊"更新日志"。 |
维护 public/changelog.json(侧边栏"更新日志"面板的静态数据源)。纯补扫制:只收录已经合入 main 的 PR,当前待提交的 PR 不写入——它的归属日在合并前不可知(07:50 生成、08:10 合入会归错结算日),留给下一次任何人跑本 skill 时补录。语义上 PR N 的 changelog 更新收录到 PR N-1 及之前(滞后一班车,换取归属日 100% 精确)。
{
"lastGithash": "<上次非空补扫时的 origin/main HEAD;空跑不前移,由下次非空补扫追平,见第 7 步>",
"updatedAt": "<最近一次实际写入新内容的 ISO 时间戳(本地时区带偏移)>",
"entries": [
{
"date": "YYYY-MM-DD",
"prs": [99],
"features": [{ "text": "...", "by": "作者名" }],
"fixes": [{ "text": "...", "by": "作者名" }]
}
]
}
entries 按 date 降序;全量保留(前端只展示最近 7 天,不删旧数据)prs 记录该天已收录的 PR 号,是补扫去重的唯一依据;前端不展示updatedAt 是前端未读红点的比对基准features/fixes 的每条是 { text, by }:by = 该 PR 的作者(PR opener,gh pr view --json author 的 login;语义=「这个功能谁做的」,最贴合 changelog)。gh 不可用时降级链 = PR opener → ^2 分支作者(merge 形态)→ %an(squash 形态)。前端把 by 渲染成条目尾部的灰字小标签(空串则不显示)。旧版纯 string 条目前端可向后兼容读取,但新写入一律用对象形态读 public/changelog.json 的 lastGithash——上次生成时已覆盖到的 main commit。
git fetch origin main
git log --first-parent --format='%H|%cI|%an|%s' <lastGithash>..origin/main
(%an 即作者名,直接作为该 PR 所有条目的 by 字段;subject 按前三个 | 切分后取剩余全段,防 subject 自带竖线。)
--first-parent:钉死主干落地 commit 作为候选范围,排除 merge 形态 PR 的分支内部 commit。不要用 --merges——本仓历史是混合形态(#95 起全是 squash 单父提交,早期才有 merge commit),--merges 会漏掉全部 squash PR。(#N) 结尾Merge pull request #Nprs 求差集:已收录的 PR 号直接跳过(去重闭环)。每个 PR 取其落地 main 的 commit 的 committer 时间(squash 形态即该单父提交、merge 形态即 merge commit;有疑问时用 gh pr view N --json mergedAt 交叉核对)。按 8:00 边界归入它自己的结算日(不是生成当天):
toISOString() 取日(那是 UTC 日,会把边界错移)。与前端 src/lib/changelogDate.ts 的 toChangelogDay 语义一致,可直接参考:node -e '
const ts = new Date(process.argv[1]).getTime() - 8 * 3600_000
const d = new Date(ts)
console.log(`${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`)
' '2026-07-05T07:59:00+08:00'
commit subject 前缀 feat → features,fix → fixes;其他前缀(perf/chore/test/refactor…)按"用户能感知到什么"判断归类,感知不到的合并成一条低调的描述也要收录(所有 PR 都必须进日志)。标题信息不足时读 commit body,必要时 gh pr view N 取 PR body。
by = 该 PR 的作者(PR opener,gh pr view --json author 的 login;gh 不可用时降级到 ^2 分支作者 / %an);一个 PR 拆出的多条同 by,多个 PR 合成的一条取主 PR 的作者date:第 3 步的代码换算结果lastGithash:git rev-parse origin/mainupdatedAt:系统时间(date +%Y-%m-%dT%H:%M:%S%z 加冒号成 +08:00 形态)prs 按号去重追加,features/fixes 追加新条目date 降序lastGithash 置为 origin/main HEADupdatedAt 仅在实际有新条目写入时刷新——无新 PR 的空跑不改 updatedAt(避免无意义红点)lastGithash(脚本化后既定决策,2026-07-08):空跑时 changelog.json 不写回、anchor 不动,由下次非空补扫(手动跑本 skill 或 auto-changelog.mjs publish)把 lastGithash 跳到当时 origin/main HEAD 自然追平。理由:GitHub Actions 是唯一 meta-PR 创建者,空跑日意味着无新真 PR 落地(否则就非空了)→ 无 commit 落地,anchor 滞后恒 ≤1 个 meta-PR(被 subject 跳过)且不累积,不值得为 bump 一个字段每天开 PR 烧 6 项 CI。详见 scripts/changelog/RUNBOOK.md。scripts/changelog/auto-changelog.mjs自动闭环已由脚本承载(2026-07-09):本模式的 scan / publish 机械步骤(fetch / git log 差集 / 归天 / 去重 / 建临时 worktree / 合并写回 / 开 PR / 轮询 CI / squash merge / 清理)是确定性脚本;rewrite 由同一脚本直调公司 LLM 网关(OpenAI-compatible
/v1/chat/completions),不再拉起 maker 调度器 agent。GitHub Actions 每日 8:00 跑三步:
node scripts/changelog/auto-changelog.mjs scan— 扫出新 PR,产物落/tmp/mivo-changelog-scan.jsonnode scripts/changelog/auto-changelog.mjs rewrite— 脚本先确定性生成 date/by/kind 骨架(feat→features,fix→fixes,其他前缀低调归入fixes),LLM 只写 PR→文案映射,产物落/tmp/mivo-changelog-rewrite.jsonnode scripts/changelog/auto-changelog.mjs publish --rewrite /tmp/mivo-changelog-rewrite.json— 脚本回填机器字段、校验 + 开 PR + 轮询 CI + squash merge三步编排详见
scripts/changelog/RUNBOOK.md。脚本行为与下方原 SOP 语义一致;下面保留原 SOP 作为语义规格说明,供审查脚本实现是否忠实于本 skill 时对照。
由 .github/workflows/daily-changelog.yml 每日 8:00 触发(恰在结算日翻页后),无人值守跑完整补扫闭环。完整 SOP:
git fetch origin main,从最新 origin/main 检出干净工作区(建议临时 worktree,避免污染开发中的工作树),在其上执行上文"流程"第 1–7 步生成/更新 public/changelog.json(每条含 by)。无人值守跑法下第 7 步的"给用户过目"跳过,靠第 5 步铁律自守updatedAt 不刷新,lastGithash 也不前移——见第 7 步既定决策,下次非空 publish 自然追平)时,不开 PR、不留分支,Actions 绿灯退出git checkout -b chore/changelog-YYYY-MM-DD # 日期 = 当天结算日
git add public/changelog.json
git commit -m "chore: 更新日志补扫 YYYY-MM-DD"
git push -u origin chore/changelog-YYYY-MM-DD
gh pr create --title "chore: 更新日志补扫 YYYY-MM-DD" --body "<新增条目清单>"
gh pr checks <N> --watch 轮询 6 项必需 CI。若 CI 报 head 落后基线,先 gh pr update-branch <N> 再等重跑。全部通过后才执行:
gh pr merge <N> --squash --delete-branch
git fetch origin main 并快进本地 main(或直接清理临时 worktree——下次运行总是从最新 origin/main 开始)chore/changelog-*,diff 仅含 public/changelog.json),绝不 merge 任何其他 PR