工作流:从 `pnpm release:notes` 到 GitHub Releases 的完整指南)
OpenSEO 版本发布笔记Release Notes工作流从pnpm release:notes到 GitHub Releases 的完整指南【免费下载链接】open-seoOpen source alternative to Semrush and Ahrefs项目地址: https://gitcode.com/GitHub_Trending/op/open-seoOpenSEO开源版 Semrush/Ahrefs 替代品采用「提交驱动」的发布笔记生成方式由release-notes/目录存放按版本号命名的 Markdown 笔记文件配合scripts/release-notes.mjs自动从 git 提交历史生成草稿再通过 GitHub CLI 发布。本文以 release-notes/README.md 为核心骨架结合仓库内生成脚本、发布脚本与既有版本文件完整讲解这套发布笔记工作流的目录规范、命令用法、分类原理与实际发布步骤读完你即可在自己的 fork 或自托管环境中复刻同一流程。一、发布笔记目录命名规范与文件组织release-notes/目录是 OpenSEO 存放「最终定稿」发布笔记的地方其 README 明确了唯一的命名约束以版本号为文件名格式为vX.Y.Z.md例如release-notes/v0.0.2.md。仓库内实际的文件印证了这一规范release-notes/v0.0.2.md 到 release-notes/v0.1.8.md 全部遵循v主版本.次版本.修订版本.md的命名。从源码看这一命名并非仅靠约定scripts/release-notes.mjs中的getReleaseNoteVersions()会扫描该目录并按正则/^v(\d\.\d\.\d(?:[-][0-9A-Za-z.-])?)\.md$/解析出版本号用于推断「上一次发布」的默认起点function getReleaseNoteVersions() { return readdirSync(release-notes).flatMap((name) { const version name.match(/^v(\d\.\d\.\d(?:[-][0-9A-Za-z.-])?)\.md$/)?.[1]; return version ? [version] : []; }); }这意味着只要按规范在release-notes/下添加版本文件生成器就会自动把它纳入版本候选列表无需额外登记。二、三步入流的典型发布流程README 给出的典型流程只有三步但每一步背后都有对应的脚本支撑生成草稿pnpm -s release:notes—— 对应 package.json 中的release:notes: node scripts/release-notes.mjs由scripts/release-notes.mjs从 git 提交历史自动汇总定稿存档把编辑后的最终版复制为release-notes/下的版本化文件如release-notes/v0.1.9.md发布上线gh release create tag --title tag --notes-file release-notes/tag.md—— 将本地定稿的 Markdown 作为 GitHub Release 的笔记上传。仓库还提供了将第 3 步固化成脚本的便捷入口scripts/publish-release.mjs对应package.json中的release:publish。该脚本会先校验package.json中version必须形如\d.\d.\d再检查release-notes/v${version}.md是否存在缺失时直接抛错Missing release notes: release-notes/v0.1.8.md随后才执行gh release create并固定使用--repo every-app/open-seo。支持--dry-run只打印将要执行的命令而不真正发布pnpm release:publish # 正式发布 v$(package.json version) pnpm release:publish -- --dry-run # 仅预览命令三、pnpm release:notes命令参数与默认行为scripts/release-notes.mjs基于 Node 内置的node:util的parseArgs解析参数可用选项如下参数类型说明默认值--from tagstring变更日志生成的起始 git tag自动推断见下--to refstring结束的 git ref公开仓库main否则HEAD--draft tagstring用生成的笔记为该 tag 创建 GitHub 草稿 Release无不创建--repo owner/repostring覆盖 GitHub 仓库标识用于 compare 链接与草稿发布自动探测-h, --helpboolean打印用法说明无README 中给出的两个实用变体在源码中均得到完整支持pnpm release:notes -- --from v0.0.1 --to HEAD # 指定区间生成 pnpm release:notes -- --draft v0.0.2 # 生成并创建草稿 Release注意这里的--分隔符pnpm release:notes先由 pnpm 解析脚本名脚本内部再对--之后的参数做二次解析argv[0] -- ? argv.slice(1) : argv所以原样参数需要放在--之后。默认--from的推断逻辑不传--from时脚本通过getDefaultFromTag()做三件事读取package.json的version当前为0.1.8汇总两类候选所有 git tagtag来源与release-notes/目录下解析出的版本release-notes来源只保留语义化版本严格小于当前package.jsonversion的候选按 semver 降序取第一个作为起始 tag若当前版本无法解析则回退到最新的 semver git taggetLatestSemverTag()用git tag --sort-version:refname排序后取首个匹配v?\d\.\d\.\d的 tag。默认--repo与--to的探测--repo默认从 git remote 探测优先取名为public的 remote其次origin并从 URL 中正则提取github.com[:/]owner/repogetPreferredRepo()--to的默认值取决于探测到的仓库若为every-app/open-seo则用main分支否则用HEADgetDefaultToRef()。四、提交分类与分组草稿是怎么生成的生成核心在buildNotes()与classifyCommit()。脚本先执行git log --no-merges --reverse --format%s from..to不传--from时范围退化为单个 refgit log to逐条拿到提交标题后做分类。分类规则如下提交类型Conventional Commits 前缀归入小节feat:Addedfix:Fixeddocs:Docsperf:/refactor:Improvedstyle:Changedchore:/ci:/test:/build:/release:直接过滤不进入笔记merge开头直接过滤此外还针对非前缀提交做了启发式兜底以add|introduce|create开头的归Added以fix|resolve|correct开头的归Fixed以improve|speed up|reduce|refactor|support开头的归Improved以document|docs|explain开头的归Docs其余归Changed。每条提交的标题还会经过stripPrefix()去掉revert:与前缀如feat(scope)!:再sentenceCase()首字母大写得到对用户友好的短句。生成时按固定小节顺序Added → Improved → Fixed → Changed → Docs输出并对同小节内重复文案去重若过滤后没有任何提交则输出No notable changes.。当同时提供repo与from时文末追加一行完整变更对比链接Full Changelog: https://github.com/repo/compare/fromTag...toRef仓库内实际版本文件如 release-notes/v0.1.8.md、release-notes/v0.1.7.md正是该输出经过人工编辑后的落盘结果——首行通常是一句概括性标题如 “Keyword capitalization, searchable Google properties and SAM reply controls.”正文按小节组织。--draft的附加行为传入--draft tag时脚本会把生成的笔记写入系统临时目录os.tmpdir()下的quick-eagle-release-notes-时间戳.md然后调用gh release create tag --draft --title tag --notes-file 临时文件 [--repo repo]即在 GitHub 上创建一个草稿 Release 而非直接发布方便人工复核后再正式发布。五、维护者视角的完整发布流程docs/MAINTAINERS.md 对维护者的发布工作流做了补充说明可以视作 README 三步流的实战展开pnpm -s release:notes # 编辑并保存最终版到 release-notes/v0.0.2.md gh release create v0.0.2 --target main --title v0.0.2 --notes-file release-notes/v0.0.2.md要点包括GitHub Releases 是 OpenSEO 面向用户的主要更新渠道维护者应引导关注者开启仓库的 Release 通知不建议把 Star 当作联系列表GitHub 不提供直接私信 Stargazer 的能力生成器默认从最近一个 semver tag起统计提交过滤chore:/ci:/test:/build:/release:等维护性提交并把剩余变更分组为面向用户的短小节最终定稿笔记必须落盘到release-notes/下的版本化文件项目仍处于快速早期开发阶段优先发布 patch 版本除非有明确理由才切 minor/major使用 OpenCode 时可通过斜杠命令/release-notes触发同一生成脚本并把多余参数透传给它。六、把流程接入 CI 与自托管环境虽然发布动作通常由维护者在本地执行但发布笔记生成是无副作用的纯本地命令只读 git 历史并输出文本完全适合在 CI 中预演。仓库的 package.json 同时暴露了release:notes与release:publish两个脚本前者只负责生成后者才真正调用gh。若你在 fork 或自托管环境中复用需要预装git、pnpm以及 GitHub CLIgh仅发布/草稿步骤需要用--repo覆盖为自己的owner/repo否则脚本会从public/originremote 自动探测用--dry-run先验证scripts/publish-release.mjs将执行的完整gh命令发布前确保package.json的version与release-notes/vX.Y.Z.md一一对应publish-release.mjs会在缺失时直接报错终止避免发布无笔记的 Release。七、小结OpenSEO 的发布笔记体系可以概括为一条清晰链路git 提交Conventional Commits→scripts/release-notes.mjs分类汇总 →release-notes/vX.Y.Z.md版本化定稿 →gh release create发布。核心要点再强调一遍release-notes/目录只存放按vX.Y.Z.md命名的最终版笔记pnpm -s release:notes负责生成草稿支持--from/--to/--draft/--repo四个参数默认行为由 semver tag、package.jsonversion 与 git remote 自动推断提交按feat/fix/docs/perf/refactor/style自动归入Added/Improved/Fixed/Changed/Docs小节维护性提交自动过滤正式发布推荐pnpm release:publish含--dry-run预演或直接按 README 的gh release create命令手动执行。对想贡献或二次开发 OpenSEO 的读者docs/CONTRIBUTING.md 与 docs/MAINTAINERS.md 是继续深入了解协作与发布规范的最佳起点而release-notes/目录本身即是这套流程最直观的活教材。【免费下载链接】open-seoOpen source alternative to Semrush and Ahrefs项目地址: https://gitcode.com/GitHub_Trending/op/open-seo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考