GithubAction的Schedule运行不准时的解决办法

  • 前言
    • 在GitHubAPI中Schedule的定义
    • 定时执行的理论基础
      • 如何开启GitHubAction的`workflow_dispatch`触发器
    • 使用云函数提供cron调度服务
  • 总结

前言

最近做一个微型项目,因为需要爬取的部分数据在国内网络受限,所以用到了GithubActions功能。
设定的 scheduleUCT时间的08:00(也就是北京时间的16:00),但实际运行的时间为北京时间17:00 至 17:20 不等。
本篇文章将介绍此现象的原因,并提供一种简单解决方法。

在GitHubAPI中Schedule的定义

Scheduled events(预定事件)
The Schedule event allows you to trigger a workflow at a scheduled time.(该Schedule事件允许您在预定时间触发工作流。)

Note: The Schedule event can be delayed during periods of high loads of GitHub Actions workflow runs. High load times include the start of every hour. To decrease the chance of delay, schedule your workflow to run at a different time of the hour.

注意:Schedule在 GitHub 操作工作流运行的高负载期间,事件可能会延迟。高负载时间包括每小时开始。为了减少延迟的可能性,请安排您的工作流在不同的时间运行。

根据定义中描述的内容,我们可以得知Schedule是存在延迟的,实测延迟的时间为几十分钟,或者超过一个小时,甚至在某种极端情况下,将不会执行。
Schedule 设置的 cron 时刻,仅仅是工作流进行计划排队的时刻,而不是准确的运行时刻。
这在某些需求中将是一种致命的不精准。
接下来,我将提供一种解决方案,用于实现Github Action工作流的定时准时执行。

定时执行的理论基础

GitHub Actions 支持workflow_dispatch触发器(请参阅GitHub Docs 上的触发工作流的事件,因此如果您手动触发工作流,它将立刻执行。
这意味着您可以使用第三方 cron 调度服务,如 IFTTT、Google Cloud Scheduler、Jenkins、Cronhub 等,向 GithubDoc 发出请求以触发工作流。

如何开启GitHubAction的workflow_dispatch触发器

在工作流的 yml 文件定义的 on 中,提供workflow_dispatch触发器

#通过 workflow_dispatch 触发,cron任务部署在云函数
name: 你的工作流名称

on:
  workflow_dispatch:
    
jobs:
  start:
#以下省略

开启workflow_dispatch后,你的工作流中会出现运行工作流的按钮,手动点击Run workflow按钮,将会执行一次工作流:

现在可以进入下一步,使用 cron 调度触发工作流的手动执行。

使用云函数提供cron调度服务

在工具的选择上,人们总是会选择便捷且有效。如果恰好是免费的,那就大快人心。
我选择的 cron 调度是 腾讯云函数SCF.。简单的POST一个链接,不会达到收费标准。
我们打开云函数的创建界面:

  1. 选择自定义创建
  2. 函数名称为默认的helloworld-1623250991 ,可以自己输入名称。
  3. 地域使用任何地域即可,这里默认选择了广州
  4. 运行环境选择Python3.6
  5. 提交方法选择在线编辑。
  6. 执行方法使用默认值:index.main_handler
  7. 函数代码如下:
import requests
import json

def run():
        payload = json.dumps({"ref": "main"})
        header = {'Authorization': 'token GitHubToken',
                  "Accept": "application/vnd.github.v3+json"}
        response_decoded_json = requests.post(
            f'https://api.github/repos/Github账号/Github项目名/actions/workflows/GithubAction工作流名称或ID/dispatches',
            data=payload, headers=header)

# 云函数入口
def main_handler(event, context):
    return run()
  1. 函数代码中的 GitHubToken、Github账号、Github项目名、GithubAction工作流名称或ID 需要根据自己的账号及项目填写。具体的API调用规则可参考: GithubDoc.
  2. 具体填写如下图所示:
  3. 在高级配置中,将执行超过时间设置为合适的时间,这里我设置为最大值900秒:
  4. 触发器配置选择默认流量 - 定时触发 - 自定义触发周期,并填入合适的Cron表达式,这里的Cron当前以 UTC +8 中国标准时间 (China Standard Time)运行,即北京时间。我输入的

0 0 16 * * * *

表示了每天16点执行1次。

总结

以上就是今天要讲的内容,本文仅仅简单介绍了如果准确定时的执行GithubAction,希望可以帮助到大家。

更多推荐

GithubAction的Schedule运行不准时的解决办法