资料

https://docs.github.com/zh/actions

基本知识

触发事件

https://docs.github.com/zh/actions/using-workflows/events-that-trigger-workflows#schedule

工作流程触发器

工作流程触发器是导致工作流程运行的事件,工作流触发器使用 on 键定义。 这些事件可以是:

  • 工作流程存储库中发生的事件
  • 在 GitHub 之外发生并在 GitHub 上触发 repository_dispatch 事件的事件
  • 预定时间
  • 手动:workflow_dispatch

使用多个事件

如果指定多个事件,仅需发生其中一个事件就可触发工作流。 如果触发工作流的多个事件同时发生,将触发多个工作流运行。

1
on: [push, fork]

或者

1
2
3
4
5
6
7
8
on:
label:
types:
- created
push:
branches:
- main
page_build:

schedule

计划任务语法有五个字段,中间用空格分隔,每个字段代表一个时间单位

1
2
3
4
5
6
7
8
9
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of the month (1 - 31)
│ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
│ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
* * * * *

可在这五个字段中使用以下运算符:

运算符 描述 示例
* 任意值 15 * * * * 在每天的每 15 分钟运行
, 值列表分隔符 2,10 4,5 * * * 在每天第 4 和第 5 小时的第 2 和第 10 分钟运行
- 值的范围 0 4-6 * * * 在第 4、5、6 小时的第 0 分钟运行
/ 步骤值 20/15 * * * * 从第 20 分钟到第 59 分钟每隔 15 分钟运行(第 20、35 和 50 分钟)

案例

在每天 5:30 和 17:30 UTC 触发工作流程

1
2
3
4
5
6
on:
schedule:
- cron: '30 5,17 * * *'


猜测逗号表示并列,短横线表示持续

推送定时以及手动执行

1
2
3
4
5
6
7
on:
push:
branches:
- master
schedule:
- cron: '0 11,23 * * *'
workflow_dispatch:

案例

基于 Github Action 的 Python 邮件发送

参考:GitHub Actions 部署爬虫并定时发送邮件

  1. 为了方便,建立一个私密的仓库 some_action,主要是不想写变量
  2. 将仓库克隆到本地
  3. 在本地 some_action 文件夹内新建一些文件夹与文件,结果如下
1
2
3
4
5
6
7
8
9
10
11
12
some_action
│ README.md

├─.git

├─.github
│ └─workflows
│ 01_test_email.yml

└─01_test_sent_email
message.txt
test_sent_mail.py

以下是几个文件内容:

  • 以下是 01_test_email.yml 文件内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 整个工作流的名称
name: 'Test Sent Mail'

on:
# 触发事件:手动, push, 定时
workflow_dispatch:
push:
branches:
- master
# schedule:
# - cron: '30 0 * * *'

jobs:
bulid:
# 指定运行在哪台机器上
runs-on: ubuntu-20.04

# 该job的操作步骤
steps:

# 将本仓库的代码拉取一份到虚拟环境机器上
- name: Checkout
uses: actions/checkout@v3

# 配置安装 python 环境
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.6

# 配置Pythonmo依赖包
- name: Install requirements
run: pip install py-emails

# 运行 python 脚本文件
- name: Working
run: python "01_test_sent_email/test_sent_mail.py"

  • 以下是 test_sent_mail.py 文件内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from smtplib import SMTP_SSL
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
import datetime

def sent_email(receiver, mail_title, mail_content):
# 发件人信息
host_server = 'smtp.163.com' # 邮箱smtp服务器
sender = '[email protected]' # 发件人邮箱
pwd = '授权码' # 授权码

msg = MIMEMultipart()
msg["Subject"] = Header(mail_title,'utf-8')
msg["From"] = Header("Github Action",'utf-8')

# 发送邮件
msg['To'] = ";".join(receiver)
msg.attach(MIMEText(mail_content,'plain','utf-8'))
smtp = SMTP_SSL(host_server) # ssl登录
smtp.login(sender,pwd)
smtp.sendmail(sender,receiver,msg.as_string())
smtp.quit()

def get_beijing_time():
SHA_TZ = datetime.timezone(datetime.timedelta(hours=8),name='Asia/Shanghai',)
utc_now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
utc_time = utc_now.strftime('%Y%m%d-%H%M%S')
# print(utc_time)

beijing_now = utc_now.astimezone(SHA_TZ)
beijing_time = beijing_now.strftime('%Y%m%d-%H%M%S')
# print(beijing_time)

return [utc_time, beijing_time]


if __name__ == "__main__":
time_now = get_beijing_time()
message_file = "01_test_sent_email/message.txt"
with open(message_file,"w", encoding="utf-8") as fw:
str00 = "当前UTC时间:" + time_now[0]
str01 = "当前北京时间:" + time_now[1]
mail_content = fw.write(str00+"\n")
mail_content = fw.write(str01+"\n")

with open(message_file,"r", encoding="utf-8") as fr:
mail_content = fr.read()
receiver = ['[email protected]'] # 接收者列表
mail_title = 'Python自动发送的邮件' # 邮件标题
sent_email(receiver, mail_title, mail_content)
  • 不用建立message.txt文件
  1. git 提交到 Github 仓库,就会触发事件,进而收到邮件