多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

vercel CLI 稳定版本发布全流程:changesets 驱动的 Release Runbook 深度解析

vercel CLI 稳定版本发布全流程:changesets 驱动的 Release Runbook 深度解析 CLI后端云原生【免费下载链接】vercelDevelop. Preview. Ship.项目地址https://gitcode.com/gh_mirrors/ve/vercel点击查看免费下载本指南以仓库根目录下的 RELEASE.mdCLI Release Runbook为骨架完整讲解 vercel 单仓库中vercelCLI 稳定版本从 changesets 合并、Version Packages自动 PR、管理员强制合并到最终发布 npm 的全链路并深入到 .github/workflows/release.yml 与 utils/determine-release.mjs 等源码实现解释发布 PR 看起来卡住是预期行为这一核心设计以及发布后验证、latest回滚和相关发布工作流。读完本文你将掌握在类似 changesets 单仓库中安全、可复用地设计和运维稳定版发布流水线的完整方法。一、发布流程总览TL;DRvercelCLI 的稳定版本发布遵循一条高度自动化的流水线全链路可概括为四步将带有 changesets 的普通 PR 合并进main分支等待Release工作流自动打开/更新名为Version Packages的发布 PR由具备分支/规则集绕过权限的管理员对该 PR 执行强制合并force merge即使必需检查看起来卡住也不要等待合并动作再次触发main上的Release工作流由changesets/action执行版本更新与 npm 发布。整个流程的核心思想是Version PackagesPR 只扮演快速交接fast handoff的角色真正的发布动作发生在它合并回main之后的下一次Release运行中。因此仓库刻意不为这个机器人生成的 PR 跑完整的 CI 检查。二、发布前置条件在触发一次稳定版发布之前需要确认以下三项前提全部满足changesets 已合并本次发布所包含的变更changeset已经合入main分支且没有遗留未处理的 changesetRelease工作流健康main上最近的Release工作流运行正常尤其是determine与release两个 job 没有持续失败管理员可用拥有分支/规则集绕过权限的管理员随时可对发布 PR 执行强制合并该权限不在普通维护者手中原文档指向的绕过用户列表位于仓库 Settings → Rules 对应规则集中属仓库内部配置读者可在自己的仓库中通过Settings → Rules查看等效配置。三、为什么Version PackagesPR 看起来卡住了这是本仓库发布模型中最容易让新人困惑的一点也是文档重点解释的设计意图Version PackagesPR 由 .github/workflows/release.yml 中的changesets/action使用GITHUB_TOKEN机器人身份创建对于这个机器人生成的 PR仓库故意不期望它运行 PR CI尽管如此规则集Rulesets仍可能要求Summary、Summary (lint)、Summary (python-packages)等检查通过这些检查在这个 PR 上会无限期地停留在 expected/pending 状态。这是预期且刻意为之的行为——因为在 release.yml 中这些Summary*检查 job如Summary (release)见 .github/workflows/release.yml绑定的是main分支的 push 触发而不是 PR 触发。发布 PR 合并回main的那一刻真正的发布工作流会立即被触发因此团队不为这个 PR 等待 CI而是直接走管理员强制合并路径。四、稳定版发布逐步操作流程步骤 1等待发布 PRchangesets 落地main后GitHub Actions 的Release工作流会运行并创建或更新标题为Version Packages的 PR。该工作流的触发条件是on: push: branches: - main即每次向main推送都会触发它依据当前是否存在 pending changeset 决定是打开/更新发布 PR还是直接发布详见下文源码解析。步骤 2校验 PR 内容合并前管理员应审查该 PR 的 diff确认其只包含发布机制生成的预期变更典型包括各包package.json中的 version 字段更新各包的 changelog变更日志更新例如 packages/cli/CHANGELOG.md、packages/backends/CHANGELOG.md 等版本同步引发的附带文件更新如 Python 包的pyproject.toml与packages/python/src/package-versions.ts见下文ci:version说明。如果 PR 中出现了预期之外的文件变更必须停下来调查后再合并防止把非发布内容混入版本号提交。步骤 3使用管理员绕过权限强制合并管理员应使用 bypass/force-merge 权限合并Version PackagesPR操作要点不要等待那些根本没在运行的必需检查它们永远不会通过等待只会阻塞发布这是本仓库发布 PR 的既定路径普通 PR 的常规合并规范不适用于此 PR。步骤 4确认main上的发布运行合并 PR 会推送代码到main再次触发Release工作流。这一次运行中changesets/action会依次执行两个脚本定义于 package.jsonpnpm ci:version pnpm ci:publish只要存在可发布的变更就会发布包包括vercelCLI 本身并创建对应的 git tag。五、源码级解析Release工作流如何决定发布还是只开 PRchangesets/action的行为是二选一的互斥逻辑存在 pending changesets→ 只创建/更新Version PackagesPR不发布任何东西不存在 pending changesets即发布 PR 被合并后的形态→ 执行 publish 脚本这是vercel唯一能到达 npm 的时机。为了在下一次changesets/action运行前就知道这次 push 是否会真正发布.github/workflows/release.yml 专门设置了一个determinejob运行仓库自研脚本 utils/determine-release.mjs 并输出两个关键信号输出含义判定依据will-publish本次 push 是否会真正执行ci:publishchangesets.length 0无 pending changesetsshould-release-binary本次发布是否包含vercel从而需要先发布原生二进制包无 pending changesets 且vercelcli版本尚未存在于 npm这个脚本的巧妙之处在于复用官方解析逻辑它直接加载changesets/cli依赖中的changesets/read来读取 changeset 状态见 utils/determine-release.mjs保证与changesets/action自身的行为不会产生漂移硬性拒绝 pre modeassertNotPreMode会在发现.changeset/pre.json存在时直接抛错见 utils/determine-release.mjs因为 pre 模式下 pending changesets 的判定逻辑不同宁可失败也不静默误判npm 检查带重试isPublishedOnNpm对npm view vercelversion version做最多 3 次重试只有遇到明确的 E404 才判定未发布其余网络类错误一律按未发布处理见 utils/determine-release.mjs——因为误判已发布会让vercel在没有原生依赖的情况下发布而误判未发布最多只是多构建一次二进制代价更小。determinejob 的输出进一步驱动了工作流的编排见 .github/workflows/release.ymlreleasejob 只有在determine成功且binaryjob 成功或跳过时才会运行binaryjob复用 .github/workflows/release-binary.yml 可复用工作流负责在发布vercel前先构建并发布vercel/vc-native-*原生包通过if: false当前处于暂时禁用状态并在环境变量VERCEL_SKIP_NATIVE_DEPS1时让 npm 发布跳过原生 optionalDependencies 的缺失校验见 .github/workflows/release.yml。六、发布执行的幕后ci:version与ci:publishci:version版本号落地changeset version node utils/sync-python-version.js uv lock pnpm install --no-frozen-lockfile这条命令见 package.json依次完成changeset version根据 changesets 内容提升各包版本号并生成 changelognode utils/sync-python-version.js将 Python 运行时包的版本从package.json同步到pyproject.toml并重新生成packages/python/src/package-versions.ts版本导出文件见 utils/sync-python-version.js保证vercel/python-runtime与vercel/python-workers两个 Python 包与 npm 包保持同版本uv lock更新 Python 依赖锁文件pnpm install --no-frozen-lockfile让 workspace 内互相引用的版本依赖关系重新对齐。ci:publish真正的发布动作node utils/inject-native-optional-deps.mjs node utils/publish-runtimes.mjs bash utils/npm-publish.sh changeset tag这条命令见 package.json的发布顺序体现了先依赖后本体的原则utils/inject-native-optional-deps.mjs为vercel注入原生二进制可选依赖node utils/publish-runtimes.mjs在 npm 发布之前先发布非 npm 的运行时包——目前委托给python/publish.mjs发布 PyPI Python 包见 utils/publish-runtimes.mjs且任何运行时发布失败都会中止后续 npm 发布bash utils/npm-publish.sh执行真正的 npm 发布稳定版走latestdist-tagchangeset tag为发布创建 git tags。发布时工作流还设置了NPM_CONFIG_PROVENANCE: true启用 npm 来源证明provenance并使用commitMode: github-api让发布提交与 tag 可以用$GITHUB_TOKEN签名见 .github/workflows/release.yml。七、发布后验证Release工作流成功后建议按以下命令验证发布结果# 查看 npm 上的最新版本号 npm view vercel version # 查看所有 dist-taglatest / canary 等 npm dist-tag ls vercel此外可以可选核对 changesets 创建的 git tags 是否存在且指向正确的提交。验证时需要注意如果发布包含原生包还需确认vercel/vc-native-*各平台包已可在 npm 上安装release-binary.yml 中甚至有最多 12 次、每次间隔 10 秒的全局安装轮询验证逻辑见 .github/workflows/release-binary.yml。八、回滚与热修复Rollback Latest Tag工作流如果latestdist-tag 指向了错误的版本无需重新发布只需调整 npm dist-tag。操作方式工作流Rollback Latest Tag.github/workflows/rollback-latest-tag.yml通过workflow_dispatch手动触发输入期望的稳定版本号例如39.2.4。该工作流内部做了三层保护见 .github/workflows/rollback-latest-tag.yml格式校验输入必须匹配^[0-9]\.[0-9]\.[0-9]$的X.Y.Z格式否则直接失败存在性校验先执行npm view vercel版本 version确认该版本确实存在于 npm不存在则打印最近 20 个版本并退出执行回滚npm dist-tag add vercel版本 latest使用NPM_TOKEN_ELEVATED凭据切换 dist-tag最后再次打印npm dist-tag ls vercel供确认。九、相关发布工作流全景仓库中与发布相关的自动化不止稳定版一条线它们共同构成了完整的发布矩阵工作流文件触发方式发布目标说明.github/workflows/release.ymlpush 到mainnpmvercel等包稳定版主链路本文核心.github/workflows/canary.ymlpush 到mainnpm canary 快照每次main推送都会执行pnpm ci:version:canarypnpm ci:publish:canary见 package.json发布canarydist-tag 快照用于提前验证.github/workflows/release-python-package.ymlworkflow_dispatchPyPI手动发布 Python 包输入支持all或具体包名并可--force强制发布实际执行node python/publish.mjs.github/workflows/release-crates.ymlpush 到main限crates/vercel_runtime/**、Cargo.toml、Cargo.lock路径或手动crates.io通过crates-io-auth-action获取临时 token 后执行cargo publish作用于crates/vercel_runtime.github/workflows/rollback-latest-tag.ymlworkflow_dispatchnpm dist-tag回滚latest不重新发布.github/workflows/release-binary.ymlworkflow_call被 release.yml 调用npm 原生包构建 macOS/Linux/Windows 五平台二进制darwin-arm64/x64、linux-arm64/x64、win-x64含 Apple 签名/公证与 smoke test当前在 release.yml 中临时禁用十、常见故障模式与排查原文档总结了三类最常见的发布故障及其处理思路结合源码可进一步细化1.Version PackagesPR 没有出现排查查看main上最新一次Release工作流运行确认在changesets/action步骤之前是否有 job 失败。常见诱因包括determinejob 中的脚本报错例如误创建了.changeset/pre.json触发assertNotPreMode硬失败、依赖安装失败或构建失败release.yml 在调用changesets/action前会执行pnpm build见 .github/workflows/release.yml。2.Version PackagesPR 检查卡住结论这是该流程的预期行为不是故障。规则集要求的Summary系列检查在该 PR 上永远不会通过无需等待直接走管理员强制合并即可。3. 合并后main上的发布运行失败处理先修复main上的问题然后重新运行Release工作流或者先合入修复代码让下一次 push 触发的Release完成发布。注意releasejob 的失败会连带Summary (release)job 失败见 .github/workflows/release.yml排查时优先看determine、binary、release三个 job 各自的结果。结语vercelCLI 的稳定版发布流水线是一个changesets 状态机 管理员强制合并 main 二次触发的典型实现它把生成版本号与真正发布拆成两次mainpush 接力完成用determine-release.mjs在发布前精确预判动作用ci:version/ci:publish串起 npm、PyPI、crates.io 与原生二进制的多语言发布矩阵最后用Rollback Latest Tag提供不重发的回滚兜底。理解这套模型后你既可以在本仓库中顺畅地推动一次 CLI 发版也可以把同样的自动开 PR 管理员强制合并 二次触发发布模式复用到任何基于 changesets 的 pnpm 单仓库中。赞分享CLI后端云原生【免费下载链接】vercelDevelop. Preview. Ship.项目地址https://gitcode.com/gh_mirrors/ve/vercel点击查看免费下载相关推荐Mastra 版本发布工作流internal/changeset-cli 自定义 Changesets 工具深度解析Mastra 版本发布工作流internal/changeset cli 自定义 Changesets 工具深度解析 导读 internal/change人工智能Agent 框架AI AgentRAG后端OpenZeppelin Contracts 全自动发布流程解析Changesets、release-vX.Y 分支与 release-cycle 工作流OpenZeppelin Contracts 全自动发布流程解析Changesets、release vX.Y 分支与 release cycle 工作流 O区块链Web3GreptimeDB 版本发布 Runbook从 Tag、GitHub Release 到文档 PR 的完整发布流程GreptimeDB 版本发布 Runbook从 Tag、GitHub Release 到文档 PR 的完整发布流程 本文是 GreptimeDB开源可观测时序数据库数据库可观测性上一篇Vendure电商平台Admin UI页面操作栏按钮扩展指南下一篇BV 开发者指南Jetpack Compose 在TV应用中的最佳实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表