拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Renovate same-major 版本策略:把“同一大版本内自动滚动“的依赖交给 rollForward,让机器人只管跨 major 升级

Renovate same-major 版本策略把同一大版本内自动滚动的依赖交给 rollForward让机器人只管跨 major 升级【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate在 Renovate 中大多数依赖都遵循语义化版本Semver的升级逻辑patch、minor 各升一档major 单独处理。但有一类特殊场景——比如 .NET SDK 的global.json配置了rollForward: major运行时会自动在同一 major 范围内选用最新可用版本。这时如果 Renovate 对 6.0.300 7.0.0范围内的每一个新版都开 PR只会产生大量改了也没实际效果的噪音 PR。Renovate 为此提供了same-major版本策略把一个具体版本X.Y.Z视为大于等于X.Y.Z、小于X1.0.0的隐式区间从而让 Renovate 只在跨 major 时提议更新。读完本文你将理解该策略的底层实现如何在 semver-coerced 之上做版本改写、每个核心 API 的行为差异、以及如何用packageRules把它配置到 dotnet-sdk 这类场景上。解决什么问题版本本身就是一个隐式区间same-major策略的设计目标是处理某个版本值实际上代表一个兼容范围的情况当配置中写的是X.Y.Z它真正表达的语义是 X.Y.Z X1.0.0——即从该版本起、到下一个 major 之前的所有版本都兼容。这一策略最典型的应用场景是 dotnet-sdk 的rollForward配置。例如一个项目的global.json中{ sdk: { version: 6.0.300, rollForward: major } }rollForward是 .NET SDK 选择 SDK 版本时的回退/向前策略这里取值为major表示选用同一 major 下的最新版本等价于区间约束 6.0.300 7.0.0。既然管理器本身dotnet SDK 解析器已经会在6.x.x范围内自动滚动到最新版Renovate 就不应该在6.0.301、6.0.400这类同 major 更新上创建 PR——那不会改变项目实际行为Renovate 真正有价值的更新提议是7.x.x这种跨 major 的升级。Renovate 的 NuGet 管理器确实会解析global.json中的这类结构其 schema 定义见 nuget/schema.ts其中rollForward字段即对应 SDK 版本滚动策略。实现原理在 semver-coerced 之上做版本改写same-major的实现非常克制它不是从零写一套比较逻辑而是底层复用 semver-coerced 版本策略只在入口处把单版本改写成区间。核心实现在 same-major/index.tsexport const id same-major; export const displayName Same Major Versioning; export const supportsRanges false; /** * Converts input to range if its a version. eg. X.Y.Z - X.Y.Z X1 * If the input is already a range, it returns the input. */ function massageVersion(input: string): string { // istanbul ignore if: same-major versioning should not be used with ranges as it defeats the purpose if (!semverCoerced.isSingleVersion(input)) { logger.warn( { version: input }, Same major versioning expects a single version but got a range. Please switch to a different versioning as this may lead to unexpected behaviour., ); return input; } // we are sure to get a major because of the isSingleVersion check const major semverCoerced.getMajor(input)!; return ${input} ${major 1}; }可以拆出三个关键点supportsRanges false声明。该策略声明自身不支持区间输入——它的语义预设就是输入是一个具体版本号。massageVersion是唯一的魔法入口。它先用 semver-coerced 的isSingleVersion判断输入是否为单版本该判断要求字符串以v或数字开头且可被 semver 强转实现在 semver-coerced/index.ts 的isSingleVersion若是则取出 major 并拼出X.Y.Z X1这样的 semver 区间再委托给 semver-coerced 的对应方法。例如6.0.300会被改写为6.0.300 7交给semver.satisfies一类函数去计算。误用即告警。如果传入的其实是一个区间例如^6.0.0massageVersion会原样透传并打印一条logger.warn提示same-major 期望单版本输入请改用其他 versioning——即源码注释里说的用区间输入会失去该策略存在的意义。最终的导出 API 采用展开继承 定向覆盖的方式export const api: VersioningApi { ...semverCoerced, matches, getSatisfyingVersion, minSatisfyingVersion, isLessThanRange, isGreaterThan, };也就是说isValid、isVersion、getMajor、sortVersions、getNewValue等全部直接复用 semver-coerced 的行为包括对非标准版本号如6.0.300、v6.0的强转能力只有与区间语义和跨 major 判断相关的 5 个方法被覆盖被覆盖的方法行为matches(version, range)把range改写为range major1后调用 semver-coerced 的matches回答version是否落在range的同 major 区间内getSatisfyingVersion(versions, range)返回给定版本列表中满足该同 major 区间的最高版本minSatisfyingVersion(versions, range)返回满足该区间的最低版本isLessThanRange(version, range)回答version是否严格小于该同 major 区间isGreaterThan(version, other)重写为仅比较 majormajor 更大才为true同 major 一律视为不大于相等其中isGreaterThan的重写值得单独说明——这是same-major语义最直接的体现// for same major versioning one version is greater than the other if its minor is greater function isGreaterThan(version: string, other: string): boolean { const versionMajor semverCoerced.getMajor(version)!; const otherMajor semverCoerced.getMajor(other)!; if (!versionMajor || !otherMajor) { return false; } return versionMajor otherMajor; }注意这与 semver-coerced 原始实现比较完整的 semver 值不同在 same-major 视角下3.1.0并不大于3.0.0因为二者同 major视为同一兼容域。任一方无法解析出 major 时保守返回false。用测试用例核对行为边界same-major/index.spec.ts 用少量用例把上述语义钉死了可以直接对照理解各方法的判定边界isGreaterThan——只看 majorexpect(sameMajor.isGreaterThan(4.0.0, 3.0.0)).toBeTrue(); // greater expect(sameMajor.isGreaterThan(2.0.2, 3.1.0)).toBeFalse(); // less expect(sameMajor.isGreaterThan(3.1.0, 3.0.0)).toBeFalse(); // same major - equal expect(sameMajor.isGreaterThan(3.0.0, 3.0.0)).toBeFalse(); // equal expect(sameMajor.isGreaterThan(a, 3.0.0)).toBeFalse(); // invalid versionsmatches——同 major 且不低于该版本才算命中expect(sameMajor.matches(1.0.1, 1.0.0)).toBeTrue(); // 同 major、更高 expect(sameMajor.matches(1.0.0, 1.0.0)).toBeTrue(); // 边界包含 expect(sameMajor.matches(2.0.1, 1.0.0)).toBeFalse(); // 跨 major expect(sameMajor.matches(1.2.3, 1.2.4)).toBeFalse(); // 同 major 但更低落在 下界之外 expect(sameMajor.matches(1.0.0, xxx)).toBeFalse(); // 非法 range最后一条1.2.3vs1.2.4的用例最能说明区间改写的意义它不是同 major 即匹配而是完整执行1.2.4 2的语义低于起点的版本同样被排除。getSatisfyingVersion/minSatisfyingVersion——在版本池中取区间极值expect( sameMajor.getSatisfyingVersion([1.0.0, 1.0.4, 1.3.0, 2.0.0], 1.0.3), ).toBe(1.3.0); // 区间 [1.0.3, 2.0.0) 内最高1.3.02.0.0 被 2 排除 expect( sameMajor.minSatisfyingVersion([1.0.0, 1.0.4, 1.3.0, 2.0.0], 1.0.3), ).toBe(1.0.4); // 区间内最低1.0.4isLessThanRange——是否严格小于整个同 major 区间expect(sameMajor.isLessThanRange?.(2.0.2, 3.0.0)).toBeTrue(); // 低于 3.x 区间 expect(sameMajor.isLessThanRange?.(4.0.0, 3.0.0)).toBeFalse(); // 高于区间 expect(sameMajor.isLessThanRange?.(3.1.0, 3.0.0)).toBeFalse(); // 落在区间内部这些测试共同刻画了同一套判定把range视为[range, major1)的左闭右开区间一切比较都基于该区间展开。实战配置为 dotnet-sdk 的 global.json 启用 same-major该策略已通过 versioning/api.ts 注册进 Renovate 的版本策略模块清单因此可以在 Renovate 配置中通过versioning: same-major指定。以global.json场景为例用packageRules针对该文件单独指定版本策略使 Renovate 只在跨 major 时更新{ packageRules: [ { matchFiles: [(^|/)global\\.json$], versioning: same-major } ] }配合 Renovate 的matchCurrentVersion规则其底层CurrentVersionMatcher正是调用各 versioning 的matches方法做判定见 package-rules/current-version.ts且测试中显式覆盖了versioning: same-major的用例见 current-version.spec.ts还可以把规则收敛得更细例如只在当前 SDK 处于 6.x 时匹配{ packageRules: [ { matchFiles: [(^|/)global\\.json$], versioning: same-major, matchCurrentVersion: 6.0.300 } ] }此时 Renovate 对global.json中sdk.version的更新判定逻辑即为6.0.4xx、6.1.x等全部命中6.0.300 7区间而被视为当前版本已覆盖不产生 PR只有7.x.x这样的跨 major 版本才会触发更新。同理若只想在特定 major 段内启用该策略比如从 7 升 8 才允许也可以结合matchCurrentVersion的正则形式按 major 过滤。配置思路说明以上 JSON 是依据packageRules、matchFiles、matchCurrentVersion等 Renovate 标准配置项与same-major的matches语义组合给出的示例适用于你自行维护的renovate.json具体字段的完整取值请参考 Renovate 的配置文档。使用注意这是实验性支持原文档same-major/readme.md在结尾特别强调该 versioning 属于实验性支持启用前建议在社区中先发起讨论因为可能仍有未覆盖的边界情况。结合源码可以归纳出三条实操注意事项输入必须是单版本。supportsRanges false传入区间时massageVersion会原样透传并输出 warn 日志Same major versioning expects a single version but got a range此时判定会退化为对原始区间的 semver 匹配行为可能与预期不符。依赖 semver 强转能力。底层是 semver-coerced因此6.0、v6.0.300这类非完整写法可以工作完全无法强转的输入如xxx会被matches判为falseisGreaterThan同样保守返回false。同 major 即相等。由于isGreaterThan只比较 major任何影响 Renovate 升级分级release type 判定、PR 标题等的链路在该策略下都只区分 major 边界minor/patch 层面的差异对升级决策是透明的——这正是想要的降噪效果但也意味着该策略不适合用于需要精细区分 minor 的依赖。参考实现与测试位置策略主实现lib/modules/versioning/same-major/index.tsmassageVersion、isGreaterThan重写与 API 组装单元测试lib/modules/versioning/same-major/index.spec.ts底层依赖的 semver-coerced 实现lib/modules/versioning/semver-coerced/index.tsisSingleVersion、matches、getSatisfyingVersion等被复用方法版本策略注册入口lib/modules/versioning/api.tsNuGet 管理器对rollForward字段的 schema 定义lib/modules/manager/nuget/schema.tsmatchCurrentVersion规则匹配器调用 versioningmatcheslib/util/package-rules/current-version.ts官方模块说明文档lib/modules/versioning/same-major/readme.md【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门