尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Rush 单体仓库自动版本升级实战:Huly 平台 bump-changes-from-tag.sh 脚本深度解析

Rush 单体仓库自动版本升级实战:Huly 平台 bump-changes-from-tag.sh 脚本深度解析 Rush 单体仓库自动版本升级实战Huly 平台 bump-changes-from-tag.sh 脚本深度解析【免费下载链接】platformHuly — All-in-One Project Management Platform (alternative to Linear, Jira, Slack, Notion, Motion)项目地址: https://gitcode.com/GitHub_Trending/platform80/platform本文以 Huly 平台仓库中的bump-changes-from-tag.sh脚本为主线完整讲解如何在一个基于 Rush.js 的 npm 单体仓库monorepo中从一个 git 版本标签如v0.7.10出发批量升级所有 Node.js 包的版本号并同步更新包间内部依赖引用。读完本文你将掌握该脚本的四种命令行调用形态、patch/minor/major 三种递增规则、rush.json项目清单解析机制、workspace:^与^两类依赖引用的更新逻辑以及脚本结束后的完整发布流程。脚本定位与应用场景bump-changes-from-tag.sh是 Huly 平台foundations/net子仓库中维护的一个 bash 脚本其详细文档位于 foundations/net/common/scripts/README.md同目录下还有一份快速参考文档 foundations/net/common/scripts/README_BUMP.md。该脚本面向的典型场景是一个包含几十甚至上百个 npm 包、统一由 Rush.js 编排的 monorepoHuly 正是这种形态仓库根目录与foundations/net各自维护独立的 rush.json。当需要发布新版本时手工逐个修改package.json的version字段并同步所有互相引用的内部依赖既繁琐又容易遗漏。该脚本把从哪个版本出发、升几个版本位、哪些包要改、内部依赖怎么同步全部自动化配合彩色日志与最终汇总让整个发版动作可复制、可审查。快速上手命令行用法脚本的完整调用语法为./foundations/net/common/scripts/bump-changes-from-tag.sh git-revision [major|minor|patch]从 脚本源码 可以看到参数解析相当灵活实际存在四种等价形态调用方式行为bump-changes-from-tag.sh无参数自动探测最新v*.*.*标签作为基线执行 patch 升级bump-changes-from-tag.sh minor第一个参数是升级类型自动探测标签 执行指定的升级类型bump-changes-from-tag.sh git-revision第一个参数是 git 修订号以它为基线默认 patch 升级bump-changes-from-tag.sh git-revision bump-type同时指定修订号与升级类型原文档给出的四个实战示例# Patch bump (default) for packages changed in the last 5 commits ./common/scripts/bump-changes-from-tag.sh HEAD~5 # Minor bump for packages changed since a specific tag ./common/scripts/bump-changes-from-tag.sh v0.7.0 minor # Major bump for packages changed since a specific commit ./common/scripts/bump-changes-from-tag.sh abc1234 major # Patch bump (explicit) ./common/scripts/bump-changes-from-tag.sh HEAD~3 patch需要说明的是上述示例中的./common/scripts/...是相对foundations/net仓库根目录的写法若在 Huly 平台仓库根目录执行则应写为./foundations/net/common/scripts/bump-changes-from-tag.sh。标签自动探测机制当不提供修订号时脚本会通过 get_latest_version_tag 函数 自动寻找基线latest_tag$(git tag -l v*.*.* | sort -V | tail -n 1)这条命令按语义化版本顺序sort -V对所有形如v*.*.*的标签排序并取最后一个即最新版本标签。找不到任何匹配标签时会给出明确报错并打印完整用法后退出。若第一个参数直接是major/minor/patch之一也会走同样的自动探测路径见 README_BUMP.md 的 Option 1/2。版本递增规则原文档给出了三种升级类型的语义对照表类型示例说明patch1.2.3→1.2.4Bug 修复、小改动默认minor1.2.3→1.3.0新功能、向后兼容major1.2.3→2.0.0破坏性变更从 increment_version 函数 的实现可以精确看到每次递增后其余位如何复位Patch1.2.3→1.2.4只递增 patch 位Minor1.2.3→1.3.0递增 minor 位并将 patch 位复位为 0Major1.2.3→2.0.0递增 major 位并将 minor 与 patch 位全部复位为 0。以 Huly 当前真实版本为例foundations/net/packages/core/package.json 中hcengineering/network-core版本为0.7.10若基线标签为v0.7.10则 minor 升级的结果是0.8.0patch 升级的结果是0.7.11。预发布版本的处理脚本支持两种版本格式标准 semver1.2.3与预发布版本1.2.3-alpha.1。在递增前代码会先用${version%%-*}剥离-之后的预发布后缀对major.minor.patch三段做纯数字校验非数字直接报 Invalid version format递增完成后再把后缀原样拼回见 increment_version 的版本校验。也就是说预发布后缀本身不会被递增但会被保留在结果中。工作原理从标签到全局版本号原文档归纳的脚本流程共五步Detects changes用git diff --name-only找出自指定修订以来的变更文件Identifies packages解析rush.json得到全部包名与所在目录Matches changes确定哪些包存在变更文件Bumps versions按升级类型递增版本号Updates dependencies更新所有包中指向工作区内部包的依赖引用。需要指出的是步骤 1/3 描述的是 README 文档中的设计意图bump changes——只升级发生过变更的包而从当前 脚本源码 看实际实现采取的是更简单的统一递增策略——先由标签版本算出唯一的新版本号NEW_VERSION随后将rush.json里登记的全部包一并升级到该版本并统一刷新内部依赖引用最后自动执行rush update同步 lockfile。两者在基线版本 全局统一升级上是一致的差异在于是否按变更集筛选包。使用前建议先通读源码确认当前实现与你期望的策略一致。rush.json 解析与包发现脚本通过 get_rush_projects 函数 以一段内嵌 Node.js 代码读取rush.json。这里有一个关键细节Rush 的配置文件允许包含注释脚本先用正则剔除单行注释//与块注释/* ... */再交给JSON.parse随后逐条输出packageName|projectFolder|shouldPublish三字段。以 foundations/net/rush.json 为例其projects清单包括{ packageName: hcengineering/network-core, projectFolder: packages/core, shouldPublish: true }, { packageName: hcengineering/network-pod, projectFolder: pods/network-pod, shouldPublish: false }shouldPublish字段在最终汇总阶段被用于区分两类包值为true的包会标记为(will be published)否则标记为(private package)。脚本为每个项目构造${REPO_ROOT}/${projectFolder}/package.json路径仓库根目录由git rev-parse --show-toplevel获取若文件缺失仅给出警告并跳过不会中断整体流程。该rush.json还展示了脚本所依托的 Rush 环境基线rushVersion: 5.158.1、pnpmVersion: 10.15.1、nodeSupportedVersionRange: 18.20.3 19.0.0 || 20.14.0 25.0.0。执行该脚本前应确保本机 Node.js 处于受支持范围内且已通过rush install完成依赖安装。依赖同步workspace: 与 ^ 两种引用形式版本号批量改写完成后脚本会遍历所有包把其中指向 monorepo 内部包即rush.json中登记过的包名的依赖引用统一更新为新版本覆盖三类依赖段dependenciesdevDependenciespeerDependencies关键的处理逻辑是保留原有的引用前缀风格见 update_dependencies 相关实现if [ $oldDep ~ ^workspace: ]; then pkg.dependencies[$package_name] workspace:^$new_version else pkg.dependencies[$package_name] ^$new_version fi即原本就是workspace:^0.7.8的继续写成workspace:^0.8.0原本是^0.7.8的则写成^0.8.0。这与 Huly 包的实际情况吻合例如 packages/core/package.json 中对hcengineering/platform-rig的引用就是^0.7.8这种普通形式。顺带一提仓库根目录的 common/scripts/bump.js 是另一套基于 Node.js 的版本发布工具其依赖类型覆盖范围更广还包含optionalDependencies并以包内是否声明repository字段来判断是否执行npm publish。如果你需要比本脚本更细粒度的按包发布控制可以对照阅读两者。安全特性与输出解读脚本在健壮性上做了多层防护源码第 12 行起set -e任何命令失败立即终止避免半成品状态校验bump type只能是major|minor|patch否则报错退出校验当前目录处于 git 仓库.git存在校验仓库根目录存在rush.json版本号三段必须为纯数字格式非法时给出清晰报错中间数据全部写入mktemp -d创建的临时目录结束后清理借助BLUE/GREEN/YELLOW/RED四色输出区分 INFO / SUCCESS / WARNING / ERROR完成前打印完整汇总基线版本、新版本、每个包的旧版本 → 新版本及发布属性供人工复核。原文档给出的标准输出示例以HEAD~3 minor 为例示意格式[INFO] Repository root: /path/to/repo [INFO] Checking changes since: HEAD~3 [INFO] Bump type: minor [INFO] Getting changed files since HEAD~3... [INFO] Changed files: packages/core/src/index.ts packages/client/src/client.ts [SUCCESS] Package company/core changed: 0.7.0 - 0.8.0 (minor) [SUCCESS] Package company/client changed: 0.7.0 - 0.8.0 (minor) [INFO] Found 2 package(s) to update [INFO] Updating package versions... [SUCCESS] Updated company/core to version 0.8.0 [SUCCESS] Updated company/client to version 0.8.0 [INFO] Updating dependencies across all packages... [SUCCESS] Version bump complete! [INFO] Summary of changes: ✓ company/core - 0.8.0 (will be published) ✓ company/client - 0.8.0 (will be published) [INFO] Next steps: 1. Review the changes: git diff 2. Run tests: rush test 3. Build all packages: rush build 4. Commit changes: git add . git commit -m Bump versions 5. For publishable packages, run: rush publish汇总段落中(will be published)与(private package)的区分直接来自 汇总打印逻辑 对shouldPublish字段的读取。发布流程脚本结束之后脚本在打印汇总后还会做两件事自动执行rush update以同步 lockfile见 脚本末尾并给出官方推荐的后续步骤清单复核改动git diff同步锁文件rush update脚本已自动执行人工可再确认运行测试rush test全量构建rush build提交改动git add . git commit -m Bump all versions to NEW_VERSION打版本标签git tag vNEW_VERSION git push origin vNEW_VERSION发布可发布包rush publish其中第 6 步回写的vNEW_VERSION标签正是下一次运行时自动探测最新标签的输入从而形成发版 → 打标签 → 下一轮从标签续升的闭环。已知限制与注意事项结合源码与原文档使用时需注意以下几点README 与实现的差异文档描述的仅升级变更包git diff --name-only驱动与当前源码全量统一升级存在出入务必以源码为准确认预期行为预发布后缀不递增1.2.3-alpha.1只会保留后缀不会把 alpha 序号加一不覆盖optionalDependencies如需一并处理可参考根目录 common/scripts/bump.js 的实现环境要求需要 git 仓库 Rush.js monorepo、Node.js用于 JSON 解析改写、bash 4 或 zshrush update自动触发脚本结尾会直接调用rush update若在 CI 或只读环境中运行需留意其网络与写权限需求。综上bump-changes-from-tag.sh是 Huly 这类大规模 Rush monorepo 中批量版本升级 内部依赖同步的实用工具理解其参数形态、递增规则与依赖引用保留逻辑后即可将其平滑接入自己的发版流程并结合git diff、rush test、rush build与rush publish完成一次完整、可审计的版本发布。【免费下载链接】platformHuly — All-in-One Project Management Platform (alternative to Linear, Jira, Slack, Notion, Motion)项目地址: https://gitcode.com/GitHub_Trending/platform80/platform创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表