什么是GitHub action
官方定义:使用GitHub Actions在存储库中自动化,自定义和执行软件开发工作流程。您可以发现,创建和共享操作以执行所需的任何作业(包括CI / CD),并在完全定制的工作流程中组合操作。
action基本使用
进入自己的GitHub 公开仓库,点击ACTION按钮
选择自己来写工作流文件,不从GitHub已经提供的工作流模板中做选择。因为是第一次写,所以自己先写可以更直观的了解一些GitHub acton 的基本概念和要素,后面再根据自己的需求在对应的模板中做选择,这样可以提高写action的效率。
GitHub自动给我们生成了这个main.yml文件,里头已经填充上一个工作流所必须的基本要素了。
这个文件可以好好说明一下。首先是文件的位置,GitHub默认给我们创建的位置是基于项目下的.github/workflows/目录中,其实这是GitHub action执行工作流的指定路径,要想让GitHub识别并执行工作流的话,对应的工作流文件是必须要放在这个目录下的。
当然最终要的是这个文件的内容了,我将其拷贝出来并做一些精简,如下。
# name属性用来指定这个工作流的名字
name: HELLO GITHUB ACITON
# 这个部分用来指定能够触发工作流执行的事件
on:
# 当对分支main进行push操作的时候,这个工作流就被触发了
push:
branches: [ main ]
# 工作流是由一个或多个的jobs构成的,在jobs里来说明要交给GitHub aciton执行的任务
jobs:
# 这个jobs中的一个任务,名字叫build(随便怎么取)
build:
# 用来指定这个任务在什么操作系统上跑(服务器是GitHub免费提供的)
runs-on: ubuntu-latest
# 指出这个build任务的步骤
steps:
# 步骤,这里只写了一个步骤,目的是输出hello github acition
- name: Run a one-line script
run: echo Hello, github action!
当我们push或者修改文件代码时,workflows会被运行
GitHub action 中的一些基本概念
刚才直观地通过一个例子来说明了一下GitHub action是怎么执行的,接下来把GitHub action的一些基本概念给汇总下,这里主要引用了阮一峰老师的文章。
GitHub Actions 有一些自己的术语。
(1)workflow (工作流程):持续集成一次运行的过程,就是一个 workflow。
(2)job (任务):一个 workflow 由一个或多个 jobs 构成,含义是一次持续集成的运行,可以完成多个任务。
(3)step(步骤):每个 job 由多个 step 构成,一步步完成。
(4)action (动作):每个 step 可以依次执行一个或多个命令(action)。
GitHub Actions
的配置文件叫做workflow
文件,存放在代码仓库的.github/workflows
目录。
workflow
文件采用YAML
格式,文件名可以任意取,但是后缀名统一为.yml
,比如foo.yml
。一个库可以有多个workflow
文件。GitHub 只要发现.github/workflows
目录里面有.yml
文件,就会自动运行该文件。
我们要写的主要文件也就是workflow文件,其中可以配置的字段非常多,主要介绍下一些常用的字段,更多的可以查看官方文档。
还是直接给出一个完整的worflow文件,字段直接用注解备注了。
#字段1 name:用来指定workflow的名称,必备
name: Greeting from Mona
#字段2 on: 用来指定触发 workflow 的条件,通常是某些事件。
# 也可以是数组,如 on: [push, pull_request]
on: push
#字段3 jobs: workflow文件的主体是jobs字段,表示要执行的一项或多项任务
jobs:
#字段4: jobs.job_id: job_id是自定义的,比如这里写my_job
my-job:
# 字段5: jobs.job_id.name: 用来指定这个job的说明
name: My Job
# 字段6: jobs.job_id.runs-on: 用来指定这个job要在什么环境跑,也是必备的
runs-on: ubuntu-latest
# 字段7: jobs.job_id.steps: steps字段指定每个 Job 的运行步骤,可以包含一个或多个步骤。steps是一个数组,每个元素是一个step
steps:
# 字段8: name,具体的一个step的名字
- name: Print a greeting
# 字段9: env,具体的一个step会用到的环境变量
env:
MY_VAR: Hi there! My name is
FIRST_NAME: Mona
MIDDLE_NAME: The
LAST_NAME: Octocat
#字段10: run,具体的一个步骤运行的命令或者 action。
run: |
echo $MY_VAR $FIRST_NAME $MIDDLE_NAME $LAST_NAME.
通过workflow示例文件也可以看出GitHub action中涉及到的基本概念的关系:在一个step中说明要做的事,比如执行指令或者使用他人的action, 一个job由多个step构成,jobs由多个job构成,而workflow的主体是jobs。workflow就是通过这样的层次组织来实现工作流的执行。
GitHub action执行定时任务脚本
使用使用GitHub action来推送天气到微信或QQ
现在,我们写一个爬虫脚本用来获取天气信息
github项目地址
参考教程
#!/usr/bin/python3
#coding=utf-8
import requests, json
# SCKEY=os.environ.get('SCKEY','') ##Server酱推送KEY
# SKey=os.environ.get('SKey','') #CoolPush酷推KEY
SCKEY='你的Server酱推送KEY' #通过 http://sc.ftqq.com/?c=code 获取
SKey='你的CoolPush酷推KEY' #通过 https://cp.xuthus.cc/ 获取
def get_iciba_everyday():
icbapi = 'http://open.iciba.com/dsapi/'
eed = requests.get(icbapi)
bee = eed.json() #返回的数据
english = bee['content']
zh_CN = bee['note']
str = '【奇怪的知识】\n' + english + '\n' + zh_CN
return str
def ServerPush(info): #Server酱推送
api = "https://sc.ftqq.com/{}.send".format(SCKEY)
title = u"天气推送"
content = info.replace('\n','\n\n')
data = {
"text": title,
"desp": content
}
print(content)
requests.post(api, data=data)
def CoolPush(info): #CoolPush酷推
# cpurl = 'https://push.xuthus.cc/group/'+spkey #推送到QQ群
# cpurl = 'https://push.xuthus.cc/send/' + SKey # 推送到个人QQ
api='https://push.xuthus.cc/send/{}'.format(SKey)
print(info)
requests.post(api, info.encode('utf-8'))
def main():
try:
api = 'http://t.weather.itboy.net/api/weather/city/' #API地址,必须配合城市代码使用
city_code = '101110105' #进入https://where.heweather.com/index.html查询你的城市代码
tqurl = api + city_code
response = requests.get(tqurl)
d = response.json() #将数据以json形式返回,这个d就是返回的json数据
if(d['status'] == 200): #当返回状态码为200,输出天气状况
parent = d["cityInfo"]["parent"] #省
city = d["cityInfo"]["city"] #市
update_time = d["time"] #更新时间
date = d["data"]["forecast"][0]["ymd"] #日期
week = d["data"]["forecast"][0]["week"] #星期
weather_type = d["data"]["forecast"][0]["type"] # 天气
wendu_high = d["data"]["forecast"][0]["high"] #最高温度
wendu_low = d["data"]["forecast"][0]["low"] #最低温度
shidu = d["data"]["shidu"] #湿度
pm25 = str(d["data"]["pm25"]) #PM2.5
pm10 = str(d["data"]["pm10"]) #PM10
quality = d["data"]["quality"] #天气质量
fx = d["data"]["forecast"][0]["fx"] #风向
fl = d["data"]["forecast"][0]["fl"] #风力
ganmao = d["data"]["ganmao"] #感冒指数
tips = d["data"]["forecast"][0]["notice"] #温馨提示
# 天气提示内容
tdwt = "【今日份天气】\n城市: " + parent + city + \
"\n日期: " + date + "\n星期: " + week + "\n天气: " + weather_type + "\n温度: " + wendu_high + " / "+ wendu_low + "\n湿度: " + \
shidu + "\nPM25: " + pm25 + "\nPM10: " + pm10 + "\n空气质量: " + quality + \
"\n风力风向: " + fx + fl + "\n感冒指数: " + ganmao + "\n温馨提示: " + tips + "\n更新时间: " + update_time + "\n✁-----------------------------------------\n" + get_iciba_everyday()
# print(tdwt)
# requests.post(cpurl,tdwt.encode('utf-8')) #把天气数据转换成UTF-8格式,不然要报错。
ServerPush(tdwt)
CoolPush(tdwt)
except Exception:
error = '【出现错误】\n 今日天气推送错误,请检查服务或网络状态!'
print(error)
print(Exception)
if __name__ == '__main__':
main()
我们需要编写的main.yml
文件
# name属性用来指定这个工作流的名字
name: GITHUB ACITON Weater
# 这个部分用来指定能够触发工作流执行的事件
on:
# 当对分支main进行push操作的时候,这个工作流就被触发了
push:
branches: [ main ]
# 工作流是由一个或多个的jobs构成的,在jobs里来说明要交给GitHub aciton执行的任务
jobs:
# 这个jobs中的一个任务,名字叫build(随便怎么取)
build:
# 用来指定这个任务在什么操作系统上跑(服务器是GitHub免费提供的)
runs-on: ubuntu-latest
steps:
# 首先copy git仓库到虚拟机上
- name: Checkout
uses: actions/checkout@v2
# 安装初始化python
- name: 'Set up Python'
uses: actions/setup-python@v1
with:
python-version: 3.8
# 安装脚本所需的依赖
- name: 'Install requests'
run: pip install requests
# 运行脚本
- name: 'Working'
env: #添加环境变量
SCKEY: ${{ secrets.SCKEY }}
SKEY: ${{ secrets.SKEY }}
run: python ./weater.py
爬虫脚本文件weater.py
#!/usr/bin/python3
#coding=utf-8
import requests, json
import os
SCKEY=os.environ.get('SCKEY') ##Server酱推送KEY
SKey=os.environ.get('SKEY') #CoolPush酷推KEY
def get_iciba_everyday():
icbapi = 'http://open.iciba.com/dsapi/'
eed = requests.get(icbapi)
bee = eed.json() #返回的数据
english = bee['content']
zh_CN = bee['note']
str = '【奇怪的知识】\n' + english + '\n' + zh_CN
return str
def ServerPush(info): #Server酱推送
api = "https://sc.ftqq.com/{}.send".format(SCKEY)
title = u"天气推送"
content = info.replace('\n','\n\n')
data = {
"text": title,
"desp": content
}
print(content)
requests.post(api, data=data)
def CoolPush(info): #CoolPush酷推
# cpurl = 'https://push.xuthus.cc/group/'+spkey #推送到QQ群
# cpurl = 'https://push.xuthus.cc/send/' + SKey # 推送到个人QQ
api='https://push.xuthus.cc/send/{}'.format(SKey)
print(api)
print(info)
requests.post(api, info.encode('utf-8'))
def main():
try:
api = 'http://t.weather.itboy.net/api/weather/city/' #API地址,必须配合城市代码使用
city_code = '101110105' #进入https://where.heweather.com/index.html查询你的城市代码
tqurl = api + city_code
response = requests.get(tqurl)
d = response.json() #将数据以json形式返回,这个d就是返回的json数据
if(d['status'] == 200): #当返回状态码为200,输出天气状况
parent = d["cityInfo"]["parent"] #省
city = d["cityInfo"]["city"] #市
update_time = d["time"] #更新时间
date = d["data"]["forecast"][0]["ymd"] #日期
week = d["data"]["forecast"][0]["week"] #星期
weather_type = d["data"]["forecast"][0]["type"] # 天气
wendu_high = d["data"]["forecast"][0]["high"] #最高温度
wendu_low = d["data"]["forecast"][0]["low"] #最低温度
shidu = d["data"]["shidu"] #湿度
pm25 = str(d["data"]["pm25"]) #PM2.5
pm10 = str(d["data"]["pm10"]) #PM10
quality = d["data"]["quality"] #天气质量
fx = d["data"]["forecast"][0]["fx"] #风向
fl = d["data"]["forecast"][0]["fl"] #风力
ganmao = d["data"]["ganmao"] #感冒指数
tips = d["data"]["forecast"][0]["notice"] #温馨提示
# 天气提示内容
tdwt = "【今日份天气】\n城市: " + parent + city + \
"\n日期: " + date + "\n星期: " + week + "\n天气: " + weather_type + "\n温度: " + wendu_high + " / "+ wendu_low + "\n湿度: " + \
shidu + "\nPM25: " + pm25 + "\nPM10: " + pm10 + "\n空气质量: " + quality + \
"\n风力风向: " + fx + fl + "\n感冒指数: " + ganmao + "\n温馨提示: " + tips + "\n更新时间: " + update_time + "\n✁-----------------------------------------\n" + get_iciba_everyday()
# print(tdwt)
# requests.post(cpurl,tdwt.encode('utf-8')) #把天气数据转换成UTF-8格式,不然要报错。
ServerPush(tdwt)
CoolPush(tdwt)
except Exception:
error = '【出现错误】\n 今日天气推送错误,请检查服务或网络状态!'
print(error)
print(Exception)
if __name__ == '__main__':
main()
如果你不想做那么多的步骤,像直接白嫖的的话,毕竟读书人的事,怎么能算嫖呢😜
点击Fork
添加两个Secrets
SCKEY:‘你的Server酱推送KEY’ #通过 http://sc.ftqq.com/?c=code 获取
SKEY:‘你的CoolPush酷推KEY’ #通过 https://cp.xuthus.cc/ 获取
KEY获取地址:
(1)server酱(支持微信推送):https://sc.ftqq.com/3.version
(2)coolpush(支持QQ推送、微信推送):https://cp.xuthus.cc/
拓展:关于action的定时设置
详细使用请参考官方帮助文档
我们想要将上面的脚本设置为每天早上七点定时运行,按照规则,我们可以将cron
设置为0 7 * * *
,但是实际运行时间不是七点,因为规则中描述的是国际时间,与我们国家的时间有差距。
我们可以通过一个时间转换的小工具转换一下TimeBie,我们早上七点就是国际时间的前一天晚上十一点,所以我们应该设置为0 23 * * *
设置为定时任务需要将上面的main.yml
文件可以改为
# name属性用来指定这个工作流的名字
name: GITHUB ACITON Weater
# 这个部分用来指定能够触发工作流执行的事件
on:
# 当对分支main进行push操作的时候,这个工作流就被触发了
push:
branches: [ main ]
schedule:
- cron: 0 23 * * *
# 工作流是由一个或多个的jobs构成的,在jobs里来说明要交给GitHub aciton执行的任务
jobs:
# 这个jobs中的一个任务,名字叫build(随便怎么取)
build:
# 用来指定这个任务在什么操作系统上跑(服务器是GitHub免费提供的)
runs-on: ubuntu-latest
steps:
# 首先copy git仓库到虚拟机上
- name: Checkout
uses: actions/checkout@v2
# 安装初始化python
- name: 'Set up Python'
uses: actions/setup-python@v1
with:
python-version: 3.8
# 安装脚本所需的依赖
- name: 'Install requests'
run: pip install requests
# 运行脚本
- name: 'Working'
env: #添加环境变量
SCKEY: ${{ secrets.SCKEY }}
SKEY: ${{ secrets.SKEY }}
run: python ./weater.py
参考链接:
github官方secrets解释
【云函数】全国疫情数据实时统计(包含部署教程)
基于GITHUB ACTION的定时任务,真香!