ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

React Router 发布流程全解:change 文件、版本脚本与 GitHub Actions 自动发布流水线

React Router 发布流程全解:change 文件、版本脚本与 GitHub Actions 自动发布流水线 React Router 发布流程全解change 文件、版本脚本与 GitHub Actions 自动发布流水线【免费下载链接】react-routerDeclarative routing for React项目地址: https://gitcode.com/GitHub_Trending/re/react-routerReact Router 的版本发布几乎完全由自动化流水线完成开发者只需把描述变更的 change 文件随 PR 合入main后续的分支管理、版本号更新、CHANGELOG 生成、npm 发布和 GitHub Release 创建全部由脚本与 GitHub Actions 接手。本篇基于仓库中的 DEVELOPMENT.md 与 scripts/changes/ 下的 TypeScript 脚本、.github/workflows/release.yml讲清楚这条“change 文件驱动”的发布链路是如何工作的帮助你在该仓库或参考其模式搭建类似多包发布系统中理解从一次普通发版到 hotfix 热修复的完整操作路径。发布系统的两个组成部分DEVELOPMENT.md 对发布流程的总述是Releases are handled by a mostly automated process consisting of:TypeScript scripts inscripts/changes/Therelease.ymlGithub workflow落到仓库中这两个组成部分分别是scripts/changes/目录下的 TypeScript 脚本各自对应发布链路的一个环节add.ts交互式创建 change 文件对应根package.json中的changes:add脚本changes.tschange 文件的解析、校验与 changelog 内容生成的核心库version.ts更新版本号、生成 CHANGELOG、删除 change 文件并创建 release 提交changes:versionpr.ts创建或更新版本化的 release PRchanges:prpublish.ts发布所有包到 npm、打 tag、创建 GitHub Releasechanges:publishvalidate.ts单独校验所有 change 文件与包级 CHANGELOG 是否齐备changes:validate。.github/workflows/release.yml 工作流。值得注意的是该文件头部注释解释了为什么所有发布逻辑集中在这一个文件里——npm 的 Trusted Publishing 配置只允许指定单个 GitHub workflow 文件因此稳定版发布与实验性experimental发布共用这一个文件靠不同的触发条件区分对应 job。change 文件一切发布的起点整个流程的“输入”是每个包目录下.changes/目录里的 Markdown 文件。以仓库中真实存在的 change 文件 packages/react-router/.changes/patch.submit-relative-option.md 为例其内容只有一句话Properly respect the relative option in useSubmit/fetcher.submit when resolivng the action path文件名与内容遵循严格的约定这些规则由 changes.ts 中的parsePackageChanges函数实现并强制校验文件名格式为bump.描述.mdbump必须是major、minor、patch或unstable四种之一unstable会在后续被规范化为 semver 递增见 changes.ts#L16-L36。例如minor.add-feature.md文件不能为空且首行不能以-或*开头的 bullet 符号——因为生成 CHANGELOG 时项目符号会自动补上正文标题只允许 4~6 级####到######因为 change 文件最终嵌套在已经使用 1~3 级标题的 CHANGELOG 中破坏性变更以 BREAKING CHANGE 前缀标注必须搭配major.前缀否则校验报错每个包的.changes/目录必须存在且包含.gitkeep例如 packages/react-router/.changes/.gitkeep以便该目录在 change 文件被清理后依然保留在仓库里。创建 change 文件不需要手写文件名运行pnpm changes:add即 add.ts脚本会用prompts交互地让你选择包、选择 bump 类型并根据描述自动生成去掉英文停用词后的 slug 文件名。另外仓库还有 change-file-check.yml 工作流在 PR 层面检查变更是否附带了 change 文件。常规发布流程main 分支DEVELOPMENT.md 描述的常规发布步骤如下原文骨架把所有待发布的改动连同 change 文件合并到mainrelease.yml发现main分支存在 change 文件时触发 “PR” 步骤运行 scripts/changes/pr.ts从main创建或更新版本化发布分支如release-v7-pr运行 scripts/changes/version.ts更新版本、生成 changelog、删除 change 文件从release-vmajor-pr向main打开一个 PR该 PR 合并后release.yml再次针对main运行此时发现没有 change 文件触发needs-publish检查查询 npm 判断当前react-router版本是否已发布若需要发布触发 “publish” 步骤运行 scripts/changes/publish.ts发布所有包到 npm、打 tag 并推送、创建 GitHub Releaserelease-vmajor-pr分支在 PR 合并后可以删除。结合 release.yml 的 job 编排可以看清上述每一步的实际落点。工作流由push到main/hotfix/v7分支触发另有workflow_dispatch用于实验性发布并且设置了concurrency组且cancel-in-progress: false——注释里解释了原因发布流程一旦开始就要完整跑完后续提交比如格式修正不应打断发布与评论动作。四个 job 的分工check先用find packages/*/.changes -name *.md ! -name README.md扫描是否有 change 文件输出has_change_files。若没有再执行needs-publish步骤读取packages/react-router/package.json的version用npm view react-router$version version对比 npm 上是否已存在同版本据此输出should_publishpull_request当has_change_files true时运行pnpm changes:pr携带FORMAT_PATtokenpublish当should_publish true时执行pnpm build后运行pnpm changes:publish --branch${{ github.ref_name }}comment仅在main分支发布成功后运行pnpm run release-comments自动在已发布的 issue/PR 下追加“已随 vX.Y.Z 发布”的评论对应 release-comments.ts。pr.tsrelease PR 的创建与更新pr.ts 的行为比文档描述多出几个值得注意的细节脚本开头通过git rev-parse --abbrev-ref HEAD取当前分支并强制其必须是main、hotfix或v7三者之一pr.ts#L40-L46发布分支名由 bump 的主版本号决定release-vmajor-prhotfix 场景为hotfix-vmajor-pr主版本号取自本次 releases 中第一个包的下一个版本pr.ts#L70-L73若解析后没有任何待发布的 change 文件脚本不会报错退出而是检查是否存在同名的陈旧 release PR若有则自动关闭并注明原因pr.ts#L75-L92——这正是“迭代 release PR”后 PR 能被自动刷新/收敛的机制非预览模式下必须提供GITHUB_TOKEN随后把 git 身份配置为 Remix Run Bot执行git checkout -B branchgit reset --hard origin/base再运行pnpm changes:version最后git push origin branch --force并通过 GitHub API 创建带pkg:react-router标签或更新 PRPR 正文由generatePrBody生成包含版本对照表和各包 changelog 预览由于 GitHub 对 PR 正文有 65,536 字符限制脚本以 60,000 字符为安全上限超限时会按包截断 changelog 部分并提示“完整内容见 PR diff”pr.ts#L50-L51、pr.ts#L253-L283。PR 头部固定写着“This PR is managed by the release workflow. Do not edit it manually.”。version.ts版本、CHANGELOG 与清理version.ts 对应文档中 “Runs version.ts: Updates versions / Generate changelogs / Deletes change files” 三步具体实现为对每个待发布包updatePackageJson把包的package.json的version写为计算出的下一版本updateChangelog把新条目插入该包CHANGELOG.md第一个##版本条目之前找不到则追加到文末deleteChangeFiles删除.changes/下除README.md外的所有.md文件。此外它还会更新根目录 CHANGELOG.md聚合所有包的变更每条前缀包名可选地引入人工撰写的scripts/changes/whats-changed.md存在时作为 “Whats Changed” 段落并入消费后删除见 version.ts#L140-L183附上vold...vnew的 compare 链接并用updateTableOfContents重新生成根 CHANGELOG 顶部details折叠块内的目录复用 GitHub 的标题锚点算法含重复标题计数。最后commitChanges用生成的 commit message 执行git add . git commit。该脚本支持两个命令行选项version.ts#L4-L9--no-commit只改文件不提交便于人工 review--preview对应根命令pnpm changes:preview只打印将要发生的版本变更、changelog 内容与 commit message不做任何修改。publish 环节pnpm 发布、tag 与 GitHub Releasepublish.ts 由 CI 的 publish job 以pnpm changes:publish --branch分支名调用参数为--branch必填本次发布来自的分支决定行为分支——main分支创建的 GitHub Release 会被标记为 Latestpublish.ts#L62-L63--skip-ci-check跳过“仅限 CI 运行”的安全检查脚本在非 CI 环境且非 dry-run 时默认拒绝运行publish.ts#L183-L190--dry-run不真正发布而是查询 npm 计算哪些版本未发布并预览将要创建的 GitHub Releasetag、名称、正文。实际发布命令是pnpm publish --recursive --filter ./packages/* --access public --no-git-checks --report-summary--report-summary让 pnpm 在根目录输出pnpm-publish-summary.json脚本随后读取该文件得到“实际发布了哪些包、什么版本”据此为每个已发布包创建形如react-routerx.y.z的 git tag已存在则跳过、git push --tags并仅为react-router主包创建 GitHub Release正文指向根 CHANGELOG 对应版本锚点已存在则跳过。若某个 Release 创建失败脚本会汇总打印并提示需要手动补建同时以非零码退出。从源码结构还可以看到一个特殊分支当发布分支为v7时发布被拆成两阶段——除react-router-dom外的所有包以version-7dist-tag 发布react-router-dom单独以latest发布publish.ts#L200-L209。这与pr.ts中允许v7作为发布分支的设定相互印证属于维护 v7 旧版本线时的专用路径。工作流中还有一个文档未展开但同属release.yml的 jobexperimental-release由workflow_dispatch手动触发并指定分支执行experimental:version打 tag 并推送pnpm buildexperimental:publishrelease.yml#L170-L209用于从任意分支发布实验版本。迭代一个处于 open 状态的 release PRDEVELOPMENT.md 的 “Iterating a release PR” 一节说明release PR 尚未合并时如需补充改动正确做法是不要直接改 release 分支而是从main拉分支做改动按需添加 change 文件推到 GitHub 并向main发 PRReview/批准后将 PR 合并到main这会触发上述pr.ts逻辑——由于 change 文件又出现了工作流会重新运行version.ts并强制推送更新已存在的release-vmajor-pr分支与 PRgit checkout -B--force推送 updatePr刷新标题和正文。反过来如果所有 change 文件都已处理完、main上不再有 change 文件pr.ts会检测到releases.length 0并自动关闭陈旧的 release PR保证 PR 状态始终与 change 文件一致。Hotfix 发布流程Hotfix 与常规流程的差别在于基线分支不是main而是从要修复的那个版本 tag 拉出的hotfix分支DEVELOPMENT.md 原文步骤从对应版本的 git tag 创建 hotfix 分支并推送到远端git checkout -b hotfix {tag} git push origin --set-upstream hotfix从hotfix再拉分支做修复连同 change 文件以 PR 形式合入hotfixrelease.yml检测到hotfix分支上有 change 文件触发 “PR” 步骤pr.ts从hotfix创建或更新hotfix-v7-pr之类的版本化分支更新新分支上的版本号、生成对应的CHANGELOG.md条目、删除 change 文件从hotfix-vmajor-pr向hotfix分支发 PR该 PR 合并后工作流再次针对hotfix运行且发现无 change 文件触发 “publish” 步骤publish.ts发布所有包、打 tag 推 tag、创建 GitHub Release最后把hotfix分支合并回main并推送然后删除hotfix分支。从实现上看这一流程与常规流程共用同一套脚本pr.ts通过当前分支名判断前缀baseBranch hotfix ? hotfix : releasepr.ts#L72-L73PR 标题也会相应显示 “Hotfix Release vX.Y.Z”而 release.yml 的push触发器本身就包含hotfix分支因此无需额外配置。需要留意的是 publish 脚本中 GitHub Release 的 Latest 标记仅在main分支发布时设置hotfix 发布不会抢占 Latest。本地可用的校验与预览命令结合根 package.json 的 scripts 定义围绕这套流程常用的命令如下均在仓库根目录执行命令作用pnpm changes:add交互式创建 change 文件选包、选 bump 类型、写描述pnpm changes:validate校验所有包的 change 文件与CHANGELOG.md是否齐备有错时退出码为 1pnpm changes:preview以 preview 模式运行version.ts只打印将发生的版本/CHANGELOG 变更pnpm changes:version真正更新版本号、CHANGELOG 并创建 release commitCI 中由pr.ts调用pnpm changes:pr --preview预览将创建/更新的 release PR 的分支、标题与正文不做任何修改pr.ts的--preview模式下无需GITHUB_TOKENpnpm changes:publish --branchmain --dry-run干跑发布列出将要发布的包与版本、预览 GitHub Release不产生 tag这些预览/校验入口让发布动作在合并与推送之前都可以被完整复核change 文件的合法性在validate与pr.ts/version.ts内部会被重复校验parseAllChangeFiles失败即退出版本与 changelog 的形态可先经--preview/--dry-run确认符合 DEVELOPMENT.md 所描述的“mostly automated” 但每步皆可人工预检的设计。小结React Router 的发布体系是一条以change 文件为唯一输入的可重复流水线add.ts产出 change 文件 →release.yml的checkjob 识别分支状态 →pr.ts在版本化分支上运行version.ts并自动开/更 release PR → PR 合并后needs-publish比对 npm 状态 →publish.ts完成 npm 发布、git tag 与 GitHub Release最后commentjob 回填 issue/PR 评论。hotfix 场景把同样的脚本复用在从版本 tag 派生的hotfix分支上只改变分支前缀与 Latest 标记行为。理解 scripts/changes/ 中每个脚本与 release.yml 中各 job 的对应关系是维护这套流程或将其迁移到自己的多包仓库的关键。【免费下载链接】react-routerDeclarative routing for React项目地址: https://gitcode.com/GitHub_Trending/re/react-router创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表