Renovate 正则版本策略 regex 版本ing 完全指南:用捕获组自定义任意依赖的版本比较规则 📅 发布时间:2026/9/13 10:05:37 👁 浏览次数: Renovate 正则版本策略 regex 版本ing 完全指南用捕获组自定义任意依赖的版本比较规则【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate当依赖的版本号既不是 SemVer、也不符合 PEP440 等任何现成规范时Renovate 内置的regex版本策略versioning scheme提供了最后的逃生舱你只需写一条带命名捕获组的正则表达式Renovate 就能据此解析、比较、排序版本号并判断兼容性。本篇基于lib/modules/versioning/regex模块的官方说明与源码实现完整讲解regex策略的捕获组语义、配置写法、典型坑点如捕获组必须纯数字以及底层比较逻辑读完即可为任意古怪版本号Maven 后缀、Docker 镜像 tag、linuxserver 系列镜像等配置一套可工作的版本更新策略。regex 策略的定位版本策略的兜底方案Renovate 将版本作为核心模块类型之一负责回答以下问题这个字符串是不是合法版本号版本 X 与约束 Y 是否匹配major/minor/patch 各是什么更新是升级还是降级见 Versioning 模块总览大多数情况下Renovate 会按数据源datasource或包管理器自动选择版本策略。但对 Docker 镜像、GitHub tags 这类没有统一版本号规范的数据源自动选择经常失效——有些镜像用 SemVer有些用 PEP440还有些用日历版本号或完全自定义的格式。官方文档建议在这种情况下通过配置手动指定versioning而regex策略的设计目标就是其他所有版本策略都不够用时的灵活兜底。从源码看regex策略注册在 lib/modules/versioning/regex/index.ts声明supportsRanges false不支持版本范围只做单版本精确比较并继承自 GenericVersioningApi。配置语法regex:前缀加正则versioning配置项的值格式为regex:正则表达式。lib/modules/versioning/schema.ts 中的解析逻辑是以第一个冒号拆分前段为策略名其余部分用冒号重新拼接作为该策略的构造参数——这意味着正则表达式本身可以包含冒号而不会出错。若策略名不存在则回退到默认策略semver-coerced并输出 debug 日志。regex策略的构造函数index.ts#L27-L48做了三件事默认配置未提供正则时使用^(?major\\d)?$即只识别纯数字版本号校验正则中必须至少包含major、minor、patch三者之一的命名捕获组否则抛出config-validation错误提示 regex versioning needs at least one major, minor or patch group defined。这一点在测试中有对应断言index.spec.ts#L10-L12通过 regEx 工具使用 RE2 实现编译正则。注意测试中还验证了不支持 lookahead/lookbehind 等 RE2 不支持的语法(?!y)、(?y)会触发校验错误见 index.spec.ts#L24-L33。捕获组语义七个可命名分量的完整规则regex策略通过正则的命名捕获组提取版本号的各个分量。支持的捕获组及语义如下捕获组必须性语义major/minor/patch三者至少提供一个版本主体。判断是否有更新时按标准语义化版本方式比较。缺省的分量视为0因此你可以用 13 个递增分量来描述任意版本体系build可选第四个版本分量必须用在 major/minor/patch 之后。build级更新按patch级处理revision可选第五个版本分量必须用在build之后。revision级更新同样按patch级处理prerelease可选若被捕获且非空该版本被视为预发布不稳定版本。当配置了ignoreUnstable: true时这类版本会被跳过compatibility可选定义依赖的构建兼容性。Renovate 提议的更新永远不会改变该值。例如固定在1.2.3-linuxlinux被捕获为 compatibility时Renovate 不会把你升到1.2.4-osxcompatibility的概念最初为 Docker 版本策略引入Docker tag 如3.10-slim、12.7.0-debian-10中后缀代表基础镜像/构建兼容性但在其他版本体系中包作者也会用或滥用后缀表达兼容性含义regex策略把它泛化了。源码中的解析过程理解捕获组如何生效看 _parse 方法 最直观protected _parse(version: string): RegExpVersion | null { const groups this._config?.exec(version)?.groups; if (!groups) { return null; } const { major, minor, patch, build, revision, prerelease, compatibility } groups; const release [ isUndefined(major) ? 0 : Number.parseInt(major, 10), isUndefined(minor) ? 0 : Number.parseInt(minor, 10), isUndefined(patch) ? 0 : Number.parseInt(patch, 10), ]; if (build) { release.push(Number.parseInt(build, 10)); if (revision) { release.push(Number.parseInt(revision, 10)); } } return { release, prerelease, compatibility, }; }关键行为正则不匹配exec返回 null时_parse返回null该 tag 直接不是合法版本Renovate 会忽略它每个数值分量都经过Number.parseInt(x, 10)解析——这就是所有捕获组必须只含纯数字约束的由来。文档中的警告Even if there is a string prefix...在代码层面表现为build捕获组若含r4parseInt会截断/解析失败导致比较结果不可靠。捕获组必须只捕获4字符串前缀r要留在正则的非捕获部分。只有当build存在时才会追加build和revision到 release 数组这保证了 4 段、5 段、3 段版本号可以在同一次比较中参与。比较逻辑变长比较与预发布规则真正的比较发生在 GenericVersioningApi._compare变长逐段比较取两侧 release 数组的最大长度逐位比较缺位按 0 填充——因此2.1与2.1.0相等源码注释明确写了 2.1 and 2.1.0 are equivalent预发布比较两侧都有prerelease时用localeCompare(..., { numeric: true })做自然序比较所以a2 a1、b1 a2只有左侧有预发布则左侧较小只有右侧有则右侧较小。这保证3.0.03.0.0b2sortVersions 直接复用_compare测试用例[1.2.3a1, 2.0.1, 1.3.4, 1.2.3]排序结果为[1.2.3a1, 1.2.3, 1.3.4, 2.0.1]index.spec.ts#L294-L302。regex策略还重写了isCompatibleindex.ts#L79-L86两侧版本号都必须可解析且捕获到的compatibility值完全相等才返回 true。默认实现只判断是否是合法版本而regex策略在此叠加了兼容性约束——这正是pin 到1.2.3-linux就不会被升到1.2.4-osx的实现机制。测试用例isCompatible(1.2.3-foo, 2.3.4-foobar) false验证了 compatibility 不同即不兼容index.spec.ts#L58-L81。由于supportsRanges falsematches、getSatisfyingVersion、minSatisfyingVersion都退化为精确等于见 generic.ts#L110-L118测试中getSatisfyingVersion([1.2.3,1.2.4], 3.5.0)返回null即此行为。实战配置示例五个官方场景以下五个示例均来自regex策略官方文档覆盖 Maven 后缀、Docker 预发布、多段构建号、带字符串前缀等典型场景。它们都通过packageRules对特定包生效。示例 1修正 guava 的后缀滥用Maven 包com.google.guava:guava的版本如31.1-jre、31.1-android作者用后缀-jre、-android表达兼容性而非版本号主体。把后缀捕获为compatibilityRenovate 就只会在同一变体内升级{ packageRules: [ { matchPackageNames: [com.google.guava:guava], versioning: regex:^(?major\\d)(\\.(?minor\\d))?(\\.(?patch\\d))?(-(?compatibility.*))?$ } ] }该正则还演示了两个技巧minor、patch段整体可选(\\.(?minor\\d))?缺省按 0 处理因此31、31.1、31.1-jre都能被正确解析与比较compatibility用.*贪婪捕获整个后缀。示例 2Python Docker 镜像预发布 兼容性后缀python镜像的 tag 同时有预发布指示如3.12.0rc1中的rc1和兼容性后缀如-bookworm{ packageRules: [ { matchDatasources: [docker], matchPackageNames: [python], versioning: regex:^(?major\\d)\\.(?minor\\d)\\.(?patch\\d)(?prerelease[^.-])?(-(?compatibility.*))?$ } ] }(?prerelease[^.-])?捕获紧跟版本号、由非点非横线字符组成的预发布段-xxx部分则归入 compatibility。注意该示例也可以改用pep440策略见 Versioning 文档 中Overriding Docker versioning一节。示例 3Bitnami 镜像build revision compatibilityBitnami 镜像 tag 形如12.7.0-debian-10-r69版本主体、发行版兼容性、构建号、修订号俱全。这正是build/revision捕获组的典型用例{ packageRules: [ { matchDatasources: [docker], matchPackageNames: [bitnami/**, docker.io/bitnami/**], versioning: regex:^(?major\\d)\\.(?minor\\d)\\.(?patch\\d)(?:-(?compatibility.)(?build\\d)-r(?revision\\d))?$ } ] }测试文件中有对应的完整验证组index.spec.ts#L354-L420用12.7.0-debian-10-r69、r100、r101验证isCompatible(12.7.0-debian-10-r69, 12.7.0-debian-10-r100) true同 compatibilityisGreaterThan(12.7.0-debian-10-r169, 12.7.0-debian-10-r100) truerevision 参与比较matches(12.7.0-debian-9-r69, 12.7.0-debian-10-r68) falsecompatibility 不同。值得一提的是这个场景在 Renovate 中已有现成的内置 presetlib/config/presets/internal/workarounds.preset.ts 中的bitnamiDockerImageVersioningpreset 使用了同一思路的正则并额外覆盖了gcr.io/bitnami-containers/**等包名说明为 Docker 镜像写 regex 版本策略是官方认可的长期 workaround 手段。示例 4linuxserver/tautullimajor build 带字符串前缀ghcr.io/linuxserver/tautulli的 tag 形如v2.30.1-ls123-ls后的数字是构建号但带字符串前缀。关键写法是把-ls放在非捕获部分只让build捕获纯数字/内容主体{ packageRules: [ { matchDatasources: [docker], matchPackageNames: [ghcr.io/linuxserver/tautulli], versioning: regex:^v(?major\\d)\\.(?minor\\d)\\.(?patch\\d)-ls(?build.)$ } ] }这里^v把 tag 的v前缀留在正则外部-ls也留在外部build只捕获123——严格遵守捕获组必须纯数字原则。示例 5linuxserver/openssh-serverpatch build revision 双前缀openssh-server的 tag 形如9.6_p2-r5-ls8同时用_p、-r、-ls三个前缀标记 patch、build、revision{ packageRules: [ { matchDatasources: [docker], matchPackageNames: [ghcr.io/linuxserver/openssh-server], versioning: regex:^(?major\\d)\\.(?minor\\d)_p(?patch\\d)-r(?build\\d)-ls(?revision.)$ } ] }三个字符串前缀_p、-r、-ls全部写在捕获组之外捕获组内只留下数字或纯内容保证parseInt能正确求值。常见陷阱与验证技巧综合文档警告与源码实现使用regex策略时需要注意至少一个 major/minor/patch 组否则初始化直接抛config-validation错误index.ts#L33-L43。测试中get(regex:not a regex)会因正则本身非法抛出同样的错误说明构造时先验证正则可编译、再验证捕获组。捕获组必须是纯数字prerelease、compatibility除外。build捕获r4将无法正确比较必须捕获4。不要使用 lookahead/lookbehindRE2 不支持会触发校验失败index.spec.ts#L24-L33。ignoreUnstable与prerelease的联动捕获了prerelease且配置ignoreUnstable: trueignoreUnstable 选项说明时预发布 tag 会被整体跳过测试中isStable(1.2.3alpha) false验证了该标记生效index.spec.ts#L104-L113。配置校验流程versioning配置在 schema.ts 中经 zod 的transform实例化——策略不存在时不会报错而是静默回退到semver-coerced并输出 debug 日志策略初始化失败如上述校验错误才会报 failed to initialize。因此如果 regex 正则写错了排查时优先检查日志中的config-validation信息。正则中的冒号安全由于解析时按第一个冒号切分后重新拼接剩余部分schema.ts#L11-L24正则体中包含:不会被误解析。小结regex版本策略以一条带命名捕获组的正则换来了对任意版本号体系的描述能力major/minor/patch至少一个缺省为 0构成主体build/revision扩展至五段比较prerelease标记不稳定版本compatibility锁定构建兼容性。其底层实现index.ts generic.ts保证了变长比较、自然序预发布排序与兼容性过滤的确定性行为。当内置策略都无法解析你的依赖版本时参考上述五个官方示例与测试用例index.spec.ts中的断言矩阵即可为 Docker 镜像、Maven 变体、自托管构建号等场景写出正确且可验证的regex版本策略。【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考