首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >自动生成 Changelog 的正确姿势:省下你80%的重复劳动

自动生成 Changelog 的正确姿势:省下你80%的重复劳动

原创
作者头像
网罗开发
发布2025-07-23 21:04:54
发布2025-07-23 21:04:54
2440
举报
文章被收录于专栏:网罗开发网罗开发

摘要

每次上线前,总有个麻烦事:写 changelog。哪怕有规约、有流程,也难保不漏掉关键改动。有时候只是漏了个小 fix,有时候直接忘了新增了个接口。尤其当你在项目 PR 多、节奏快的团队里,一不留神就踩雷。

这篇文章就聚焦一个实际痛点:如何从 Git 提交记录中自动提取变更内容,生成结构化的 changelog 文档? 我们会用一段 Node.js 脚本来实现,支持提取 commit 中的新增(feat)、修复(fix)、重构(refactor)等内容,并写入 CHANGELOG.md。此外,也会补充一个 Python 版本,方便习惯不同语言的团队快速上手。

引言

自动生成 changelog 的做法并不新鲜,比如 conventional-changelog 和 semantic-release 已经广泛应用在一些社区项目中。但大多数脚本功能都偏重「CI 集成」,而我们更关注日常开发场景下,如何做得轻量、可控、可定制。

我们从以下三个角度来切入:

  • 用 Node.js 脚本从 git 提交中提取信息
  • 自动分类成 feature / fix / refactor 等结构
  • 将变更内容追加到指定位置,并支持定制输出格式

提取 Git 提交日志

约定式 Commit Message 规范

想要自动提取变更内容,前提是你的 Git 提交得有「格式」。我们推荐使用 Conventional Commits,格式长这样:

代码语言:txt
复制
feat: 新增用户登录功能
fix: 修复图片上传失败的 bug
refactor: 重构用户信息接口

这样我们才能靠正则表达式提取关键词,归类成 changelog 项。

用 Node.js 获取提交信息

我们先用简单的 child_process 执行 git log:

代码语言:js
复制
const { execSync } = require('child_process');

function getCommitLogs(fromTag = '') {
  const range = fromTag ? `${fromTag}..HEAD` : '';
  const log = execSync(`git log ${range} --pretty=format:"%s"`).toString();
  return log.split('\n');
}

这个函数支持传入起始 tag(比如 v1.0.0),只获取从那个版本以来的提交信息。

分类处理 Commit 信息

提取关键类型

我们做一个分类 map,把不同类型映射成中文分组标题:

代码语言:js
复制
const typeMap = {
  feat: '✨ 新功能',
  fix: '🐞 修复问题',
  refactor: '♻️ 重构优化',
  docs: '📚 文档变更',
  chore: '🔧 其他修改',
};

function classifyCommits(commits) {
  const result = {};

  commits.forEach((line) => {
    const match = line.match(/^(\w+):\s*(.+)/);
    if (!match) return;

    const [, type, message] = match;
    const title = typeMap[type] || '📦 其他';
    if (!result[title]) result[title] = [];
    result[title].push(`- ${message}`);
  });

  return result;
}

生成 changelog.md 文件

格式化输出 Markdown

最终我们用一个函数拼接 Markdown 字符串:

代码语言:js
复制
function generateMarkdown(classifiedCommits) {
  const lines = [`## 📝 本次变更 (${new Date().toLocaleDateString()})\n`];
  for (const [title, items] of Object.entries(classifiedCommits)) {
    lines.push(`### ${title}`);
    lines.push(...items);
    lines.push('');
  }
  return lines.join('\n');
}

插入到 changelog 文件中

最后把 markdown 内容追加到 changelog:

代码语言:js
复制
const fs = require('fs');

function appendChangelog(content) {
  fs.appendFileSync('CHANGELOG.md', `\n${content}`);
}

完整可运行脚本

代码语言:js
复制
// changelog-generator.js
const { execSync } = require('child_process');
const fs = require('fs');

const typeMap = {
  feat: '✨ 新功能',
  fix: '🐞 修复问题',
  refactor: '♻️ 重构优化',
  docs: '📚 文档变更',
  chore: '🔧 其他修改',
};

function getCommits() {
  return execSync('git log --pretty=format:"%s"').toString().split('\n');
}

function classify(commits) {
  const result = {};
  for (let line of commits) {
    const match = line.match(/^(\w+):\s*(.+)/);
    if (!match) continue;
    const [, type, msg] = match;
    const title = typeMap[type] || '📦 其他';
    if (!result[title]) result[title] = [];
    result[title].push(`- ${msg}`);
  }
  return result;
}

function generateMd(data) {
  const now = new Date().toLocaleDateString();
  const lines = [`## 📝 更新日志 (${now})\n`];
  for (const [title, items] of Object.entries(data)) {
    lines.push(`### ${title}`);
    lines.push(...items, '');
  }
  return lines.join('\n');
}

function writeToFile(content) {
  fs.appendFileSync('CHANGELOG.md', '\n' + content);
}

const commits = getCommits();
const grouped = classify(commits);
const markdown = generateMd(grouped);
writeToFile(markdown);
console.log('✅ Changelog updated.');

真实应用场景

项目日常发布

在每次上线前执行:

代码语言:bash
复制
node changelog-generator.js

团队成员只要保持良好的 commit message,就能自动生成结构化的变更记录。

结合 PR 模板

在 PR 模板中插入生成 changelog 的 commit 类型规范说明,推动团队使用统一提交风格。

脚本 + Git Hook 联动

可以结合 pre-push hook 自动触发 changelog 生成,或者和 CI/CD 搭配用脚本生成 changelog 并发布到 Release Notes。

QA 环节

Q1: 一定要用 Conventional Commits 吗?

建议是的。如果提交风格混乱,脚本就无法准确提取变更类型。当然也可以适配项目实际需求调整正则。

Q2: 可以集成到 CI/CD 流程里吗?

完全可以。比如在 GitHub Actions 中增加一步执行 node changelog-generator.js,并将结果作为 artifact 或 Release Notes 输出。

Q3: 如何避免重复生成同样的 changelog?

可以结合 tag 范围限制,只提取 上一次 tag ~ 当前提交 的日志。

总结

手动写 changelog 麻烦又容易出错,不如让机器来干这活。通过简单的脚本 + 提交规范,我们就能实现 changelog 自动化,不仅提升发布效率,还能提升团队协作的一致性。更重要的是——你再也不用担心「这个功能上线了吗?」的问题了。

后续我们还会分享更多类似的“创意自动化脚本”,比如:

  • 自动清理本地无用分支
  • 自动同步多环境配置文件
  • 定时备份数据库并发送告警

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 摘要
  • 引言
  • 提取 Git 提交日志
    • 约定式 Commit Message 规范
    • 用 Node.js 获取提交信息
  • 分类处理 Commit 信息
    • 提取关键类型
  • 生成 changelog.md 文件
    • 格式化输出 Markdown
    • 插入到 changelog 文件中
  • 完整可运行脚本
  • 真实应用场景
    • 项目日常发布
    • 结合 PR 模板
    • 脚本 + Git Hook 联动
  • QA 环节
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档