最近对个人调度任务做了一次较大调整:核心从依赖 GitHub Actions 内置 schedule 的被动排队,改成由外部定时任务主动触发 workflow。要解决的主要是调度延迟。我有一批天级任务需要相对准时,例如拉取前一日数据、汇总昨天的工作;但 GitHub Actions 的 cron 并不可控,经常晚数小时,极端时当天该跑的 run 都没出现。GitHub 文档也写了,高负载时内置 schedule 会拖队,整点尤其挤,严重一点排队里的 job 还可能被丢掉。这和在公司里做数据调度是同一类烦恼。
好在目前没有严格意义上的任务依赖;真有前后关系时,会拆成串联节点。更多还是用错开执行时间这类小技巧顶一顶。
外部主动触发
除了 workflow 里自带的 schedule,还可以用第三方 cron 从仓库外 dispatch,相对更可控。调研阶段我主要用 Google Antigravity 查资料;古法编程也行,直接在 Google 里搜,AI 概览往往也会点到 workflow_dispatch、repository dispatch 这类做法。大意就是:定时器不在 GitHub 队列里干等,而是由外部按点去触发。落地代码在 kuhung/action-cron-hub,个人用的小 hub,负责外部定时和集中补触,细节就不展开了。线上各 workflow 原先自带的 schedule 我也下掉了,定时只走外部这一路,免得 GitHub 内外各响一次、同一天跑两遍。
用 Pi CLI 批量改配置
落地时我用 Pi 的 CLI 客户端来改仓库。授权充分后,它可以读项目下的文件。我把多个相关仓库收进一个大文件路径下,在根目录让它扫描各子目录里已有的 GitHub workflow 配置,批量改 trigger,省得一个个仓库翻 yaml。这种多任务批量改,和之前统一改 GA4 实践指南:从配置到 AI 工作流 里那套埋点一样,改一处公共抽象、下面一起生效。(再次心痛:上次用 Claude 改到一半,账号被封了。)
整体改动不大,前后折腾大约两个半小时。收尾时在 Antigravity 里用 Gemini 3.8 Flash 做了一个简单的触发页,浏览器里可以手工点跑。哪天某个任务没按预期触发、或 run 失败了,不必等下一轮 schedule,线上补一手。这和在公司里补某一天的数据有点像:同一套 workflow,多打一次信号而已,前提是参数里写清「算哪一天的数」,同一天重复跑别写成两份。
原型阶段的边界
目前仍是基本原型:触发路径从「等 GitHub 排队」变成了「我们从外部打信号」。公司里管数据任务,通常会分开看三件事:有没有按时触发、任务有没有跑完、跑完的结果能不能用。我现在主要解决了第一件,后面两件还靠邮件和人工扫一眼。触发之后跑没跑成、要不要重试、失败是上游、数据还是 API 问题,还没有系统化监控,牵涉的外部面太多。失败告警暂时还是邮件。
若放在组织里的生产体系,后面多半还会补告警、重试和可回滚,保证时间线能拉起、跑完、出问题能收住。个人栈先做到「准时触发 + 能手工补触 + 天级任务写清算哪天的数」就够用。run 显示成功,也不等于汇总邮件里的数已经对劲,这点和上班时既要准时开跑、也要核对产出是一个道理。
为什么值得改
这次不算过度设计,是积压很久的瓶颈:线上数据采集任务经常大面积延迟,和 GitHub Actions 免费用户变多、平台自身稳定性都有关系。对我影响最大的是周报链路:希望每周六、周一早上有相对明确的行动指导,但日常任务本来期望早上 8 点左右就绪,常常拖到中午才出来,「指导」就弱化了,才动手改触发方式。
大面积改 workflow 时,适合抽公共部分做复用,有点像中台,但不鼓励过度抽象、过早抽象。
参考资料
- Manually running a workflow -
workflow_dispatch与手工触发 - Events that trigger workflows - schedule - 内置 cron 的行为与限制
- Troubleshooting workflows - 计划任务延迟与 cron 排查
- Google Antigravity - 调研阶段使用的 Google 实验性开发环境