
Plate 仓库 main→next 直连同步sync-main-to-next 发布车道自动化的实现与实战【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate导读本指南围绕 Plate 仓库的sync-main-to-next技能.agents/skills/sync-main-to-next/SKILL.md展开讲解如何在一次稳定版本发布之后把main分支的新提交通过一条命令直接同步进nextbeta 预发布车道并在同一提交内完成 beta 版本元数据的确定性修复。读者学完后将掌握release-branch-prs.mjs脚本的三段式命令契约dry-run → push → verify、发布元数据冲突的自动解决规则、工作流观察与 npm/GitHub 回读校验方法以及一套可复用的快速、低仪式感的 beta 车道追赶方案。背景为什么main → next需要直连同步而不是 PR在 Plate 的发布架构中CI 负责实际发布而车道维护由 release-lanes 规则负责。核心设定是main分支发布稳定包对应 npm taglatestnext分支发布预发布包对应 npm tagbeta.changeset/pre.json只属于nextmain上存在该文件时绝不能发布主版本major变更集先进入next做 beta再提升为稳定版次版本minor变更集直接进main补丁patch修复既可进main也可在 beta 车道活跃时进next。从源码视角看这套双车道设计的关键约束是稳定版与 beta 版共享同一份仓库但包版本、变更集状态和 changelog 在两条分支上必然分叉。因此普通的main - next同步 PR 会引入大量确定性的发布元数据冲突例如同一个package.json在main上是1.2.3、在next上是1.3.0-beta.5造成无谓的评审噪声。sync-main-to-next的答案是用一个 merge commit 直连同步、自动修复已知的发布元数据冲突、直接推送next然后让release.yml发布 beta。release-lanes 中明确指出不要创建例行的main - next同步 PR直连同步才是被认可的快车道。快速上手三段式命令序列sync-main-to-next技能SKILL.md定义的标准执行序列只有三条命令node tooling/scripts/release-branch-prs.mjs sync-main-to-next --dry-run node tooling/scripts/release-branch-prs.mjs sync-main-to-next --push node tooling/scripts/release-branch-prs.mjs verify-main-to-next-sync第一条--dry-run只读演练报告main比next领先多少个提交、会生成多少个 beta changeset不改动任何远端状态第二条--push执行真实的直连同步并在本地生成 merge commit 后推送到origin/next第三条verify-main-to-next-sync对刚生成的提交做元数据校验详见后文验证环节。脚本位于 tooling/scripts/release-branch-prs.mjs其 CLI 契约L1297-L1322明确支持三种命令Usage: release-branch-prs.mjs promote --version x.y.z | sync-main-to-next [--push] | verify-main-to-next-sync [--dry-run]其中sync-main-to-next的语义是不带--push时只做本地合并与元数据修复生成提交但不推送带--push时才推送到origin/next--dry-run全程只打印将要执行的 git/gh/pnpm 命令而不真正执行logDryRun。命令契约背后的执行流程sync-main-to-next命令最终调用syncMainToNextDirectL1165-L1275。整个流程可以拆成 8 个阶段1. 拉取远端并计算领先提交数runGit([fetch, origin, main, next], { dryRun }); const aheadText runGit([rev-list, --count, origin/next..origin/main], { capture: true });若ahead 0直接跳过并打印 No new commits to sync from main to next.不产生任何提交。2. 校验工作区干净真实同步要求本地工作区完全干净assertCleanWorktreeForDirectSyncconst status runGit([status, --porcelain, --untracked-filesall], { capture: true }); if (!status) return; throw new Error(Direct main - next sync requires a clean worktree before mutating next. ...);这是最重要的硬性前置条件之一任何本地已跟踪或未跟踪的改动都会让脚本直接拒绝执行。3. 创建 merge commit不提交runGit([checkout, -B, next, origin/next], { dryRun }); runGit([merge, --no-ff, --no-commit, origin/main], { allowFailure: true, dryRun });--no-ff保证生成真正的双父 merge commit这对接下来的验证步骤至关重要--no-commit则把提交动作延后到所有元数据修复完成之后。4. 确定性解决发布元数据冲突脚本把冲突文件限定在已知发布元数据白名单内isMainToNextMetadataFile所有package.json根级及packages/**下的工作区包所有CHANGELOG.md根级.changeset/pre.json。resolveMainToNextMetadataConflicts 遍历git diff --diff-filterU列出的未合并文件逐类处理package.jsonresolvePackageManifestForMainToNextSyncL532-L553校验冲突只发生在version字段其他字段必须与 next 或 main 之一完全一致并保留 next 的 beta 版本、覆盖 main 的稳定版本绝不允许版本回退.changeset/pre.json直接取 stage 2即 next 侧的 beta pre-release 状态CHANGELOG.mdgetMainToNextChangelogResolutionL695-L752以 next 现有版本为锚点把 main 侧新增的稳定版本章节确定性插入对应位置锚点版本之前或末尾并刷新已存在稳定章节的内容。若存在白名单之外的文件冲突脚本不会猜测而是抛出包含精确文件列表的错误要求人工介入。5. 确保 beta pre 模式与生成补丁 changesetensureMainToNextBetaPreModeL400-L414若next已有.changeset/pre.json且mode pre、tag beta直接保留否则在同一同步提交内重建 beta pre 状态createMainToNextBetaPreState会收集所有工作区包当前版本作为initialVersions。writeMainToNextSyncChangesetsL453-L469对被同步的main提交涉及的所有公开非private工作区包生成auto-main-to-next-sync-包名.md补丁 changeset内容为--- package-name: patch --- Synced latest changes from main into the beta lane.这样 beta 车道就能发布这些来自main的修复而不是把它们积压在待处理的 Version Packages PR 里。6. 版本化 提交当生成了 beta changeset 时脚本会运行pnpm ci:version根 package.json 中定义为pnpm changeset version pnpm install --no-frozen-lockfile使next获得已版本化的 beta 包元数据而非待处理状态。提交信息根据是否生成 changeset 自动选择getMainToNextSyncCommitMessage有 changesetchore: sync main to next无 changesetchore: sync main to next [skip release]L17-L19。7. 提交前验证if (!dryRun) { verifyMainToNextSyncMergeCommit({ commit: HEAD }); }推送之前脚本必须通过verify-main-to-next-sync的完整校验见下一节任何失败都会中止流程。8. 推送runGit([push, origin, HEAD:next], { dryRun }); console.log(Synced ${ahead} main commit(s) directly into next with ${changesets.length} beta changeset(s).);脚本以github-actions[bot]身份提交git config user.name/emailL1194-L1204并直接推送origin/next。若分支保护拒绝推送则触发硬性停止条件见下文。验证环节verify-main-to-next-sync 校验什么verifyMainToNextSyncMergeCommitL1037-L1095是一个可独立调用的校验命令核心断言包括必须是双父 merge commitgit rev-list --parents -n 1 HEAD必须返回至少两个父提交否则报错 is not a merge commit; main - next sync must preserve the main merge parent无冲突标记所有涉及元数据文件的最终内容不得包含//assertNoConflictMarkers包版本不回退对每个package.json解析后的版本既不能改名也不能从 next 的 beta 版本降级唯一的例外是推进到更新的预发布版本pre.json 保持 betanormalizeText(resolved) normalizeText(ours)即必须与 next 侧的 beta pre-release 状态完全一致changelog 确定性解析后的 changelog 必须与确定性合并的期望输出一致缺失或改动的稳定版本章节都会报错。校验通过后输出 Main - next sync metadata verification passed.并逐条打印每个元数据文件的处理结果保留的版本、插入的稳定 changelog 章节等。推送后只观察本批工作流 回读校验技能文档SKILL.md强调推送后只观察由本次同步提交创建的工作流不要等待无关的旧运行gh run list --branch next --limit 10 \ --json databaseId,name,workflowName,headSha,status,conclusion,displayTitle,url gh run watch release-run-id --exit-status gh run watch ci-run-id --exit-status随后进行 npm 与 GitHub 的双向回读npm view platejs dist-tags --json npm view platejslatest version npm view platejsbeta version gh release list --limit 5 gh pr list --base next --head sync/main-to-next --state open --json number,url前三条验证 npmlatest/betatag 是否指向期望版本后两条确认 GitHub release 状态并找出遗留的旧式sync/main-to-nextPR。清理时机只有在直连同步与发布验证都通过之后才关闭陈旧的sync/main-to-nextPRrelease-lanesgh pr list --base next --head sync/main-to-next --state open --json number,url gh pr close number --comment Closing because release-lanes synced main directly into next.运行纪律Keep It Fast该技能被设计为一次调用即授权跑完整条车道one-shot因此带有明确的效率约束SKILL.md除非用户明确要求 autogoal 产物否则不创建或更新计划不运行 autoreview不创建main - nextPR不触碰 promotion本捷径不是next - main已知推送 SHA 后不重复运行宽泛的 release 状态命令不等待无关的旧工作流。同时要注意sync-main-to-next只是一个便利包装器convenience wrapper不是第二套发布系统——release-lanes 拥有发布架构、脚本契约、硬性停止条件和交接格式的所有权SKILL.md。硬性停止条件在实际操作中只有以下情况才需要停止并询问release-lanes直连同步脚本因脏工作区被拒绝已知发布元数据之外的真实源码冲突分支保护拒绝所需的 merge 或 pushrelease 或 CI 在一次明确的重试/修复后仍然失败npmlatest或beta发布后指向意外版本回读不匹配。技能文档SKILL.md进一步收窄为五条实战触发点脏 checkout、真实源码冲突、分支保护拒绝、一次修复尝试后的 release/CI 失败、npm/GitHub 回读不匹配。除此之外不要停下来询问下一步是否执行——车道计划本身就是授权边界。交接报告五条以内完成后按固定格式汇报SKILL.md严格控制在五行以内已推送的同步提交release 与 CI 运行 URLnpmlatest与beta版本陈旧 PR 清理结果残余风险无风险则写none。与 release-lanes 全车道的衔接sync-main-to-next只是 release-lanes 全流程中的一条车道。完整的车道还包括Status只读状态收集fetch main/next、查 promote PR、查release.yml工作流、查 npm dist-tagsRe-Enter Beta当 promotion 使next退出 pre 模式、且无需直连同步时可用pnpm changeset pre enter beta独立重建 beta 模式chore: enter beta pre-release mode [skip release]Promote Beta To Stable通过promote.yml工作流.github/workflows/promote.yml 内部调用node tooling/scripts/release-branch-prs.mjs promote --version ...生成next - main的 PR合并时必须使用Create a merge commitL59 明确提示不要 squash 或 rebase因为分支血缘是硬性要求Verify Releaseswatchrelease.yml、核对 npm dist-tags 与 GitHub releases。理解了这条捷径在全车道中的位置后就能明白它的设计哲学在稳定发布之后用最少仪式感、最少人工干预的方式让 beta 车道快速追上main同时不破坏双车道的版本语义。对于需要自行维护类似稳定分支 预发布分支双车道仓库的团队release-branch-prs.mjs中的确定性元数据合并、版本不回退校验、changeset 自动生成与提交前验证都是一份可以直接借鉴的工程模板。【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考