#Github

简介

GitHub Actions 是 GitHub 在 2018 年推出的持续集成服务。它可以自动完成一些开发周期内的任务,如 Push 代码时自动编译,Pull 代码时自动执行测试脚本等等。

我了解 GitHub Actions 的契机是,我在 GitHub 上保存了一些 Markdown 文档,我希望每次更新文档后自动使用 Pandoc 转换成 PDF 文档。接下来我们一起学习如何通过 GitHub Actions 实现这样的需求。

首先我们先直观的了解一下它在 GitHub 的位置,如果打开一个仓库,它有图中绿色对号√,或者红色叉号×,说明这个项目配置了 GitHub Actions,绿色表示自动化的流程运行成功了,红色表示失败了。

我们点开Actions按钮就可以查看具体的任务详情。下面我们先学习如何配置一个简单的 GitHub Actions。

配置 GitHub Actions

GitHub Actions 可以简单理解为一些自动化脚本,工具,目的就是为了减少重复工作,所以这些工具都可以做成普适性的工具。而 GitHub 官方就开放了一个这类工具的市场,我们可以在上面搜索自己想要的工具。因为初学 GitHub Actions 所以也不知道怎么写配置文件,我们可以直接搜索一个并应用它,看看别人是怎么写的。

我们进入一个自己的仓库,点击Actions,搜索框中搜索PDF,在搜索结果中找到Create PDF · Actions这个工具。如果搜索到点击Configure。如果显示未找到,则点击set up a workflow yourself,同样搜索PDF

打开详情页面,拉到底,将Example usage。里的内容复制到编辑框中。点击右上角Start commit将会把我们新建的main.yml提交到仓库中。这就相当于创建了一个生成 PDF 的 GitHub Actions。当然每个 Actions 都有一些使用要求,比如这里还要根据介绍,创建几个文件夹,比如从哪个文件夹获取源文件,生成后的 PDF 又会放到哪个文件夹等。这里就不再介绍,我们先了解如何创建一个 Actions。

Workflow 配置

GitHub Actions 的配置文件叫做 workflow 文件,存放在代码仓库的.github/workflows 目录。

workflow 文件采用 YAML 格式,文件名可以任意取,但是后缀名统一为.yml or .yaml,比如 foo.yml or foo.yaml。一个库可以有多个 workflow 文件。GitHub 只要发现.github/workflows 目录里面有.yml or .yaml 文件,就会自动运行该文件(并行)。

接下来我们逐个参数来解释都有哪些功能。

on

触发 workflow 的 GitHub 事件的名称。比如push代码时触发,其他人fork代码仓时触发等等。

可以只有一个事件触发,

1
on: push

也可有多个事件触发,使用列表列举,

1
on: [push, fork]

所有支持的事件列表,请查看官方文档

on.[push|fork].[tags|branches]

注意:从这里开始就会出现一个字段下有子字段,每个点号.分割一个子字段。如push或者fork可以作为on的子字段,tags或者branches可以作为push或者fork的子字段。在yaml文件中,缩进很重要,每个缩进都表示是从属关系,表示是该字段的子字段。千万要注意缩进关系,如果缩进出错,那么将无法解析yaml文件。

指定触发事件时,可以限定分支或标签。

1
2
3
4
on:
push:
branches:
- master

上面代码指定,只有 master 分支发生 push 事件时,才会触发 workflow。

name

工作流程的名称。GitHub 在仓库的操作页面上显示工作流程的名称。如果省略 name,GitHub 将其设置为相对于仓库根目录的工作流程文件路径。

jobs

workflow 运行包括一项或多项 jobs。jobs 默认是并行运行。要按顺序运行作业,可以使用 [job_id].needs 关键词在其他 job 上定义依赖项。

每个作业在 runs-on 指定的运行器环境中运行。

jobs.[job_id]

jobs 中的每个任务都有一个[job_id] ,且其必须为 jobs 对象中唯一的字符串键值[job_id]必须以字母或_开头,并且只能包含字母数字字符、-_

1
2
3
4
5
jobs:
first_job: # [job_id],任务 id
name: My first job
second_job:
name: My second job

jobs.[job_id].[runs-on]

runs-on 字段指定运行所需要的虚拟机环境。它是必填字段。目前可用的虚拟机如下。

1
2
3
- ubuntu-latest,ubuntu-18.04或ubuntu-16.04
- windows-latest,windows-2019或windows-2016
- macOS-latest或macOS-10.14

下面代码指定虚拟机环境为 ubuntu-18.04。

1
runs-on: ubuntu-18.04

jobs.[job_id].name

workflow 文件的主体是 jobs 字段,表示要执行的一项或多项任务。

job_id 里面的 name 字段是任务的说明。它可以在网页端的 UI 上显示。

1
2
3
4
5
jobs:
first_job:
name: My first job # [job_name],任务名称
second_job:
name: My second job

jobs.[job_id].needs

needs 字段指定当前任务的依赖关系,即运行顺序。

1
2
3
4
5
6
jobs:
job1:
job2:
needs: job1
job3:
needs: [job1, job2]

上面代码中,job1 必须先于 job2 完成,而 job3 等待 job1 和 job2 的完成才能运行。因此,这个 workflow 的运行顺序依次为:job1、job2、job3。

jobs.[job_id].steps

steps 字段指定每个 Job 的运行步骤,可以包含一个或多个步骤。每个步骤都可以指定以下三个字段。

1
2
3
- jobs.[job_id].steps.name:步骤名称。
- jobs.[job_id].steps.run:该步骤运行的命令或者 action。
- jobs.[job_id].steps.env:该步骤所需的环境变量。

下面是一个完整的 workflow 文件的范例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
name: Greeting from Mona
on: push

jobs:
my-job:
name: My Job
runs-on: ubuntu-latest
steps:
- name: Print a greeting
env:
MY_VAR: Hi there! My name is
FIRST_NAME: Mona
MIDDLE_NAME: The
LAST_NAME: Octocat
run: |
echo $MY_VAR $FIRST_NAME $MIDDLE_NAME $LAST_NAME.

上面代码中,steps 字段只包括一个步骤。该步骤先注入四个环境变量,然后执行一条 Bash 命令。

jobs.[job_id].steps[*].uses

选择一个 action,可以理解为若干 steps.run,有利于代码复用。这也是 github action 最主要的功能。

比如最常用的,下载本仓库的代码到工作区,就是使用的一个 action 完成的:

1
2
3
steps:
- name: Check out Git repository
uses: actions/checkout@v2

注:@v2 什么意思?
表示 Action 的版本。我们如果不带版本号的话,就是默认使用最新版本。Github 官方强烈要求我们带上版本号。这样子的话,我们就不会出现:写好一个 Workflow,但是由于某个 Action 的作者一更新,我们的 Workflow 就崩了的问题

jobs.[job_id].steps.run

在 shell 中执行的命令:

1
2
3
4
5
6
steps:
- uses: actions/checkout@v2
- name: create dir
id: dir
run: |
mkdir output # create output dir

以上配置是在下载完本仓库的代码后,在仓库根目录新建一个output文件夹。注意run:后的|表示可以多行命令。如果没有|表示只能执行一条命令。

jobs.[job_id].steps.working-directory

用来指定在run命令在哪执行。

1
2
3
- name: Create dir
run: mkdir output
working-directory: ./build

jobs.[job_id].steps.shell

用来指定 shell 类型,如 Python,bash,powershell 等。

1
2
3
4
steps:
- name: Display the path
run: echo $PATH
shell: bash

所有支持的类型请查看官方文档

如何跳过 GitHub Actions

在 commit message 中只要包含了下面几个关键词就会跳过 Github Actions。

1
2
3
4
5
[skip ci]
[ci skip]
[no ci]
[skip actions]
[actions skip]

实例:自动使用 Pandoc 将 Markdown 文件转换为 PDF

Dunky-Z/uefi-spec-zh项目中使用的 GitHub Actions 为例,解释如何实现将 Markdown 文件转换为 PDF。

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
52
53
# CI 名为 MPPL
name: MPPL

# 在 Push 代码时触发 CI
on: push

jobs:
# 任务名称为 convert_via_pandoc
convert_via_pandoc:
# 在 ubuntu-latest 系统上运行
runs-on: ubuntu-latest
steps:
# 步骤一:下载最新代码
- uses: actions/checkout@v2
# 步骤二:在项目根目录建立 output 文件夹放生成的 PDF 文件
- name: create file list
id: files_list
run: |
mkdir output # create output dir
# 步骤三:更新项目的子模块
- name: Git Sumbodule Update
run: |
git submodule update --init --remote --recursive
# 步骤四:为运行的系统中安装需要的字体,因为原系统没有需要的中文字体
# 字体来源为项目目录的MPPL/fonts
- name: add fonts
run: |
sudo apt-get install ttf-mscorefonts-installer
sudo apt-get install fontconfig
fc-list :lang=zh
ls -lh /usr/share/fonts/
cp -rf ./MPPL/fonts/* /usr/share/fonts/
mkfontscale
mkfontdir
fc-cache
fc-list
# 步骤五:安装 pandoc 和 texlive
- name: install pandoc
run: |
sudo apt-get update
sudo apt-get install texlive-full
sudo apt-get install pandoc
sudo apt-get clean
# 步骤六:使用 pandoc 命令生成 pdf
- name: build pdf
run: |
cd src
pandoc -f markdown-auto_identifiers --listings --pdf-engine=xelatex --template=../MPPL/templates/mppl.tex --output=../output/UEFI规范-中文.pdf *.md
# 步骤七:将生成的结果上传到 GitHub
- uses: actions/upload-artifact@master
with:
name: output
path: output

注意事项

every step must define a uses or run key
every step must define a uses or run key · Issue #2 · einaregilsson/beanstalk-deploy

参考

GH actions: a step cannot have both the uses and run keys · Issue #318 · fhem/mod-Buienradar

every step must define a uses or run key · Issue #2 · einaregilsson/beanstalk-deploy

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×