我本身就有一台自用的服务器(其实也不算,就是一个性能很弱的nas主机)每天24小时运行着,上面跑的系统是ubuntu 18,最近发现了一种玩法,可以把自己写的脚本,或者github上白嫖来的脚本,以定时任务的方式放在上面跑,然后每天就会自动做一些任务感觉挺方便的。目前是把一些签到类的脚本和定时推送消息的脚本放在上面,当然,还有很多的玩法,只要有自己的需求和强大的脚本哈。

前不久在github上瞎逛的时候,我想找找现在有没有什么有趣的脚本可以白嫖哈,发现很多开发者在进行脚本运行说明的时候,都会带上使用GITHUB ACTION的方式来跑。之前我是没有了解过这方面的内容的,在我看来其实挺神奇的,为什么呢?因为执行脚本那必然是需要一台服务器来运行的,也就是会占用服务器的资源,换句话说,难道GitHub可以免费给开发者提供用于运行脚本的服务器资源吗?答案是:没错。那这,如果能够充分的利用这个平台,肯定可以产生很多玩法的,事实也是如此,GitHub action 甚至有个属于自己的市场了,所以,这方面可以折腾下,玩好了那就真香!

什么是GitHub action

我不能很精确的描述它的定义,也不想照搬官方文档对它的定义。简单说说我的理解,字面意思翻译过来就是GitHub动作,加点动词,那就是GitHub帮你做一些(一系列)动作。GitHub action产生的初衷是用于CI的,也就是持续集成。我们知道写完代码,或者改完bug,首先要编译,然后测试,测试没问题可能就是部署了,当然,我说的过程很简单,实际开发过程可能是更复杂的。这些过程实际上都是开发人员手动做的,每次都一样,老实说有点机械和重复。如果能够做到,开发人员修改完代码,程序会自动的进行构建,编译,然后跑测试用例,生成测试报告,如果测试没有问题,然后就部署运行。那么这将是一件十分惬意的事吧,其实现在已经有很多成熟的方案了,我了解到的关于java的就有maven,它是一个专门用于构建java工程的工具,能够一条龙的做到这些过程。

CI和这些构造工具有什么不同吗?其实我还不清楚,只能说一点简单的理解,太菜了哈。现阶段我觉得他们的核心思想是一致的,也就是加快程序开发效率。CI可以从更宏观的角度去描述程序的集成过程,而构建工具可以只是CI的一个环节。CI一般而言都是一个任务流或者说流水线,在这个过程中一个个任务被顺序或者并行执行。

怎么用GitHub action

想要使用GitHub action的功能,首先需要在GitHub上创建一个公开仓库,GitHub action对公开仓库是不收费的。

创建 hello GitHub aciton 工作流

首先,先写一个最简单的GitHub action的工作流来直观的看看其需要什么要素,其实很大部分的内容在GitHub action的官方文档里将的很清楚了,GITHUB ACTION官方文档

进入自己的GitHub 公开仓库,点击ACTION按钮

maven github 关系 github action maven_字段

点击创建一个新的工作流

maven github 关系 github action maven_ci_02

选择自己来写工作流文件,不从GitHub已经提供的工作流模板中做选择。因为是第一次写,所以自己先写可以更直观的了解一些GitHub acton 的基本概念和要素,后面再根据自己的需求在对应的模板中做选择,这样可以提高写action的效率。

maven github 关系 github action maven_github_03

接下来就来到了这个页面,GitHub自动给我们生成了这个main.yml文件,里头已经填充上一个工作流所必须的基本要素了。

maven github 关系 github action maven_ci_04

这个文件可以好好说明一下。首先是文件的位置,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!

一个最最基本的GitHub action工作流就写好了,当进行push操作的时候就会触发。

触发的结果可以点击action按钮进行查看

maven github 关系 github action maven_maven github 关系_05

接下来点击工作流: hello github aciton

maven github 关系 github action maven_github_06

可以看到右侧显示了触发这一个工作流执行的事件,我这里进行了一次push 到main分支的操作,所以就触发了这个工作流。想看到工作流执行的详情,那就再点击到具体的事件就可以了。

maven github 关系 github action maven_github_07

因为我这个工作流十分的简单,唯一的任务就是build,点击build可以看到执行的过程。一个任务的执行一般都是由set up job + steps + complete job构成的,steps前后一般是GitHub action做一些环境的配置,steps部分就是主要由我们写的任务了。我在这个工作流中只写了一个step,也就是 在控制台打印hello,github action!,可以看到它被正确的执行了。

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的特点,写一点脚本让GitHub帮我们定时运行,这点想想就很有意思。

定时推送天气信息到邮箱

使用GitHub action来推送天气到邮箱

还是给出workflow的完整文件,并在上面做注释

name: 'GitHub Actions Weather Bot'
 
on:
  push:
  schedule:
  # 定时任务,在每天的5点推送天气信息到邮箱
    - cron: '0 21 * * *'

jobs:
  bot:
    runs-on: ubuntu-latest
    steps:
    # 首先copy git仓库到虚拟机上
      - name: 'Checkout codes'
        uses: actions/checkout@v1
    # 执行仓库中的脚本文件
      - name: 'Get Weather'
        run: bash ./weather.sh
      # 获取格式化的日期并存入GitHub内置的环境变量中
      - name: 'Get Date'
        run: echo "REPORT_DATE=$(TZ=':Asia/Shanghai' date '+%Y-%m-%d %T')" >> $GITHUB_ENV
      # 使用现成的发送邮箱的GitHub action来发送邮件
      - name: 'Send mail'
        uses: dawidd6/action-send-mail@master
        with:
          # 这些是发送邮件需要配置的参数,更多详细的说明请访问具体的仓库
          server_address: smtp.qq.com
          server_port: 465
          # 这些sectret的环境变量需要配置在setting中的secret下
          username: ${{ secrets.MAIL_USERNAME }}
          password: ${{ secrets.MAIL_PASSWORD }}
          subject: 天气预报 (${{env.REPORT_DATE}})
          body: file://result.html
          to: 1113794717@qq.com
          from: GitHub Actions
          content_type: text/html

下面是脚本文件的内容,目的其实就是获取天气信息并生成文件

#!/bin/bash
set -eux

CITY=Shenzhen
LANGUAGE="zh-CN"
UNIT=m
UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"

curl \
  -H "Accept-Language: $LANGUAGE" \
  -H "User-Agent: $UA" \
  -o result.html \
  wttr.in/$CITY?format=4\&$UNIT

接下来再说明下怎么配置一些比较私密的信息,比如账号、密码之类的

在具体的项目下,点击setting

maven github 关系 github action maven_字段_08

找到secrets

maven github 关系 github action maven_github_09

新增一个secret

maven github 关系 github action maven_ci_10

maven github 关系 github action maven_ci_11

这些新增的secret是可以在GitHub action中使用的,比如上面用于发送天气信息到邮箱的工作流中就用到了。

定时执行bilibili签到、投币脚本

这是我的有关哔哩哔哩的基本仓库,欢迎使用,easy-bilibili

还是贴出完整的workflow文件,并做些说明

name: easy-bilibili-daily-task
on:
  push:
    branches: [ master ]
  schedule:
    # 定时任务,在每天的5点执行任务
  	- cron: '0 21 * * *'
jobs:
  start:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
      - name: use cache to speed up the time of build
        uses: actions/cache@v2
        with:
          path: ~/.m2/repository
          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
      - name: execute the task
        env:
          # 这些参数可以使用电脑打开哔哩哔哩web版获取到,然后将对应的值放入secrets中
          sessdata: ${{ secrets.SESSDATA }}
          userId: ${{ secrets.USERID }}
          bill_jct: ${{ secrets.BILL_JCT }}
          # 配置这个参数可以将消息推送到微信(关注server酱)
          sckey: ${{ secrets.SCKEY }}
        run: mvn compile exec:java -Dexec.mainClass="com.hhdd.Main" -Dexec.args="${sessdata} ${userId} ${bill_jct} ${sckey}"

这个工作流里比较特别的地方,使用了一个cache动作来加速maven的构建。

maven构建的程序依赖很多jar包,如果每次都重新下载这些jar包将很花费时间和网络资源。用了cache就能够将需要的jar包存储起来,存在GitHub提供的服务器上,下次还需要这些依赖的时候直接去取,而不需要重新到网络上下载,这就大大加快了构建的过程。为了能够准确的找到自己存储在GitHub服务器上的cache,使用这个cache动作的时候会生成一个key,生成key的方式多种多样,围绕的核心准则是能够准确的找到cache并且当依赖发生变化的时候能够及时的更新cache。这里用到的是官方提供的生成方式 ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }},已经足够好用了。

工作流的最后一步是执行整个maven工程的主类,也就是Main,需要传入一些参数,参数的来源是secret。

来看看执行结果

maven github 关系 github action maven_ci_12

成功进行观看视频和投币,哈哈。

最后

简单写了点GitHub action的用法和玩法,我用它来推送天气消息和哔哩哔哩的签到任务。其实如果足够有心,你也可以这么做,还是挺方便有趣的。GitHub action能做的东西当然远不止这些,何况说,它的核心是用来CI的,其实我这种玩法有玩坏的嫌疑哈,要了解更多当然得看github action的官方文档了。GitHub上还有挺多有意思的脚本,如果配合上这个GitHub action还挺不错的哈,比如:

  1. BILIBILI-HELPER (b站签到)
  2. jd_base(jd签到)

这是我的个人博客地址:https://huanglusong.github.io/
有任何问题,只要是对技术热爱,喜欢倒腾的小伙伴欢迎加入qq群:624017389,一起交流,本人主要是搞java开发的,希望能和大家共同学习,齐头共进。

参考文章:

  1. GitHub Actions 入门教程_阮一峰
  2. GitHub Actions 教程:定时发送天气邮件
  3. GITHUB ACTION 官方文档