- CI/CD
- DevOps
【免费下载链接】woodpecker
Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.
Cron 定时任务是 Woodpecker CI/CD 中实现"周期化自动构建"的核心机制:它允许你按预定义的时间表(如每天、每 5 分钟)自动触发 pipeline,而无需任何代码提交。本文以 Woodpecker 官方文档 为主体,结合仓库源码(调度器、API、配置解析与 CLI 实现),完整讲解定时任务的配置流程、调度语法、事件过滤、权限要求与底层工作原理,读完即可在自己的仓库中落地一套可用的定时流水线。
前置要求:谁能配置定时任务
在开始之前,需要明确一个权限门槛:配置 Cron 任务要求你对该仓库至少拥有 push(推送)权限。这是因为定时任务本质上是一种"按时间触发"的特殊 pipeline 事件,涉及仓库级别的运行策略设置,普通只读协作者无法修改。
从仓库源码可以印证这一点——Cron 的创建与修改均通过仓库设置类 API 完成,服务端在处理请求时会通过session.Repo(c)校验当前会话用户对目标仓库的权限(见 server/api/cron.go 中的PostCron、PatchCron处理器),权限不足的请求会被会话中间件直接拦截。
第一步:在 pipeline 配置中添加事件过滤
创建定时任务的第一步是修改你的 pipeline 配置文件(如.woodpecker.yml),让相关步骤在cron事件下才会被执行。Woodpecker 的配置使用when约束(constraint)机制来声明步骤的运行条件。
官方文档给出的示例是:为一个原本只由其他事件触发的步骤,追加event: cron过滤条件:
steps: - name: sync_locales image: weblate_sync settings: url: example.com token: from_secret: weblate_token when: event: cron # 仅由定时任务触发时执行 cron: "name of the cron job" # 可选:只由指定名称的 cron job 触发这段配置的含义是:
when.event: cron:该步骤只在事件类型为cron时运行;when.cron: "name of the cron job":可选的进一步过滤——只有当触发这次 pipeline 的定时任务名称匹配时,步骤才会执行。如果不写这一行,那么所有cron 事件触发时该步骤都会运行。
事件过滤的底层实现
在源码层面,cron被定义为一种独立的 Webhook 事件类型。在 server/model/const.go 中可以看到:
EventCron WebhookEvent = "cron"它与其他事件(push、pull_request、tag、deployment等)一起被Validate()校验,是合法的 pipeline 事件之一。
事件与 cron 名称的双重匹配逻辑实现在 pipeline/frontend/yaml/constraint/constraint.go 中:当元数据中的事件为EventCron时,约束匹配会额外校验当前 pipeline 的 Cron 名称是否命中cron约束列表(对应源码第 192-193 行):
if m.Curr.Event == metadata.EventCron { match = match && c.Cron.Match(m.Curr.Cron) }也就是说,Woodpecker 在解析 pipeline 配置时,会把你写在when.cron里的名称列表与本次触发 pipeline 的 Cron 任务名做精确匹配,两者同时满足步骤才会进入执行队列。仓库中对应的测试用例(见 pipeline/frontend/yaml/constraint/constraint_test.go)也验证了"事件为 cron、名称匹配/不匹配"两种场景下的命中结果。
提示:如果你希望"定时任务只跑部分步骤",就用
when.cron按名称精确圈定;如果你希望"所有 cron 触发时都跑这些步骤",只写when.event: cron即可。
第二步:在仓库设置中创建定时任务
修改完 pipeline 配置并推送到仓库后,进入仓库设置页面(Repository Settings)中的 Cron 区域,点击创建新任务,填写以下字段:
- 名称(Name):定时任务的名字,必须是唯一的,且会作为
when.cron的匹配依据; - 分支(Branch):要针对哪个分支的代码执行,留空则默认使用仓库的默认分支(源码中
cron.Branch == ""时会回退到repo.Branch,见 server/cron/cron.go 的CreatePipeline); - 调度表达式(Schedule):cron 表达式,决定触发时间;
- 时区(Timezone):调度表达式解析所基于的时区,默认为
UTC(对应源码中PostCron处理器的默认值赋值逻辑); - 启用开关(Enabled):控制任务是否参与调度。
创建时服务端会做如下校验(见 server/model/cron.go 的Validate()):
- 名称与调度表达式均不能为空;
- 调度表达式必须能被标准 cron 解析器解析;
- 时区必须能被 Go 的
time.LoadLocation加载。
同时,如果指定了分支,服务端还会调用对应 Forge 的BranchHead接口确认该分支真实存在(见 server/api/cron.go 的PostCron)。
调度语法详解
Woodpecker 的调度表达式遵循github.com/gdgvda/cron库的 CRON 表达式格式,该格式同时支持标准的 5 字段 cron 表达式与若干扩展:
- 标准 5 字段格式:
分 时 日 月 星期,例如30 * * * *表示每小时的第 30 分钟执行一次; - 6 字段格式:可带秒(
秒 分 时 日 月 星期); - 描述符(Descriptors):
@daily、@hourly、@weekly、@monthly、@yearly等,例如@daily表示每天零点执行; - 间隔(Intervals):
@every <duration>,例如@every 5m表示每 5 分钟执行一次,这是定时测试、缓存刷新类任务最常用的写法。
官方文档给出的示例:
@every 5m # 每 5 分钟 @daily # 每天 30 * * * * # 每小时的第 30 分钟如果需要系统学习 cron 语法本身(而不只是 Woodpecker 的封装),可以借助在线的 crontab 生成器工具进行实验调试。
调度时间的计算与更新
每个定时任务在数据库中都会维护一个NextExec字段(下一次执行时间戳)。创建、修改调度表达式、切换时区或重新启用任务时,服务端都会调用CalcNewNext(实现在 server/cron/cron.go)重新计算下一次执行时间:
func CalcNewNext(schedule, tzLoc string, now time.Time) (time.Time, error) { zone, err := time.LoadLocation(tzLoc) ... c, err := parser.Parse(schedule) ... next := c.Next(now) ... }从实现可以看到,计算是"基于当前时刻推算下一个未来执行点"(c.Next(now)),如果表达式在指定时区下没有任何未来执行时间,会返回明确的错误——这也解释了为什么创建任务时必须保证表达式合法。
第三步:调度器如何触发 pipeline(运行原理)
创建好定时任务后,服务端的调度循环会负责按时触发。调度器实现在 server/cron/cron.go 的Run函数中,运行机制如下:
- 轮询检查:调度器每1 分钟(常量
checkTime = time.Minute)向数据库查询一次"已到执行时间"的定时任务,每次最多取 10 条(常量checkItems = 10); - 加锁防重:对每个到期的任务调用
CronGetLock获取分布式锁,并将新的NextExec写入数据库——如果锁已被其他实例获取,则本次跳过,从而保证在多副本部署时同一任务不会重复执行; - 创建 pipeline:调用
CreatePipeline,读取仓库与 Forge 信息,刷新用户令牌后获取指定分支的最新 commit(BranchHead),据此构造一个Event: EventCron的 pipeline(相关字段见 server/model/pipeline.go); - 入队执行:将 pipeline 交给
pipeline.Create创建并进入调度队列,随后按普通 pipeline 流程分发到 Agent 执行。
值得注意的细节:定时任务触发的 pipeline 会携带Cron字段(任务名称)以及AdditionalVariables(任务附加变量,见下文),这正是步骤级when.cron过滤和变量注入能够生效的数据来源。
手动触发与附加变量
除了等待调度器自动触发,你还可以在界面或通过 API立即手动运行某个定时任务(对应POST /repos/{repo_id}/cron/{cron},处理器为 server/api/cron.go 中的RunCron)。它会跳过调度等待,直接基于当前分支头部分支创建并执行一次 cron 事件 pipeline——适合"改了配置想立刻验证"的场景。
另外,Cron 模型还支持Variables map[string]string字段(见 server/model/cron.go),你可以为定时任务附加自定义变量,这些变量会作为AdditionalVariables注入到 pipeline 中,供步骤内的环境变量/设置使用,实现"同一个 pipeline 配置、不同定时参数"的复用。
使用 CLI 管理定时任务
除了 Web 界面,Woodpecker CLI 也提供了完整的 Cron 管理命令(源码位于 cli/repo/cron)。常用操作如下:
列出仓库的定时任务(需要仓库 ID 或完整名称作为参数):
woodpecker-cli cron ls <repo-id|repo-full-name>输出默认使用模板展示任务 ID、名称、分支、调度表达式与下一次执行时间(模板定义见 cli/repo/cron/cron_list.go)。
添加定时任务:
woodpecker-cli cron add <repo-id|repo-full-name> \ --name <cron-name> \ --schedule "@daily" \ --branch main \ --enabled其中--name与--schedule为必填参数,--branch指定执行分支,--enabled控制是否启用(默认启用,参数定义见 cli/repo/cron/cron_add.go)。
其他管理命令:cron update(修改名称、调度、分支、启用状态)、cron show(查看单个任务详情)、cron rm(删除任务)分别对应 cli/repo/cron/cron_update.go、cli/repo/cron/cron_show.go、cli/repo/cron/cron_rm.go。
说明:CLI 通过 woodpecker-go 客户端调用服务端 REST API(
/repos/{repo_id}/cron系列接口),因此以上命令与 Web 界面操作完全等价,适合脚本化运维。
常见使用场景与建议
基于上述机制,Cron 定时任务在 Woodpecker 中常见的落地场景包括:
- 定时数据同步/导入导出:如文档开头的
sync_locales示例,每天定时从上游同步翻译文案; - 定时测试与巡检:
@every 5m或@hourly对主干分支跑冒烟测试、健康检查; - 定时依赖升级/缓存刷新:利用
@daily、@weekly等描述符定期重建镜像或刷新缓存; - 多任务分流:通过
when.cron名称过滤,让不同定时任务各跑各自专属的步骤集合。
配置时建议注意以下几点:
- 分支留空时任务会跟随仓库默认分支的最新提交执行,若想固定某个发布分支请显式指定
branch; - 调度表达式建议先在本地/在线工具中验证正确性,创建时服务端虽会校验语法,但不会校验业务语义(如"凌晨跑"是否是你想要的时刻);
- 时区默认是 UTC,国内时间场景下记得显式设置时区(如
Asia/Shanghai),否则"每天执行"的实际时刻会与预期相差 8 小时; - 修改 pipeline 配置后,需要让
when.event: cron的步骤真正在配置解析阶段生效,配置推送后定时任务才会按新规则执行。
小结
本文围绕 Woodpecker 官方 Cron 文档 展开,完整覆盖了从"pipeline 配置事件过滤 → 仓库设置创建任务 → 调度器自动触发"的全链路:when.event: cron与when.cron双条件过滤决定了哪些步骤在定时触发时执行;@every 5m、@daily、30 * * * *等表达式由 gdgvda/cron 解析器驱动;调度器每分钟轮询、加锁防重并基于分支最新 commit 创建 cron 事件 pipeline。配合 Web 界面、REST API 与 CLI 三种管理入口,你可以在保持 push 权限的前提下,快速搭建稳定可靠的定时 CI 流水线。如需深入源码,可从 server/cron/cron.go(调度循环)、server/model/cron.go(数据模型与校验)、server/api/cron.go(REST API)与 pipeline/frontend/yaml/constraint/constraint.go(事件/名称过滤)四个文件继续阅读。
- CI/CD
- DevOps
【免费下载链接】woodpecker
Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.
相关推荐
Woodpecker CI/CD 定时任务(Cron)完整配置指南:从事件过滤到调度原理
Woodpecker CI/CD 定时任务(Cron)完整配置指南:从事件过滤到调度原理 Woodpecker 内置了与 CI 流水线深度集成的定时任务(Cro
CI/CDDevOpsFlashMLA深度解析:突破性大模型注意力计算优化技术实现原理
FlashMLA深度解析:突破性大模型注意力计算优化技术实现原理 FlashMLA是DeepSeek团队开发的高性能注意力计算内核库,为DeepSeek V3系
算子库大模型Enable Screenshot vs 同类工具:为什么它是最佳选择?
Enable Screenshot vs 同类工具:为什么它是最佳选择? 在数字生活中,我们经常遇到无法截图的场景——银行APP的支付界面、视频平台的版权内容、
移动开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考