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?

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

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

什么是工作流?

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

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

javascript 复制代码
/**
    | - play-github-action
        | - .github
            | - workflows
                - 11.yml
                - learn-github-action.yml
*/

工作流有哪些配置?

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

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

yaml 复制代码
# learn-github-action.yml配置如下:
name: learn-github-action
on: [push]
yaml 复制代码
# 11.yml配置如下:
name: 11
on: [push]

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

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

yml 复制代码
# 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

好,我们再来看下效果:

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

点进去看一下:

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

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

运行一下,效果如下:

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

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必须都运行成功,只要有一个依赖项失败,就会跳过job3的执行。

可能会用到的其他知识点

上下文

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

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

javascript 复制代码
${{ context上下文 }}

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

yml 复制代码
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关键字下设置变量,语法如下:

yml 复制代码
name: learn-github-action
on: [push],
env:
    DAY_OF_WEEK: Monday

部署

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

最后

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

相关推荐
miofly31 分钟前
GitHub 今日推荐|sweety-handdraw-video:文章转手绘口播视频
javascript·开源·github
console.log('npc')1 小时前
[特殊字符] AI Agent 工作台前端实战教程 · 新手入门指南
前端·人工智能
gCode Teacher 格码致知1 小时前
前端教学2:ul标签的应用场合与经典案例
前端
const_qiu1 小时前
第 2.5 章 2.5.6:前端登录、Token 无感续签与路由守卫
java·前端·人工智能·状态模式
用户83134859306981 小时前
Vue3 事件:常用用法与开发高频坑点
前端·javascript·vue.js
weixin_446260851 小时前
ReAct‑Evolve:基于轨迹反馈的ReAct智能体自主提示演化系统
前端·react.js·前端框架
其实防守也摸鱼1 小时前
存储管理:页面置换算法学习任务(测验题要求给出置换页面顺序,缺页次数,缺页率)
android·前端·数据库·学习·oracle·自动化
怒放的生命19912 小时前
前端项目 Docker 打包实操指南
前端·docker·容器
tedcloud1232 小时前
Docker Compose 部署 Immich:手机照片自动备份与常见故障排查
运维·前端·docker·容器·智能手机·开源·流程图
时间的情敌2 小时前
《WebGIS 前端的成长路线,三维可视化工程师需要掌握什么》
前端·状态模式