GitHub Action一次看个透

大家好,我是小九九的爸爸,本次给大家带来的内容是自动化部署。聊到这个方向,大家肯定都会想到CI、CD等一系列名词。那这次就来一遍看个透吧。这篇文章肯定会有没讲到的地方,也欢迎大家在评论区里补充。

首先来说一下 部署(Deployment),它其实就是代码发布的一种行为。就拿前端来举例子,如果是开发的工具库的话,那肯定避免不了下面的流程:

  • npm config set registry xxx
  • npm login
  • npm version xxx
  • npm publish
  • npm run build(生成工具库的使用文档以及changelog)
  • 将使用文档推到服务器上或者免费的托管平台。

这一套下来,你说是否繁琐呢,不好定义。这个时候出现了自动部署的概念。相当于你把你固定的操作流程写成一个任务清单,然后自动化部署工具执行这个任务清单就完事了。

所以你看,自动部署(Continuous Deployment,简称CD)干了什么事呢?其实就是帮你执行那些重复的部署动作。当然,如果你觉得手动部署也花费不了自己多长时间,那自动部署对你来说就完全没必要了。

实现自动化部署有哪些方案呢?Jenkins是一个,GitHub Action也是一个解决方案。

那我们本篇文章的主角就出来啦,GitHub Action。

GitHub Actions 是一种持续集成和持续交付 (CI/CD) 平台,这个平台主要是依靠“工作流”的概念来完成部署的功能。同时,它也可以将整个运行流程给可视化出来。下图就是我们今天要做出来的成果:

GitHub Action一次看个透_第1张图片

如何使用GitHub Action?

这个功能是依附在GitHub平台上的,所以要求就是你的项目必须托管在GitHub上。为了方便学习GitHub Action,我们可以随便在自己的账号下建一个项目,建项目的流程在这里就省略了,请自行发挥。

上面我们说过,这个功能是围绕“工作流”来展开。那我们就来说说“工作流”的概念吧。

什么是工作流?

工作流是一个可配置的自动化流程,将运行一个或多个作业。工作流由YAML文件定义。

上面这句话我第一次看的时候,其实内心是懵逼的,后来我知道了,它想表述的是一个工作流,就是一个yaml文件,就是一个可以执行具体命令的容器。yaml文件的位置是有要求的,位于项目根目录下的.github目录下的workflows目录里。我的项目名称叫做play-github-action,所以我的项目结构应该是下面这样的:

/**
    | - play-github-action
        | - .github
            | - workflows
                - 11.yml
                - learn-github-action.yml
*/

工作流有哪些配置?

配置 说明 是否必输
name 表明这次工作流的名称
on 表明工作流里的任务什么时候被执行
jobs 表明工作流里的任务集合
concurrency 表明工作流里的最大任务数量

说了那么多,我们来配置下yml文件,来看看效果:

# learn-github-action.yml配置如下:
name: learn-github-action
on: [push]
# 11.yml配置如下:
name: 11
on: [push]

当我们push代码的时候,这2个工作流就会被执行,此时回到GitHub平台,点击actions页签来看一下具体的情况:

GitHub Action一次看个透_第2张图片
从上面的工作流程,我们可以暂时得出GitHub Action平台有以下几点规律:

  • 只要你push来代码,就会执行yml文件。这是因为我们使用了on关键字。当然如果你想指定push某个分支时再执行话,这也是可以的。这种需求很常见,比如main分支里有yml文件,你今天基于main分支新切了一个develop分支,那此时develop分支里,自然就会有main分支的yml文件。如果你想指定push main分支时才会运行workflow,那么你可以这么写:
name: CI
on:
  push:
    branches: [ main ]

  • 在这个平台里,一个yml就是一个数据list,点进去我们就会看到具体的任务,以及任务里的步骤。
  • 当我们多次提交后,会发现,其实每个yml文件的执行顺序是不固定的。这是因为工作流之间默认的工作方式是并发。
  • 上面的workflows报错啦,符合预期,因为我们并没有定义jobs。

什么是作业?

我们以单页面应用来举例子,我们部署应用的时候一般会经历以下步骤:

  • 拉取代码
  • 安装依赖
  • 执行打包
  • 将打包后的产物推到远程服务器里

那这个时候,这4个动作就可以被认为是4个作业。当然,你也可以把这4个动作合并为一个作业,你甚至也可以分解为2个作业,这完全取决于用户。

那如何声明job呢?使用jobs关键字。jobs定义里一个集合,你需要将跟本次需求相关的job都放入到这个集合里。还需要声明一点,当一个workflow里拥有多个job时,默认情况下,job的执行顺序是并行的。

作业有哪些配置?

配置 说明 是否必输
jobs.job_id 作业的id
jobs.job_id.runs-on 定义运行job时的计算机类型。其实就相当于指定服务器的运行系统。
jobs.job_id.steps 完成id为job_id的任务,需要执行的步骤集合。
jobs.job_id.steps.run 执行shell命令,相当于node里的child_process。
jobs.job_id.steps.use 用于获取你上传的代码。
jobs.job_id.name 当前作业id的名称。如果你只配置里job_id,那么平台会认为作业的id、name是一样的。
jobs.job_id.needs 定义job之间的关系

又说了那么多,我们再来修改下配置,然后再see one see 效果:

# learn-github-action.yml配置如下:
name: learn-github-action
on: [push]
jobs:
  checkout-bats-version1:                     # job_id
    name: checkout-version1-name              # job_id.name
    runs-on: ubuntu-latest                    # job_id.runs-on
    steps:
      - uses: actions/checkout@v1             # 检出代码
      - uses: actions/setup-node@v3
        with: 
          node-version: '14'
      - run: npm install -g bats               # 执行命令
      - run: bats -v

push一下代码,我们再来看下效果:

GitHub Action一次看个透_第3张图片

learn-github-action.yml文件执行成功了,但是 11.yml 文件失败了。符合预期,因为我们只改了learn-github-action.yml文件。点进去看一下:

GitHub Action一次看个透_第4张图片

那我如果再加一个任务呢?

name: learn-github-action
on: [push]
jobs:
  checkout-bats-version1:                #job1
    name: checkout-version1-name
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v3
        with: 
          node-version: '14'
      - run: npm install -g bats
      - run: bats -v
  checkout-bats-version2:               #job2
    name: checkout-version2-name
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v3
        with: 
          node-version: '14'
      - run: npm install -g bats
      - run: bats -v

运行一下,效果如下:

GitHub Action一次看个透_第5张图片
这个效果图告诉我们,当前这2个任务是并行的关系。那如何表示任务之间是继发的呢?needs关键字闪亮登场,修改yml文件如下:

name: learn-github-action
on: [push]
jobs:
  checkout-bats-version1:                #job1
    name: checkout-version1-name
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v3
        with: 
          node-version: '14'
      - run: npm install -g bats
      - run: bats -v
  checkout-bats-version2:                #job2
    name: checkout-version2-name
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v3
        with: 
          node-version: '14'
      - run: npm install -g bats
      - run: bats -v
  checkout-bats-version3:                #job3
    needs: [checkout-bats-version1, checkout-bats-version2]
    name: checkout-bats-version3-name
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v3
        with: 
          node-version: '14'
      - run: npm install -g bats
      - run: bats -v

运行以后,我们就得到了文章开头的那个图。这段代码表示,job3的运行之前,必须先运行job1、job2。

可能会用到的其他知识点

上下文

它其实就是一个对象,这个对象里包含里当前workflow的信息、当前workflow下的每个job的信息、当前workflow下的所有变量的信息等等。

那如何访问上下文对象呢?语法如下:

${{ context上下文 }}

它可以在任何地方被使用,比如可以在if表达式里使用。举个例子,上面的步骤中,我们不是使用了on关键字实现了push指定分支才触发workflow嘛,我们也可以使用上下文来实现这个功能:

name: learn-github-action
on: [push],
jobs:
  checkout-bats-version1:                     # job_id
    name: checkout-version1-name              # job_id.name
    if: ${{ github.ref == 'refs/heads/main' }}
    runs-on: ubuntu-latest                    # job_id.runs-on
    steps:
      - uses: actions/checkout@v1             # 检出代码
      - uses: actions/setup-node@v3
        with: 
          node-version: '14'
      - run: npm install -g bats               # 执行命令
      - run: bats -v

只有当if条件通过啦,github action才会将 名为checkout-version1-name的job 发送到运行器ubuntu-latest上,将作业发送到运行器后,执行job下的步骤。在这个步骤里,我们使用了内置的github上下文,还有很多内置的上下文,具体的可以去 上下文 - GitHub 文档看看。

环境变量

在env关键字下设置变量,语法如下:

name: learn-github-action
on: [push],
env:
    DAY_OF_WEEK: Monday

部署

github action也支持将前端工具发布到npm上,具体的操作,相信有前面的铺垫后,阅读起来应该不成问题。

最后

好啦,本期分享到这里就结束啦,希望我的分享对你有帮助,如果你觉得还可以,也可以给我来一个3星好评,我们下期再见啦~~

你可能感兴趣的:(github,持续部署)