news 2026/9/13 11:03:52

Renovate 的 endoflife-date 数据源:基于软件生命周期自动化更新版本

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Renovate 的 endoflife-date 数据源:基于软件生命周期自动化更新版本

Renovate 的 endoflife-date 数据源:基于软件生命周期自动化更新版本

【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate

本篇技术指南讲解 Renovate 中endoflife-date数据源(lib/modules/datasource/endoflife-date/)的完整用法:它借助 endoflife.date 提供的软件版本与生命周期终止(End-of-Life)信息,为那些没有传统包仓库的软件(如 Amazon EKS、操作系统发行版等)提供版本追踪能力。读完本文,你将掌握如何用自定义正则 Manager 把任意.tfvars等配置文件中的版本字段接入 Renovate 更新流程,并理解该数据源的底层请求、数据解析与废弃标记机制。

一、数据源是什么:用 EOL 信息驱动的版本追踪

endoflife-date数据源的核心思路很简单:很多软件并不发布在 npm、Maven 或 Docker Hub 这类传统注册表里,它们的版本演进与支持周期信息反而被整理在 endoflife.date 这个公开网站上。Renovate 通过该网站的公开 API 读取某个软件(如amazon-eks)的版本列表,从而把版本更新自动化能力延伸到这些"没有包管理器"的场景。

在仓库中,该数据源的标识与默认注册表地址定义在 lib/modules/datasource/endoflife-date/common.ts:

export const registryUrl = 'https://endoflife.date/api'; export const datasource = 'endoflife-date';

这意味着在配置中只需写datasource=endoflife-date,Renovate 就会向该 API 发起查询。对应的数据源实现类是EndoflifeDateDatasource(lib/modules/datasource/endoflife-date/index.ts),它继承了统一的Datasource抽象基类(lib/modules/datasource/datasource.ts),对外暴露标准的getReleases()接口。

二、底层工作原理:请求、解析与缓存

1. 请求路径构造

当 Renovate 需要查询某个软件时,会调用_getReleases(),通过joinUrlParts拼接出最终的 API 路径:

const url = joinUrlParts(registryUrl, `${packageName}.json`);

也就是说,depName=amazon-eks最终会被解析为对https://endoflife.date/api/amazon-eks.json的 GET 请求。因此,depName 必须与 endoflife.date 站内登记的软件名称(package 名称)完全一致。如果你不确定某个软件在 endoflife.date 上的确切名称,可以使用该网站 API 文档中提供的 "All packages"(全部软件包)端点来查询可用清单。

2. 响应数据解析:Zod Schema 与废弃标记

API 返回的是 JSON 数组,每一项代表一个版本周期(cycle)。数据源用 Zod schema(lib/modules/datasource/endoflife-date/schema.ts)进行校验和转换:

const ExpireableField = z.union([ UtcDate.transform((x) => { const now = DateTime.now().toUTC(); return x <= now; // 日期型 EOL:若已过期则视为废弃 }), z.boolean(), // 布尔型 EOL / discontinued ]); export const EndoflifeDateVersions = z .object({ cycle: z.string(), latest: z.optional(z.string()), releaseDate: MaybeTimestamp, eol: z.optional(ExpireableField), discontinued: z.optional(ExpireableField), }) .transform(({ cycle, latest, releaseDate, eol, discontinued }): Release => { const version = latest ?? cycle; const isDeprecated = eol === true || discontinued === true; return { version, releaseTimestamp, isDeprecated }; }) .array();

从这段源码可以提炼出几个关键事实:

  • 版本号取值:优先取latest字段;若不存在,则回退到cycle(版本周期名)。例如 Amazon EKS 数据中cycle1.26latest1.26-eks-1,最终版本号取1.26-eks-1
  • 发布时间的来源releaseDate字段被映射为releaseTimestamp。数据源在类声明中标注了releaseTimestampSupport = true,并在releaseTimestampNote中说明:"发布时间的确定来自结果中的releaseDate字段"。这意味着 Renovate 可以基于该时间戳应用"最小发布时间"(minimum release age)等策略。
  • 废弃判断eoldiscontinued字段既可能是布尔值,也可能是日期字符串。日期会被与当前 UTC 时间比较:若 EOL 日期已过,该版本被视为已废弃(deprecated)。这一逻辑在测试中得到了充分验证(详见下文第五节)。

3. 默认行为与缓存

EndoflifeDateDatasource还声明了这些默认行为(lib/modules/datasource/endoflife-date/index.ts):

属性含义
defaultRegistryUrls[https://endoflife.date/api]默认注册表地址
defaultVersioningloose默认使用宽松版本控制
cachingtrue结果可被包缓存复用
releaseTimestampSupporttrue支持基于发布日期的时间策略

getReleases()外层还套了一层withCache包缓存,缓存键为registryUrl:packageName的组合;这保证了同一仓库中多次查询同一个软件时不会重复请求 API。而错误处理走的是基类handleGenericErrors(lib/modules/datasource/datasource.ts):遇到 429 限流或 5xx 服务端错误会包装成ExternalHostError抛出,404 与空结果则直接返回null(表示查无此包)。

三、版本控制:默认 loose,推荐 semver

原文档明确提醒:该数据源默认使用loose版本控制loose是 Renovate 中最宽松的版本方案,几乎任何字符串形式都能被解析,适合像1.26-eks-13+这类非标准版本号。

但宽松也意味着排序和比较规则简单粗暴。因此官方文档建议:只要可能,就改用更严格的版本方案(如semver,以获得更准确的升级判断。你可以在renovate.jsonpackageRules中用matchVersioning(或在自定义 Manager 的versioningTemplate中)为特定包指定更严格的版本控制。仓库中endoflife-date的测试(lib/modules/datasource/endoflife-date/index.spec.ts)使用的也是默认的 loose 解析。

四、实战配置:用自定义 Manager 更新 Terraform.tfvars中的版本

原文档给出了一个完整的端到端示例,这是本数据源最典型的应用场景:使用 Amazon EKS 时,让 Renovate 自动更新 Terraform.tfvars文件里的 Kubernetes 版本号

1. 在.tfvars文件中标记要更新的变量

假设你的仓库里有这样一个.tfvars文件,其中kubernetes_version定义了 EKS 使用的 Kubernetes 版本:

# renovate: datasource=endoflife-date depName=amazon-eks versioning=loose kubernetes_version = "1.26"

注意紧挨着变量的这行注释:# renovate: datasource=endoflife-date depName=amazon-eks versioning=loose。它相当于给 Renovate 下达指令——用endoflife-date数据源、查询amazon-eks这个软件、按loose版本方案来更新下一行的版本值。注释中的depName必须与 endoflife.date 上登记的软件名称一致。

2. 在renovate.json中注册自定义 Manager

接下来在renovate.json中配置一个customType: "regex"的自定义 Manager,让 Renovate 去扫描并解析所有.tfvars文件:

{ "customManagers": [ { "customType": "regex", "description": "Update Kubernetes version for Amazon EKS in tfvars files", "managerFilePatterns": ["/.+\\.tfvars$/"], "matchStrings": [ "#\\s*renovate:\\s*datasource=(?<datasource>.*?) depName=(?<depName>.*?)( versioning=(?<versioning>.*?))?\\s.*?_version\\s*=\\s*\"(?<currentValue>.*)\"" ], "versioningTemplate": "{{#if versioning}}{{{versioning}}}{{/if}}" } ], "packageRules": [ { "matchDatasources": ["endoflife-date"], "matchPackageNames": ["amazon-eks"], "extractVersion": "^(?<version>.*)-eks.+$" } ] }

这份配置各部分的职责如下:

  • managerFilePatterns:限定只处理仓库中匹配/.+\.tfvars$/的文件。
  • matchStrings:一个正则表达式,负责从注释行与赋值行中捕获四个命名组:datasourcedepNameversioningcurrentValue。其中versioning组是可选的(( ... )?),体现"注释里可以不写versioning"的容错设计。
  • versioningTemplate:使用 Handlebars 模板语法,把注释中捕获到的versioning值动态注入;若注释未写versioning,则回退到数据源默认的loose
  • packageRules.extractVersion:对amazon-eks的版本号做归一化,详见下文。

3. 执行效果

启用以上配置后,Renovate 会:

  1. 解析仓库中所有*.tfvars文件;
  2. 定位以# renovate: datasource=endoflife-date depName=dependency-name versioning=versioning注释开头、且变量名以_version结尾的赋值行;
  3. 调用 endoflife.date 数据源查询新版本;
  4. 有新版本时,自动将currentValue更新为最新版本并提交 PR。

针对amazon-ekspackageRule还会额外做一步清洗:通过extractVersion正则^(?<version>.*)-eks.+$把类似1.26-eks-1的完整版本号中-eks-${eks-release-version}后缀剥掉,只保留 Kubernetes 主次版本号(如1.26),从而让升级判断聚焦在 Kubernetes 主版本层面。

五、extractVersion 的源码级解释

extractVersion是 Renovate 在获取版本列表后、进入版本比较前执行的一层预处理。在 lib/modules/datasource/common.ts 的applyExtractVersion中可以看到它的实现:

const extractVersionRegEx = regEx(extractVersion); releaseResult.releases = filterMap(releaseResult.releases, (release) => { const version = extractVersionRegEx.exec(release.version)?.groups?.version; if (!version) { return null; // 无法匹配的版本会被剔除 } release.versionOrig = release.version; // 原始版本号被保留到 versionOrig release.version = version; return release; });

也就是说:extractVersion通过具名捕获组(?<version>...)从 API 返回的版本号中提取出"真正参与比较的版本";原版本号保存在versionOrig中不会丢失。这一处理发生在 lib/modules/datasource/index.ts 的applyDatasourceFilters调用链中(先applyExtractVersion,再做过滤、排序去重与约束筛选),因此如果某个版本的原始字符串无法被extractVersion匹配,它会被直接过滤掉——这提醒我们在编写该正则时要覆盖数据源可能返回的所有版本形态。

六、测试用例验证:数据解析与异常处理的可靠保证

仓库为该数据源提供了完整的单元测试(lib/modules/datasource/endoflife-date/index.spec.ts),可以作为理解其行为最直观的参考:

  • 真实数据处理:使用eks.json夹具(lib/modules/datasource/endoflife-date/fixtures/eks.json)模拟 API 响应,断言amazon-eks返回 9 个版本,其中1.181.21等已过 EOL 的版本isDeprecated: true1.22及之后的版本为false,且每个版本都带上了releaseTimestamp
  • 布尔型废弃标记:使用apache-cassandra.json夹具,验证discontinued: true字段(布尔型)会被正确识别为已废弃。
  • 日期型废弃标记:使用fairphone.json夹具,验证eol为日期字符串时,测试中把系统时间固定为2023-06-03(通过 luxon 的Settings.now注入),早于该时间的eol日期被判定为废弃。
  • 边界与异常registryUrl为空时返回null;API 返回 404 时返回null;返回空数组时返回null;返回 5xx 时抛出EXTERNAL_HOST_ERROR

这些测试同时覆盖了 schema 解析、废弃判断、错误处理三个维度,说明该数据源在"数据不完美"(缺字段、废弃字段类型不一)的情况下也能稳定工作。

七、使用建议与注意事项

  1. 先确认 package 名称depName必须是 endoflife.date 已登记的软件名,建议通过其 API 文档中的 "All packages" 端点核对,避免因名称不符导致 404(404 时数据源返回null,Renovate 会静默跳过该依赖)。
  2. 版本方案按需收紧:默认loose能覆盖大多数情况,但如果你的软件版本符合 SemVer 规范,优先显式指定versioning=semver以获得更精确的升级判断。
  3. extractVersion要写全:正则需覆盖该软件 API 可能返回的所有版本形态,否则无法匹配的版本会被过滤,可能导致漏更新。
  4. 该数据源适合的软件:EKS、Kubernetes 发行版、操作系统版本、语言运行时等没有传统包仓库、但有明确版本与支持周期的软件。它不适用于已有专门 datasource 的生态(如 npm 包应使用 npm 数据源)。

八、相关文件索引

  • 数据源实现:lib/modules/datasource/endoflife-date/index.ts
  • 常量定义:lib/modules/datasource/endoflife-date/common.ts
  • 响应 Schema:lib/modules/datasource/endoflife-date/schema.ts
  • 单元测试:lib/modules/datasource/endoflife-date/index.spec.ts
  • 测试夹具:lib/modules/datasource/endoflife-date/fixtures/(eks.jsonapache-cassandra.jsonfairphone.json
  • 数据源基类:lib/modules/datasource/datasource.ts
  • 版本获取与过滤管线:lib/modules/datasource/index.ts、lib/modules/datasource/common.ts

【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 11:00:46

Three.js GLTFExporter 实战指南:从导出失败到生产级 glTF 资产生成

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 11:00:43

配电网韧性提升:应急移动电源动态调度与Matlab实现

1. 项目背景与核心价值配电网作为电力系统的"最后一公里"&#xff0c;其可靠性直接关系到民生用电质量。近年来频发的极端天气事件&#xff08;如台风、冰灾&#xff09;暴露出传统配电网在灾害应对中的脆弱性。2021年某沿海城市台风期间&#xff0c;仅因一棵倒伏树木…

作者头像 李华
网站建设 2026/9/13 11:00:24

ESLint no-unused-labels 规则详解:自动清除重构残留的未使用标签

ESLint no-unused-labels 规则详解&#xff1a;自动清除重构残留的未使用标签 【免费下载链接】eslint Find and fix problems in your JavaScript code. 项目地址: https://gitcode.com/GitHub_Trending/es/eslint 本篇指南围绕 ESLint 内置规则 no-unused-labels 展开…

作者头像 李华
网站建设 2026/9/13 10:56:48

AI学术写作工具:书匠策AI如何提升论文效率与质量

1. 项目概述&#xff1a;当学术写作遇上AI生产力革命 去年帮导师审阅本科课程论文时&#xff0c;一个现象让我震惊&#xff1a;超过60%的论文存在结构性硬伤&#xff0c;比如文献综述变成资料堆砌、论证逻辑链条断裂、格式规范全军覆没。这促使我开始系统研究AI写作辅助工具&am…

作者头像 李华
网站建设 2026/9/13 10:56:08

ClaudeCode Insights:智能代码分析与优化实践

1. ClaudeCode Insights命令概述ClaudeCode作为新一代智能编程助手&#xff0c;其Insights命令功能彻底改变了开发者与代码交互的方式。这个功能的核心在于通过静态代码分析和动态行为预测&#xff0c;为开发者提供超越传统IDE的深度代码理解能力。不同于简单的语法高亮或错误检…

作者头像 李华