Renovate bun-version Manager:自动维护.bun-version文件,锁定 Bun 运行时版本
【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate
导读
本文围绕 Renovate 仓库中bun-version管理器(Manager)展开,讲解它是如何"只做一件事"——持续保持仓库根目录下.bun-version文件与 Bun 最新发布版本同步。读完本文,你将掌握.bun-version文件的作用、Renovate 如何匹配与解析该文件、版本更新采用何种版本策略(npm/semver)与数据源(npm),以及如何通过源码与测试验证其行为,并据此在自托管或 GitHub App 场景下正确配置和使用该管理器。
一、背景:.bun-version是什么
Bun 是一款面向 JavaScript 生态的现代运行时与工具链(包管理器、打包器、测试运行器一体),常被用作 npm、pnpm、Yarn 的替代方案。与 Node.js 生态中通过.nvmrc锁定 Node 版本、pyenv 生态中通过.python-version锁定 Python 版本类似,Bun 官方支持在项目根目录放置一个.bun-version文件,用于固定项目所需的 Bun 运行时版本。
Renovate 仓库中bun-version管理器的定位非常纯粹,其官方描述只有一句话:
Simply keeps the
.bun-versionfile updated.
即:只负责把.bun-version文件里声明的 Bun 版本更新到最新,不涉及package.json、锁文件或任何其他依赖的更新(那是bun管理器的职责,详见 bun 管理器说明)。这种"单一职责"的设计与nvm(维护.nvmrc)、nodenv(维护.node-version)、pyenv(维护.python-version)、terraform-version(维护.terraform-version)等管理器一脉相承。
二、管理器如何被注册与发现
Renovate 采用"管理器即模块"的架构。bun-version在 lib/modules/manager/api.ts 中被导入并注册:
import * as bunVersion from './bun-version/index.ts'; // ... api.set('bun-version', bunVersion);注册后,配置中即可通过"bun-version": {...}来引用、覆盖该管理器的行为。同时,lib/modules/manager/bun-version/index.ts声明其归属于 JavaScript 生态类别:
export const categories: Category[] = ['js'];分类信息会被 tools/docs/manager.ts 中的文档生成器用于聚合"按语言/生态分类的管理器清单",因此在官方文档的 JavaScript(js)分类下可以看到bun-version。
三、核心实现解析:extractPackageFile
管理器全部核心逻辑都集中在 lib/modules/manager/bun-version/index.ts 的extractPackageFile函数中,完整源码如下:
export function extractPackageFile(content: string): PackageFileContent | null { if (!content) { return null; } if (content.split('\n').length > 2) { return null; } const dep: PackageDependency = { depName: 'Bun', packageName: 'bun', currentValue: content.trim(), datasource: NpmDatasource.id, }; if (!isValid(content.trim())) { dep.skipReason = 'invalid-version'; } return { deps: [dep] }; }其解析规则可以拆解为四点:
- 空文件不处理:
content为空时直接返回null,表示该文件无法构成有效依赖声明。 - 只接受单行版本号:文件按换行切分后若超过 2 行(即包含两个换行符,说明至少有 3 行内容)则整体跳过。这与
.bun-version约定俗成的"一行一个版本号"格式相符——多行内容被视为异常输入,不冒险猜测。 - 提取依赖信息:无论文件内容为何,都会生成一条
PackageDependency:depName: 'Bun'—— 依赖展示名;packageName: 'bun'—— 对应 npm 包名;currentValue: content.trim()—— 文件内容去除首尾空白后的版本字符串;datasource: 'npm'—— 版本来源为 npm registry。
- 版本合法性校验:若修剪后的内容不是合法的 npm 版本/范围(
isValid来自 lib/modules/versioning/npm/index.ts,底层使用semver.validRange),则该依赖被标记为skipReason: 'invalid-version',Renovate 不会为它创建更新 PR,但依然会把它作为"已知但跳过"的依赖暴露给上游流程。
测试用例印证行为边界
lib/modules/manager/bun-version/index.spec.ts 用一组用例把上述规则钉死:
| 输入 | 结果 | 说明 |
|---|---|---|
'1.1.15\n' | 提取currentValue: '1.1.15' | 正常单行版本,带结尾换行 |
'' | null | 空文件跳过 |
'1.1.15' | 正常提取 | 无结尾换行也可解析 |
'1.1.15\n1.1.16\n' | null | 多行内容整体跳过 |
'notaversion\n' | skipReason: 'invalid-version' | 非法版本被标记跳过 |
'1.0\n' | 提取currentValue: '1.0' | 兼容不完整语义化版本(如1.0这种省略 patch 的写法) |
值得注意的是最后一个用例:1.0并非严格的三段式x.y.z版本,但由于 npm 版本化层对 range 的宽容处理(validRange),它仍被视为合法输入进入更新流程。
四、默认配置:文件匹配与版本策略
管理器的默认配置(defaultConfig)同样是理解其行为的关键:
export const defaultConfig = { managerFilePatterns: ['/(^|/)\\.bun-version$/'], versioning: id, // id = 'npm' };4.1 文件匹配规则
- 正则
/(^|/)\.bun-version$/表示:匹配任意目录层级下的、以.bun-version结尾的隐藏文件,包括仓库根目录的.bun-version(^锚定)以及子目录中的.bun-version(/锚定)。 - 依据 docs/usage/modules/manager/index.md 的说明,
managerFilePatterns是"可扩展(additive)"的:如果你希望额外匹配其他文件名(例如自定义的bun-version.txt),可以在配置中追加而不必担心覆盖默认正则:
{ "bun-version": { "managerFilePatterns": ["/^bun-version\\.txt$/"] } }- 若某个被默认模式命中的文件你并不想让 Renovate 处理,则应通过全局的
ignorePaths排除,而不是修改匹配模式。
4.2 版本策略:npm / SemVer
versioning: 'npm'意味着.bun-version中的版本号按SemVer 语义化版本(及 npm 的 range 语法)解释。该版本化实现位于 lib/modules/versioning/npm/index.ts,它直接复用semver库,并额外通过normalizeLegacyXRanges兼容1.x、1.0.x这类旧式写法;其公开 API 覆盖equals、getMajor、isGreaterThan、isValid、matches、subset等完整比较与范围运算能力。
因此,.bun-version中的1.1.15、1.2、1.x等写法都能被正确解析与排序,Renovate 会按 SemVer 规则挑选合适的升级目标(major/minor/patch 拆分、PR 分组等均沿用 npm 版本化策略)。
五、数据源:从 npm 获取 Bun 版本
管理器声明支持的数据源为:
export const supportedDatasources = [NpmDatasource.id];即使用 npm 数据源(lib/modules/datasource/npm)来查询bun包的已发布版本。这与 Bun 的发布方式一致——Bun 的每个版本都会同步发布到 npm(包名bun),因此通过 npm registry 即可获得完整、可靠的版本列表。Renovate 会对比.bun-version中的currentValue与 npm 上的最新版本,并依据rangeStrategy(默认与 npm 管理器的全局策略一致)决定如何生成更新 PR。
六、文档如何生成:readme.md 的归宿
如果你在官方站点看到bun-version管理器的文档,它实际上由 tools/docs/manager.ts 自动拼装:前半部分是通用模板(Categories、File Matching、Supported datasources、Default config 等,均从defaultConfig等代码导出数据动态生成),后半部分"Additional Information"追加的正是 lib/modules/manager/bun-version/readme.md 的原文。这也是仓库要求每个管理器都维护一个精简 readme.md 的原因——它是最终用户文档"附加信息"章节的原料。
七、使用与配置建议
7.1 前置条件
- 仓库中存在
.bun-version文件(内容为一行 Bun 版本号); - 该文件未被
ignorePaths或预设(如config:recommended的示例目录忽略规则)排除; - 自托管环境可正常访问 npm registry(或已配置对应的 registry 镜像/hostRules)。
7.2 开箱即用
bun-version管理器默认即启用,无需任何额外配置。当.bun-version中的版本落后于 npm 上bun包的最新版本时,Renovate 会按照既有节奏(调度、分组、语义化提交等全局配置)自动创建更新 PR。
7.3 常见定制
{ "bun-version": { "ignoreDeps": ["Bun"], "rangeStrategy": "bump" } }ignoreDeps:临时忽略该依赖的更新;rangeStrategy:由于.bun-version本质上记录的是一个固定(pin)版本,一般无需修改,但若文件内写的是范围(如1.x),可结合 npm 版本化层支持的bump/widen/replace策略(见 lib/modules/versioning/npm/index.ts)调整升级方式;- 若因 CI 或运行时原因需要 Renovate 忽略某个具体版本(如某个损坏的 Bun 版本),可配合
allowedVersions或ignoreVersions使用。
八、与相关管理器的关系
bun管理器(lib/modules/manager/bun):负责package.json依赖与锁文件的更新,与bun-version互补;当package.json同时被bun与npm管理器命中时,仓库会优先按 bun 的解析结果处理(除非存在 npm/pnpm/Yarn 锁文件)。- 同类"版本钉住文件"管理器:
nvm(.nvmrc)、nodenv(.node-version)、pyenv(.python-version)、terraform-version(.terraform-version)遵循完全相同的设计模式——都是"单一文件、单行版本、单一数据源"的轻量管理器,可作为参考对比阅读。
结语
bun-version是 Renovate 中典型的"小而美"管理器:一个正则匹配.bun-version文件、一个函数完成解析与校验、npm 数据源 + npm 版本化策略完成版本比对。理解它的源码与测试,你不仅能精确掌握.bun-version文件的更新行为边界(单行、合法版本、可扩展文件模式),还能举一反三地看懂 Renovate 整个 manager 体系的组织方式与文档生成链路。
【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考