ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Renovate 调度(Scheduling)配置指南:精确控制依赖更新的时间窗口

Renovate 调度(Scheduling)配置指南:精确控制依赖更新的时间窗口 Renovate 调度Scheduling配置指南精确控制依赖更新的时间窗口【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate本文围绕 Renovate 的调度机制展开讲解如何通过timezone、schedule、automergeSchedule等配置选项把依赖更新创建分支、自动合并限制在指定的时间窗口内并结合源码剖析调度判定的底层原理。读完本文你将掌握 cron 调度语法的正确写法、内置调度预设的使用方法以及如何为特定包或包组单独定制更新节奏从而有效降低 PR 噪音、避开业务高峰时段。Renovate 调度的定位与默认行为Renovate 何时运行由后端配置决定Renovate 本身是一个周期性运行的 CLI 程序什么时候跑由运行它的后端backend管理方决定而不是由仓库配置文件决定。例如管理员可以把 Renovate 配置为每小时运行一次、每天运行一次或仅在下班时间运行。每个仓库实际被处理的频率取决于多个因素后端配置的运行频率例如每小时、每天组织或账号下已 onboarding 的仓库总数每个仓库里待处理的工作量依赖数量、待更新分支数等。这里有一个关键限制如果后端配置导致每个仓库大约每 X 小时才被调度一次那么仓库级配置无法把间隔缩短到小于 X也无法强制 Renovate 在某个精确时刻处理特定仓库。仓库配置只能在Renovate 程序已经运行起来这个前提下决定这次运行是否允许为某些依赖创建/更新分支。默认时区UTC默认情况下Renovate 的所有调度均按UTC 时区解释。如果需要按本地时间调度可以通过timezone配置选项设置自己的时区详见下文设置时区一节。调度运行耗时依赖数与仓库数的影响Renovate 处理单个仓库的耗时随依赖数量、仓库数量的增长而增长。官方文档给出了如下量级参考待更新依赖数拥有这些依赖的仓库数运行耗时11非常快110快1100慢501慢100100非常慢这意味着在后端硬件上应预留足够的处理时间避免把调度窗口设置得过于局促例如每周日只跑一小时——后面仓库级调度配置一节会再次强调这一点。全局调度与具体调度从宏观上看Renovate 有两种调度方式作用完全不同调度方式作用说明全局调度Global决定 Renovate 程序何时运行通常由组织管理员控制对于 Mend Renovate App由 Mend 决定 Renovate 何时运行具体调度Specific当 Renovate 运行时检查调度以决定是否应为某个依赖查找更新通常写在renovate.json或类似的配置文件中因此一个依赖只有在两个条件同时成立时才会被更新Renovate 程序正在运行在你的硬件上或 Mend 的硬件上Renovate 配置文件中的调度允许 Renovate 查找该依赖的更新。管理更新频率Renovate 默认始终开启、发现更新立即开 PR这会让用户被源源不断的新 PR通知淹没。合理使用调度可以显著改善体验典型做法包括在仓库的 Renovate 配置文件中把检查更新的频率限制为每周一次为某个包或某个包组单独设置更新调度见下文为特定依赖设置调度。从源码看schedule配置项在 lib/config/options/index.ts 中的定义为限制在一天或一周中的这些时间段创建分支类型为字符串数组默认值为[at any time]同时支持allowString即可以写成单个字符串但官方建议使用数组语法。调度使用场景调度工具可以帮你实现以下目标在非办公时段运行 Renovate把持续集成资源释放给开发人员让某些包按固定周期更新而不是一有新版就立刻更新减少白天收到的 Renovate PR 通知。一句话概括调度解决的是什么时候允许 Renovate 动手的问题而不是要不要更新的问题。自定义调度自定义调度只需掌握两个核心配置项timezone时区与schedule调度。整体步骤如下告诉 Renovate 你想使用哪个timezone学习调度语法推荐 cron可选设置仓库级调度可选通过packageRules为某个包或包组设置自定义schedule。设置时区timezone默认情况下 Renovate 的调度按 UTC 解释。若希望按本地时间调度使用timezone配置项其值必须是有效的 IANA 时区名称IANA Time Zone Database 中的合法名称。例如{ timezone: America/Los_Angeles }配置项定义同样位于 lib/config/options/index.ts类型为字符串说明中明确要求符合 IANA 时区格式。从源码来看时区合法性校验在 lib/workers/repository/update/branch/schedule.ts 的hasValidTimezone函数中完成它用 Luxon 的DateTime.local().setZone(timezone).isValid判断时区是否有效无效时返回Invalid schedule: Unsupported timezone ...错误信息。测试用例 lib/workers/repository/update/branch/schedule.spec.ts 中同时覆盖了有效时区返回 true与无效时区返回 false两种场景。调度语法设置好时区后就可以定义一周中的哪些天或一天中的哪些小时允许 Renovate 执行变更操作。推荐的 cron 语法官方强烈推荐使用标准cron 语法。常用写法对照描述Cron 语法每个周末* * * * 0,6凌晨 5 点前* 0-4 * * *每个工作日的晚上 10 点到次日凌晨 5 点* 22-23,0-4 * * 1-5周五和周六* * * * 5,6每季度每 3 个月的 1 号* * 1 */3 *使用 cron 语法时有两点硬性约束分钟位置必须使用*通配符Renovate 不支持分钟级粒度因此30 0 * * *这类写法是无效的cron 表达式必须包含五个部分分、时、日、月、周。上述校验逻辑在源码中可以直接验证hasValidSchedule函数lib/workers/repository/update/branch/schedule.ts先用croner的CronPattern尝试解析如果解析成功且分钟位置包含非*的值或表达式不是以*开头就会报错Invalid schedule: ... doesnt have * as minutes。已废弃的 breejs/later 语法Renovate 还支持但已废弃基于breejs/later库的自然语言文本语法。官方计划在未来的大版本中移除breejs/later库前提是找到把所有合法调度迁移到 cron 语法的方案因此强烈建议所有用户改用 cron 调度新配置不要再使用 later 语法。breejs/later库负责解释every、before、after、on等关键词以及天time_beforetime_after等语义。合法但已废弃的 later 写法与 cron 写法对照合法但已废弃的 later 语法Cron 语法every weekend* * * * 0,6before 5:00am* 0-4 * * *after 10pm and before 5am every weekday* 22-23,0-4 * * 1-5on friday and saturday* * * * 5,6every 3 months on the first day of the month* * 1 */3 *再次强调Renovate 不支持精确到分钟或指定精确时刻的粒度粒度最小必须是一小时。源码层面later 语法的兼容路径同样在hasValidSchedule中当 cron 解析失败时会调用later.parse.text()解析文本并检查解析结果——若出错、或指定了分钟s.m、或既没有月份/星期/时刻限制都会判定为无效调度。另外isScheduledNowlib/workers/repository/update/branch/schedule.ts会先尝试 cron 解析成功则走cronMatches判断否则退回 later 语法的later.schedule(parsedSchedule).isValid()判断。两条路径并存正是当前cron 为主、later 兼容的实现写照。仓库级调度配置需要注意Renovate 进程何时运行通常由管理员控制例如通过系统cron工具。对于 Mend Renovate AppMend 维护者控制进程运行节奏通常是每小时一次。如果你自行掌控 Renovate 所运行的硬件官方建议在硬件上为 Renovate 预留足够的处理时间确保能处理完所有仓库避免每周日运行一小时这类过于局促的调度否则一定会遇到问题仓库可能处理不完更新被反复跳过。仓库级配置示例{ description: Schedule daily before 4 AM, schedule: [* 0-3 * * *] }{ description: Schedule during typical non-office hours on weekdays (i.e., 10 PM - 5 AM) and anytime on weekends, schedule: [* 0-4,22-23 * * 1-5, * * * * 0,6] }调度预设Schedule presetsRenovate 内置了常见调度场景的预设preset例如每周一次非办公时段等。在自建调度之前先检查内置预设是否满足需求——这样可以少写代码、少踩坑。这些预设只决定 Renovate 何时查找更新不影响任何具体依赖/包。内置预设定义在 lib/config/presets/internal/schedule.preset.ts 中可以直接在配置里通过extends: [schedule:xxx]引用例如预设名含义对应 cronschedule:daily每天凌晨 4 点前* 0-3 * * *schedule:earlyMondays每周一凌晨 4 点前* 0-3 * * 1schedule:weekly每周一次继承schedule:earlyMondays—schedule:monthly每月 1 号凌晨 4 点前* 0-3 1 * *schedule:quarterly每季度 1 号* * 1 */3 *schedule:yearly每年 1 月 1 日* * 1 */12 *schedule:nonOfficeHours工作日 22 点-次日 5 点 周末全天* 0-4,22-23 * * 1-5,* * * * 0,6schedule:officeHours工作日 8-17 点* 8-17 * * 1-5schedule:weekdays工作日* * * * 1-5schedule:weekends周末* * * * 0,6此外还有一组schedule:automerge*预设automergeDaily、automergeEarlyMondays、automergeMonthly、automergeNonOfficeHours、automergeOfficeHours、automergeQuarterly、automergeWeekly、automergeWeekends、automergeYearly它们作用于automergeSchedule而不是schedule用于限制自动合并的时间窗口。为特定依赖设置调度利用packageRules搭配schedule可以为特定包或包组定制更新节奏从而限制频繁更新依赖带来的噪音。以 AWS SDK 为例把它限制为每周日晚上更新{ packageRules: [ { description: Schedule AWS SDK updates on Sunday nights (9 PM - 12 AM), matchPackageNames: [aws-sdk/*], schedule: [* 21-23 * * 0] } ] }使用schedule属性时的关键要点始终使用数组语法[]即使只设置一个调度多个条目之间用逗号分隔如[cron for schedule 1, cron for schedule 2]数组中的多个条目按布尔 OR 逻辑解释——只要命中其中任意一个时间窗口就算在调度内。与调度配合使用的其他配置项automergeSchedule单独限制自动合并时间如果开启了automerge可以再用automergeSchedule单独限定自动合并分支/PR的时段与schedule创建分支的时段互不影响。该配置定义在 lib/config/options/index.ts默认同为[at any time]。从 lib/workers/repository/update/branch/automerge.ts 可以看到自动合并判定调用的是isScheduledNow(config, automergeSchedule)即复用同一套调度判定逻辑、只是传入不同的配置键。需要注意当platformAutomerge开启时Renovate 在 PR 创建时就把平台自动合并入队此时automergeSchedule无法生效如果必须严格限定自动合并时段需要把platformAutomerge设为false改用 Renovate 自身的自动合并。updateNotScheduled是否在调度外更新已有分支schedule默认只约束创建分支而updateNotScheduledlib/config/options/index.ts控制是否在非调度时段更新已有分支默认值为true。若希望调度被更严格地执行——即调度窗口外连已有分支的更新也不推送——需要显式设置{ updateNotScheduled: false }从 lib/workers/repository/update/branch/index.spec.ts 的测试用例如第 340、191 行附近的用例可以看到updateNotScheduled为false且isScheduledNow返回 false 时分支更新会被跳过反之则允许在调度外继续更新已有分支。调度判定流程与最佳实践底层判定流程isScheduledNow综合源码 lib/workers/repository/update/branch/schedule.tsRenovate 判断当前是否在调度内的完整流程是读取schedule或automergeSchedule配置若为空、at any time则直接放行校验调度合法性hasValidSchedule非法时记录 warning 并放行fail-open 策略若配置了timezone校验其合法性并用它把当前时间now转换到时区无效时同样放行逐个尝试 cron 解析成功则用croner的CrondomAndDow: true模式计算上一个整分钟之后的下一次运行时刻与当前分钟比对cronMatches失败则回退到breejs/later的later.schedule().isValid()只要命中任意一个调度条目OR 逻辑即认为在调度内。值得注意的实现细节cron 匹配把当前时刻与下一次 cron 触发时刻按分钟对齐比较nextMinute.toMillis() nowMinute.toMillis()本质上以小时为最小粒度判断当前是否处于允许窗口内与不支持分钟粒度的约束一致。时间窗口与边界条件建议调度窗口建议至少留 3-4 小时如果调度过于严苛而 Renovate 恰好在窗口外运行的概率又高依赖更新会被反复跳过日与月同时受限时是 AND 逻辑schedule中如果同时限制日day of month与星期day of weekRenovate 只有在两者同时命中时才运行。例如* * 1-7 * 4表示仅每月第一个星期四运行已有旧式 later 语法的处理Renovate 的配置迁移机制见 lib/config/migrations/custom/schedule-migration.ts会自动把after 10pm and before 5am这类跨天写法拆成两条调度、把on the last day of the month规范化为on the first day of the month、把every weekday等文本统一格式逐步引导配置向 cron 迁移区分创建分支与更新分支默认情况下schedule只约束新分支的创建已有分支在调度外仍可能被更新需要严格模式时记得配置updateNotScheduledfalse。小结Renovate 的调度体系可以概括为两层控制后端决定程序何时运行仓库配置决定程序运行时是否允许动某个依赖。仓库侧的核心工具是timezoneschedule推荐统一使用五段式 cron 语法分钟位固定为*善用内置的schedule:*预设减少重复配置再配合automergeSchedule与updateNotScheduled精确控制自动合并与分支更新的边界。把握住最小粒度一小时、数组 OR 逻辑、日与月 AND 逻辑、窗口至少 3-4 小时这几个要点就能为团队设计出既安静又不漏更新的依赖自动化策略。【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表