ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Renovate node 版本化方案:v 前缀归一化、LTS 稳定性判定与发布日程驱动的实现解析

Renovate node 版本化方案:v 前缀归一化、LTS 稳定性判定与发布日程驱动的实现解析 Renovate node 版本化方案v 前缀归一化、LTS 稳定性判定与发布日程驱动的实现解析【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate本文基于 Renovate 仓库中 node 版本化方案说明 展开完整覆盖该方案对 npm 版本化的包装逻辑、v前缀去除、Node.js LTS 稳定性判定规则、LTS 代号codename升级以及 Docker 标签后缀的适用边界。读完你可以理解在 Renovate 配置versioning: node之后每个关键判定函数isStable、getNewValue、isValid、matches背后的具体实现以及为什么 Node.js 27 之后稳定性判定从奇偶规则切换为发布日程驱动。一、定位npm 版本化的薄封装node 版本化 在 API 层面显式声明自己是 npm 版本化 的包装器// lib/modules/versioning/node/index.ts (L7-L10) export const id node; export const displayName Node.js; export const urls []; export const supportsRanges false;其api导出先展开...npm再覆盖五个方法index.ts#L97-L106export const api: VersioningApi { ...npm, isStable, getNewValue, isValid, matches, getSatisfyingVersion, minSatisfyingVersion, allowUnstableMajorUpgrades: true, };也就是说版本比较、排序、getMajor/getMinor/getPatch、区间匹配等基础能力全部复用 npm 版本化实现底层是semver与semver-stable包node 方案只额外注入三类行为去除v前缀替换版本号时不保留v前缀LTS 感知新大版本不立即视为稳定要等其发布线进入 LTS 阶段代号codename支持erbium、gallium等 LTS 代号可被识别并参与版本替换。这个api会通过 版本化注册表 暴露给配置项versioning用户即可在renovate.json/packageRules中写versioning: node启用。二、规则一替换时去除v前缀Node.js 官方发布渠道常带v前缀如v18.12.0而仓库里.nvmrc、engines字段通常不写v。node 方案在getNewValue中做了归一化index.ts#L21-L45function getNewValue({ currentValue, rangeStrategy, currentVersion, newVersion }: NewValueConfig): string | null { // Try to use codename if the current value is a codename if (rangeStrategy ! pin findScheduleForCodename(currentValue)) { const newSchedule findScheduleForVersion(newVersion); if (newSchedule?.codename) { return newSchedule.codename.toLowerCase(); } } const res npm.getNewValue({ currentValue: normalizeValue(currentValue), rangeStrategy, currentVersion, newVersion, }); if (res isVersion(res)) { // normalize out any v prefix return valid(res); } return res; }关键点在isVersion(res)之后调用valid(res)semver.valid会返回不带前缀的规范版本号于是v1.1.0被替换为1.1.0、v27.0.0-alpha.1被替换为27.0.0-alpha.1。单元测试 index.spec.ts#L15-L37 直接验证了这一点${1.0.0} | ${replace} | ${1.0.0} | ${v1.1.0} | ${1.1.0} ${~8.0.0} | ${replace} | ${8.0.2} | ${v8.2.0} | ${~8.2.0} ${27.0.0-alpha.1} | ${replace} | ${27.0.0-alpha.1} | ${v27.0.0-alpha.2} | ${27.0.0-alpha.2} ${27.0.0-alpha.1} | ${replace} | ${27.0.0-alpha.1} | ${v27.0.0} | ${27.0.0}三、规则二LTS 稳定性判定isStable这是 node 方案存在的核心理由。isStable的实现分三步index.ts#L51-L77export function isStable(version: string): boolean { if (!npm.isStable(version)) { return false; } const schedule findScheduleForVersion(version); if (!schedule) { return false; } // Node 27 reworked the release schedule: the dedicated LTS date was dropped // (every line now eventually becomes LTS), so the LTS-promotion point is read // from a different milestone for those newer entries. let ltsStart schedule.lts; if (schedule.alpha) { ltsStart schedule.maintenance; } if (!ltsStart) { return false; } return DateTime.local() DateTime.fromISO(ltsStart); }3.1 预发布版本永远不稳定第一步委托给npm.isStable其底层是semver-stable见 npm/index.ts#L104。因此任何带预发布后缀的版本——包括27.0.0-alpha.1、12.0.3a——都直接判为不稳定。测试用例index.spec.ts#L85-L92明确断言expect(nodever.isVersion(27.0.0-alpha.1)).toBe(true); // 是合法版本 expect(nodever.isStable(27.0.0-alpha.1)).toBe(false); // 但永远不稳定这与文档中预发布版本如27.0.0-alpha.1始终被视为不稳定的描述一一对应。3.2 用发布日程数据推导 LTS 起点第二步通过 schedule.ts 查询内置的 Node.js 发布日程// lib/modules/versioning/node/schedule.ts (L29-L35) export function findScheduleForVersion(version: string) { const major semver.getMajor(version); const schedule nodeSchedule[v${major!}]; return schedule; }日程数据结构定义在 types.tsexport interface NodeJsSchedule { alpha?: string; // Node 27 新日程的 alpha 起点 lts?: string; // 进入 LTS 的日期Node 26 及更早 maintenance?: string; end: string; start: string; codename?: string; }以 node-js-schedule.json 中的真实条目为例v18: { start: 2022-04-19, lts: 2022-10-25, maintenance: 2023-10-18, end: 2025-04-30, codename: Hydrogen }, v27: { alpha: 2026-10-28, start: 2027-04-22, maintenance: 2027-10-20, end: 2030-04-30, codename: }可以看到v27条目没有lts字段、只有alpha和maintenance——这正是isStable中if (schedule.alpha) ltsStart schedule.maintenance分支存在的原因从 Node.js 27 起官方调整了发布日程每个大版本最终都会进入 LTS因此没有专门的 LTS 起始日代码改从maintenance里程碑对 v27 是2027-10-20读取 LTS 起点。3.3 新旧两套稳定性规则文档说明了规则演进的两个阶段Node.js 26 及更早发布线遵循奇偶方案奇数大版本永远不会进入 LTS。这与日程数据一致——v5、v7、v9、v11、v13、v15、v17、v19、v21、v23、v25均无lts字段isStable中ltsStart为undefined直接返回false即奇数大版本的任何版本在 node 方案下永远是不稳定的。Node.js 27 及以后每个大版本最终都成为 LTS稳定性从发布日程推导而不是看大版本号奇偶。测试用例 index.spec.ts#L39-L70 通过冻结系统时间来精确验证了两种形态// Node 27 schedule (new shape): alpha 2026-10-28, Current from 2027-04-22, // LTS (maintenance) from 2027-10-20. const t3 DateTime.fromISO(2027-06-01); // Current 阶段尚未 LTS const t4 DateTime.fromISO(2027-11-01); // LTS 阶段 ${27.0.0} | ${t3} | ${false} ${27.0.0} | ${t4} | ${true} ${v27.0.0} | ${t4} | ${true} ${27.0.0-alpha.1} | ${t4} | ${false}同时16.0.0在 2020-09-01LTS 日 2021-10-26 之前为false、在 2021-06-01 仍为false而14.0.0在 2021-06-01 已为true。值得注意的是判定是以整条发布线为粒度的源码注释index.ts#L72-L75说明一旦某大版本线整体进入 LTS 日期该线的所有版本包括早于官方首个 LTS 点发布的18.0.0官方首个 LTS 版本是18.12.0都算稳定这种粗粒度是有意为之。四、规则三LTS 代号Codename支持Renovate 能识别 Node.js LTS 代号并直接以代号作为版本号参与升级例如.nvmrc中写fermiumRenovate 会提出升级到gallium。这一能力在 官方 Node.js 文档页 中有说明在源码中通过normalizeValue与代号索引表实现index.ts#L12-L19function normalizeValue(value: string): string { const schedule findScheduleForCodename(value); if (schedule) { const major schedule.version.replace(v, ); return ^${major}; } return value; }schedule.ts#L12-L27 在模块加载时把日程表中的代号建成大写索引 MapERBONIUM键所以查询不区分大小写——测试里Fermium首字母大写也能命中。代号的升级链路如下全部有测试断言index.spec.ts#L15-L37、L94-L111场景输入结果说明代号升级代号currentValueerbium,newVersionv14.1.4fermium新大版本有代号时返回小写代号大小写归一currentValueFermium,newVersionv16.1.6gallium查询大小写不敏感同线无变化currentValuegallium,rangeStrategybump,newVersionv16.1.6gallium仍在 16 线内代号不变新大版本无代号currentValuegallium,newVersionv27.0.0^27.0.0v27 日程中codename为空回退为 npm 区间替换代号作区间matches(16.0.0, gallium)truegallium归一化为^16后做区间匹配代号选版本getSatisfyingVersion([16.0.0,14.0.0,16.9.9], gallium)16.9.9满足^16的最高版本除getNewValue外isValid、matches、getSatisfyingVersion、minSatisfyingVersion都会先走normalizeValue所以代号在合法性校验和区间匹配场景同样可用。isValid的测试用例index.spec.ts#L72-L83显示erbium与^10.0.0、10.x均合法bogus与10.9.8.7四段版本不合法27.0.0-alpha.1合法。五、实际使用哪些文件会用 node 版本化Renovate 管理 Node.js 运行时的典型落点见 docs/usage/node.mdpackage.json的engines字段package.json的volta字段.nvmrcnvm.node-versionnodenv.tool-versionsasdfmise 配置文件mise.toml、.mise.toml、.config/mise.toml.travis.yml的node_js字段。对应仓库中 nvm 管理器、nodenv 管理器、runtime-version 管理器 等抽取模块负责从这些文件提取currentValue随后统一交给 node 版本化 API 判定。官方文档明确只要使用node版本化方案Renovate 就会理解 LTS 代号并提供代号之间的升级如fermium→gallium。六、边界不能用于带后缀的 Docker 标签文档给出了一个明确的使用限制当 Node 镜像标签带-alpine等后缀时不能用node版本化替代docker版本化。原因是 npm/semver 版本化会把这类后缀视为预发布标记从而判定不稳定。仓库文档给出了对应的变通方案利用versionCompatibility正则把后缀从版本号中剥离再套用node版本化configuration-options.md#L5163-L5182{ packageRules: [ { matchDatasources: [docker], matchPackageNames: [node], versionCompatibility: ^(?version[^-])(?compatibility-.*)?$, versioning: node } ] }该特性对currentValue是具体版本号而非区间时最有用文档同时提示它可以与extractVersion组合但那是较罕见的边缘场景且extractVersion会先于versionCompatibility生效。七、小结一张表看懂 node 版本化的行为矩阵输入isValidisStable以当前日期在 LTS 日之后为前提说明16.0.0truev16 LTS 日2021-10-26之后为 true偶数线走lts字段11.0.0true恒为 false奇数线Node 26 及更早规则日程无lts字段27.0.0true2027-10-20maintenance之后为 trueNode 27 新日程走alpha分支27.0.0-alpha.1true恒为 falsesemver-stable判定预发布不稳定erbium/galliumtrue—区间形式代号经normalizeValue转为^major12.0.3afalsefalse非规范 semver实现上的三个文件构成完整证据链node 版本化入口 负责行为覆盖、schedule.ts 负责日程与代号查询、node-js-schedule.json 负责数据覆盖v0.8到v27。若需扩展新版本线的支持只需向该 JSON 补充日程条目——对 Node 27 的新形态写入alpha/maintenance字段即可被isStable正确消费。【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表