
Plate 主版本发布迁移同步从 Changesets 版本化到 GitHub Releases 的自动化发布工作流重构【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate本篇文章基于 Plate 仓库的发布迁移同步计划docs/plans/2026-04-27-major-release-migration-sync.md系统讲解 Plate 如何将生成式 release 文档同步硬切换为GitHub Releases 驱动的发布架构由 Changesets 发布包、工作流创建单一全局 GitHub Release、/docs/releases从 Version Packages PR 主体生成发布索引。读完本文你将掌握一条完整可复用的 monorepo 发布流水线设计确定性的发布说明生成、AI 改写与结构化校验、全局 Release 创建、发布文档页数据源切换以及对应的测试与验证手段。一、迁移目标为什么要把发布文档同步硬切换掉Plate 仓库此前的发布文档体系存在一个明显问题content/releases/index.mdx中存储着由自动化生成的大块 changelog 内容发布 PR 的正文被直接复制进页面而不是由自动化程序整理。这种做法的维护成本高、内容易漂移且仓库级别的 tag 对比例如v53.0.1...v53.0.2对于 Changesets 只发包不创建仓库级 tag 的发布方式来说通常是空的无法作为文档的正确目标。迁移计划确立了三个核心目标发布自动化只负责发布以 Changesets 的版本输出和每个包CHANGELOG.md中对应已发布版本的小节作为唯一事实来源source of truthGitHub Releases 成为发布说明的内容管理系统CMS工作流在发布后创建一个全局vX.Y.ZRelease/docs/releases页面改为从发布数据生成渲染而不是在 MDX 中存放大块生成的 changelog明确保留与裁剪边界保留 Plate 的prepare-release-changesets步骤、自动发布复选框流程、发布后的 registry/template 同步任务裁掉生成式 release body 同步、仓库 compare 链接、临时的global-release辅助脚本以及参考对象 Better Auth 的 beta/LTS/snapshot 分支支持和产品域pr-analyzer。从范围看这次迁移只触及发布自动化本身不涉及编辑器内核与业务功能。二、旧工作流的事实调查Findings在执行硬切换之前计划先完成了对现状的调查这些结论都能在仓库源码中得到印证发布入口.github/workflows/release.yml 使用changesets/actionv1创建标题为[Release] Version packages的版本 PR前置脚本tooling/scripts/prepare-release-changesets.mjs 在changesets/action之前运行它为运行时依赖方runtime dependents自动补充 changeset但它发生在版本化之前无法看到生成后的 changelog 与已版本化的包文件这正是需要自定义version命令的原因正确插入点自定义 Changesetsversion命令——先执行pnpm changeset version再同步 release changelog 小节。changesets/actionv1支持version输入项来指定更新包版本与 changelog 的命令Linked 分组.changeset/config.json 中 Plate 使用 linked 分组platejs、platejs/*、udecode/react*、udecode/cn、udecode/utils与 Better Auth 的固定分组不同——已发布且被链接的包会对齐版本但未变更的包并不必然在每次发布中都发布对比样本Base UI 把发布文档放在docs/src/app/(docs)/react/overview/releases采用概览时间线 每个发布一页 元数据文件的结构但它的发布文档没有一个完整的同步脚本且是单一产品的时间线形态Plate 是 monorepo一次发布横跨数十个包单一时间线形态并不适用最终采用带折叠/展开的展开式信息流expanded feedMDX 约束Contentlayer 不接受 HTML 注释标记生成的标记必须使用{/* ... */}JSX 注释数据保留策略发布文档按包 tag 日期做保留Version-PR 输出在合并前还没有 tag因此新生成的条目使用当前同步日期content/releases/index.mdx曾是规范化的保留发布存储同步脚本会在下一次运行时解析生成的ReleaseIndex /数据并删除残留的生成v*.mdx页面AI 路径来源Better Auth 的 Claude action 使用claude_code_oauth_tokenPlate 保留这条路径但始终以确定性的原始 notes 作为回退与校验的事实来源。三、新架构蓝图硬切换实施计划3.1 工作流基线Workflow Baseline新工作流以 Better Auth 的.github/workflows/release.yml为起点改造保留push到main触发workflow_dispatch仅用于确定性脚本就绪后的发布说明预览concurrency并发控制、固定版本的 action、job 级权限、GitHub App token 支持、persist-credentials: falsechangesets/action设置createGithubReleases: false关闭其自建 Release 的行为在changesets/action之前保留node tooling/scripts/prepare-release-changesets.mjs自动发布复选框检测与 Version Packages PR 合并路径使用 App token 或API_TOKEN_GITHUB而非默认的GITHUB_TOKEN保证合并 release PR 后能再次触发发布工作流发布后的sync-release-artifacts任务registry 与模板同步。裁剪掉 Better Auth 的next分支触发与守卫、release/**分支与维护 dist-tag、main→next 同步 PR、snapshot 输入与整个 snapshot job、博客文章注入、包/产品域分类器。3.2 发布命令Release Commands根级脚本见 package.json 的scripts字段最终落地为ci:versionpnpm changeset version pnpm install --no-frozen-lockfile用于版本 PR 生成阶段执行版本化并同步锁文件ci:releasenode tooling/scripts/release-packages.mjs走 Plate 当前的发布路径仍会在changeset publish前执行构建从 Changesetsversion命令中移除pnpm release:releases因为/docs/releases不再存储生成的发布正文。3.3 确定性发布说明Deterministic Notes核心脚本是 tooling/scripts/release-notes.mjs其设计要点输入changesets/action输出的PUBLISHED_PACKAGES全局版本从已发布包中取最高的语义化版本getGlobalReleaseVersion对版本做 semver 正则过滤后降序取第一个工作区包映射从packages/与packages/udecode/下各目录的package.json构建包名→目录映射getWorkspacePackageschangelog 提取对每个已发布包找到对应CHANGELOG.md用extractReleaseChanges精确定位该版本小节并原样保留### Major Changes、### Minor Changes、### Patch Changes三组标题空小节会被过滤小节按 major→minor→patch 排序输出形态按包分组输出 markdown每个包一个小节包内按变更类型分节贡献者从 changelog 正文的by user模式中收集汇总为## Contributors小节链接策略不输出仓库 compare 链接每条Full changelog链接采用首选包 tag存在platejs版本时优先否则取第一个匹配版本号的包 tag每个包小节在验证通过后由add-package-changelogs子命令追加指向该包CHANGELOG.md的链接并钉在GITHUB_SHA上。计划明确不复制 Better Auth 的pr-analyzer.ts将 conventional commit scope、PR label、变更文件映射到产品域的分类器因为 Changesets 的包 changelog 已经提供了可靠的天然分组Plate 只需要一个小型的包映射 changelog 解析器。3.4 Claude AI 改写Claude Polish保留 Better Auth 的 Claude 改写形态提示词模板位于 .github/prompts/release-notes-rewrite.md先由确定性脚本生成原始 release notes用sed将模板中的__RAW_CHANGELOG_PATH__占位符替换为真实路径构建 prompt通过anthropics/claude-code-action/base-action运行 Claude凭据使用claude_code_oauth_token限制工具为Read、Write、Bash(gh pr diff*)、Bash(gh pr view*)与--max-turns 100校验运行release-notes.mjs validate只在校验通过时使用 AI 输出否则回退到原始 notes。适配 Plate 的提示词核心约束可在 .github/prompts/release-notes-rewrite.md 中看到完整原文Plate 是一个面向 React 的开源富文本编辑器框架改写要为使用者描述改变了什么而非内部实现保留包标题## \package-name及其顺序保留### Major/Minor/Patch Changes标题及其顺序保留 PR 链接、作者链接、包名、Full changelog链接保留迁移说明尤其是### Major Changes下的破坏性变更不增删条目、不发明包摘要、不使用 em dash、不添加CHANGELOG链接链接由工作流在校验后注入。校验规则validateAiReleaseNotes逐项断言包标题列表完全一致、变更类型标题列表完全一致、包 changelog 链接与 full changelog 链接一致、PR 链接与 commit 链接一致、条目数-开头的 bullet 数不减少、迁移说明关键词Migration出现次数不减少、Contributors小节未被删除、贡献者句柄未被遗漏。任何一项失败都会删除.final文件并回退原始 notes。3.5 全局 GitHub Release发布成功steps.changesets.outputs.published true后工作流依次执行从release-notes.mjs的输出中读取VERSION若refs/tags/v${VERSION}不存在则在GITHUB_SHA上创建该 tag若 Release 已存在则gh release edit更新否则gh release create创建正文优先使用通过校验的 AI notes${RAW_PATH}.final.final.validated同时存在否则使用原始 notes未通过校验的 AI 输出会被显式警告并忽略版本号含-预发布或发布通道为beta时附加--prereleaseRelease 创建失败视为真实失败——因为文档页现在依赖 GitHub Releases 数据。3.6 文档页/docs/releases计划最初设想/docs/releases在运行时通过 API 拉取 GitHub Releasesnext: { revalidate: 3600 }但随后被第 25 步superseded停止运行时拉取改为从 Version Packages PR 主体生成发布索引。最终落地为 apps/www/src/generated/release-index.json 这一生成产物由 tooling/scripts/sync-version-package-releases.mjs 生成。该脚本的工作方式通过gh pr view --json ...读取指定 Version Packages PR或gh pr list --search [Release] Version packages拉取最近 N 个已合并 PR解析 PR 主体中每个## packageNameversion小节的### Major/Minor/Patch Changes内容把同一全局版本的多个包归并为一个 release 条目groupPackageChangesByVersion把 Changesets 原始条目行- #4954 by user – summary形态重写为更紧凑的- summary (#4954)形态并顺带收集贡献者合并已有索引与解析结果按 tag 去重、版本降序按--from参数过滤早期版本通过gh release list查询已存在的 GitHub Release URL为Full changelog与CHANGELOG链接选择合适目标将结果写入release-index.json实现幂等重复运行不产生多余变更。页面侧apps/www/src/app/(app)/docs/releases/page.tsx/docs/releases/page.tsx) 是静态页面export const dynamic force-static直接导入release-index.json用 apps/www/src/lib/releases.ts 的工具函数把发布按大版本号分组最近两个大版本作为当前发布展开渲染更早的大版本进入 Older releases 卡片区并链接到各自的大版本页v48 及更早则链接到迁移归档页面渲染逻辑apps/www/src/app/(app)/docs/releases/release-page-content.tsx/docs/releases/release-page-content.tsx)提供 Package changes 与 Plate UI 两个开关按钮和一个 RSS 订阅入口。四、当前仓库中的最终实现工作流逐步拆解对照 .github/workflows/release.yml硬切换后的完整发布流程如下触发与守卫push到main/next仓库当前仍保留next分支支持 beta 通道通过Guard release channel步骤区分latest与betamain上若存在.changeset/pre.json则直接报错退出自动发布检测actions/github-script遍历与该 commit 关联的 PR检查 PR 主体是否勾选自动发布isAutoReleaseChecked、是否包含 changeset 文件hasChangesetFile输出enabled与source_pr准备 changesetsnode tooling/scripts/prepare-release-changesets.mjs为运行时依赖方补自动 changeset版本化或发布changesets/actionv1设置version: pnpm ci:version、publish: pnpm ci:release、createGithubReleases: false同时注入NPM_CONFIG_TAG、PLATE_DISABLE_PUBLISH、PLATE_RELEASE_CHANNEL等环境变量版本 PR 分支未发布检出 Version Packages PR运行node tooling/scripts/sync-version-package-releases.mjs --pr $RELEASE_PR --from v49生成release-index.json若文件有变更则以[Release] Sync release docs提交并推回 PR 分支发布分支已发布先推包 tagpublished-package-tags.mjs再生成原始 notes、构建 AI prompt、运行 Claude 改写、校验最后创建/更新全局vX.Y.ZRelease自动合并若自动发布被勾选用 App token 合并 Version Packages PRsquash 删分支使合并事件再次触发main上的发布流程发布后同步sync-release-artifactsjob 在main上运行——重新同步发布文档--latest 300 --from v49、构建并推送 registrybuild:registrybuild:tw、等待 npm 传播await-npm-publish.mjs、更新模板templates:update --local并在失败时创建修复 PR。五、测试与验证矩阵计划为每个关键行为都配套了聚焦测试仓库中可找到 tooling/scripts/release-notes.test.mjs、tooling/scripts/release-workflow.test.mjs、tooling/scripts/sync-version-package-releases.test.mjs 等测试文件全局版本解析getGlobalReleaseVersion从混有不同版本号的PUBLISHED_PACKAGES中选出最高版本changelog 精确提取extractReleaseChanges只取目标版本小节跨版本解析 bug 正是被测试捕获后修复的AI 输出校验删除包标题、删除 PR 链接、删除条目、丢失迁移说明都会导致validateAiReleaseNotes返回失败工作流约束release-workflow.test.mjs直接读取.github/workflows/release.yml做正则断言——包含createGithubReleases: false、version: pnpm ci:version、publish: pnpm ci:release、gh release (create|edit)、sync-release-artifacts同时断言不包含sync-main-to-next、sync-release-docs、global-release、pr-analyzer、snapshot:、release/**脚本契约断言package.json中ci:version/ci:release的精确内容并确认release:releases已从脚本中移除路由重定向/docs/migration与/cn/docs/migration重定向到/docs/releases在 apps/www/next.config.ts 中配置。验证命令计划原文node --test运行聚焦的发布工作流/文档测试pnpm lint:fixBiome 修复并检查注意 Biome 要求脚本中的正则字面量必须是模块级常量否则 lint 失败pnpm --filter www typecheck文档站点类型检查Browser Use对/docs/releases做桌面端与移动端截图验证本地验证时使用http://localhost:3001/docs/releases注意改版后需重启 dev server 以清除旧的已删除路由/chunk。六、执行过程中的关键教训Errors 复盘计划文档最后记录了三类真实踩坑对同类迁移很有参考价值Lint 约束首次运行pnpm lint:fix失败因为 Biome 要求脚本中的正则字面量为模块级常量需要把正则移到文件顶部常量区release-notes.mjs与sync-version-package-releases.mjs中都能看到这种组织方式Contentlayer 与 MDX 注释pnpm --filter www typecheck曾因 MDX 中的 HTML 注释而失败生成的标记必须改用{/* ... */}JSX 注释这一经验也被沉淀为专门的技术文档构建冲突误启动pnpm --filter www build会先跑 CI 专属的 registry 构建干扰 Next.js 构建需要恢复生成的apps/www/public/r/*产物并改用定向 typecheck 路径。七、总结Plate 的这次发布迁移把大块 changelog 塞进 MDX的旧模式重构为一条以 Changesets 为版本事实来源、以 GitHub Releases 为发布说明出口、以/docs/releases为展示层的完整闭环确定性脚本保证可复现与可测试Claude 改写提升文案质量但始终受结构化校验约束全局 Release 失败即发布失败以保护文档数据依赖。对于任何需要治理 monorepo 发布文档的团队这条确定性生成 AI 润色 强校验回退 生成态文档页的流水线设计都是可以直接借鉴的样板。【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考