Github Actions 实践总结
12月 1, 2019
Github Actions 发布有一段时间了,自己用的也挺嗨,过来总结一下。我主要在两个地方用到了,一个是博客,另一个是打包、发布前端项目。整体功能上 Actions 和 GitLab CI/CD 差不多,同样实现了项目的自动化测试、打包、部署,不过 Actions 利用了 GitHub 开源项目平台的特点,提供了 Marketplace,可以直接复用其他作者的 Action。
GitHub Actions 提供了 Marketplace,方便我们对其他好的 Action 进行复用,可以说这也是相比 Gitlab CI/CD 最大的优势了,因为在很多技术栈相同的情况下,CI/CD 的流程也是差不多相同的,很多其他厂商也可以为自己的项目提供一个自动化测试、部署的最佳实践,规范了流程也提高了效率。
概念 #
GitHub Actions 里的术语大致有 Workflow(工作流)、Job(任务)、Step(步骤),他们大致的关系也是依次递进一对多的形式,比如:一个项目可以有多个 Workflow,一个 Workflow 可以有多个 Job,一个 Job 可以有多个 Step。
Workflow #
持续集成一次运行的过程,类似 Gitlab CI/CD 中的 Pipeline 的概念。GitHub Actions 里也需要 runner 用于执行这些 Workflow,可以在项目的 Settings 里配置自己部署的 runner。
Jobs #
Jobs 用于表示要运行各个任务,也类似 Gitlab CI/CD 中的 Jobs 的概念,不同的 Job 也可以跑在不同的机器上面,他们可以是并行运行的,也可以按一定顺序进行的。
Step #
Step 定义了 Job 里要执行的每一个步骤,同时定义了执行的顺序,Step 的值是一个列表,即每一个 Step 也需要多个操作命令才能完成这一件事。
Action #
可能有人觉得 Workflow 和 Action 是一回事,毕竟这个功能就叫 GitHub Actions,我认为还是有点区别的:能封装出来给别人用的叫 Action,自己为项目定义的全流程叫 Workflow,后面的内容我也会以此为原则进行表达。可以参考官方的描述。
配置文件 #
一个 Workflow 的配置文件,一般放在 .github/workflows/
下面,可以自定义文件名,并以 .yml
格式为后缀。GitHub 只要发现.github/workflows
目录里面有.yml
文件,就会“编译”该文件,根据文件定义的规则选择什么时候怎么执行。除了上面介绍的概念,还需要一些其他的关键字,才能完成整个 Workflow 的执行。
name #
定义了 Workflow 的名称。
on #
on
指定了什么情况下触发执行 Workflow。
on:
push:
branches:
- main
- 'releases/**'
on.workflow_call #
自己制作一个 Actions 时,通过 workflow_call 里配置 inputs、secrets 可以实现参数的动态输入,从而实现可复用的 Action。
jobs.id #
Job 的 id 是一个字符串,是用于区分不同 job 的唯一标识符,只能包含字母、数字、-
或 _
。下面例子里 my_first_job
和 my_second_job
就是 job 的 id。
jobs:
my_first_job:
name: My first job
my_second_job:
name: My second job
jobs.runs-on #
runners 运行的环境,枚举有:
- windows-latest
- ubuntu-latest
- macos-latest
jobs.needs #
needs 的值为 job_id,表示 step 的依赖顺序。
jobs.if #
有一些 Step 是根据条件判断是否执行的,在 if 下面,环境变量可以省略 ${{ }}
。
jobs.environment #
声明环境的 name
和 url
,会在 Actions UI 中显示。
jobs.steps.id #
也可以 step 定义一个 id,并可以通过上下文被使用。
jobs.steps.uses #
使用开源的其他项目复用一部分操作。
jobs.steps.with #
在 uses 复用了其他的项目,可能需要 with 配置一些输入的参数。
jobs.steps.run #
run 参数指定在 runner 上执行自己的命令。
环境变量 env #
环境变量 env 可以用来定义一些会多次使用的变量,通过 env 命令声明,然后通过 ${{ env.XXX }}
使用。
env:
DAY_OF_WEEK: Monday
jobs:
greeting_job:
runs-on: ubuntu-latest
env:
Greeting: Hello
steps:
- name: "Say Hello Mona it's Monday"
if: ${{ env.DAY_OF_WEEK == 'Monday' }}
run: echo "$Greeting $First_Name. Today is $DAY_OF_WEEK!"
env:
First_Name: Mona
Github Actions 内置了一些默认的环境变量可以直接使用,比如分支名 GITHUB_REF_NAME
等,更多请参考 官方文档。
上下文 context #
上下文和环境变量类似,但是也有区别:环境变量只存在于执行任务的机器上;而上下文在 workflow 的任何时间节点都存在,包括默认环境变量不可用的时候。例如,在将 job 路由到 runner 执行之前,需要对 gitHub
的上下文进行判断。
name: CI
on: push
jobs:
prod-check:
if: ${{ github.ref == 'refs/heads/main' }}
runs-on: ubuntu-latest
steps:
- run: echo "Deploying to production server on branch $GITHUB_REF"
实战:发布一个 Vue 应用 #
写了一个 Vue 的 demo 项目,想在代码提交后直接发布到 GitHub Pages,我在 Marketplace 已经找到了满足需求的 Action:VuePagesAction,项目主页提供了配置 Example,可以直接在自己的项目里创建 Workflow。
name: Build Vue
on: [push]
jobs:
build_vue:
runs-on: ubuntu-latest
name: Build Vue
steps:
- uses: actions/checkout@v2
- id: Build-Vue
uses: xRealNeon/VuePagesAction@1.0.1
with:
username: 'YourGithubName'
reponame: 'YourRepoName'
token: ${{ secrets.GITHUB_TOKEN }} # Leave this line unchanged
在提交代码到 GitHub 后,此条 Workflow 就会自动运行,并发布到 GitHub Pages,可以参考我的项目 demo。
HCL?main.workflow? #
之前为了能够自动化发布我的博客,也废了不少功夫,我还写了两个 Action:publish-hugo-site 和 push-to-master,不过用的还是以前使用 HCL 的 main.workflow
的写法,在新的 workflow 场景下 GitHub 已经不支持这种方式了,不能再使用,具体可以看 GitHub 的声明。