GitHub Actions 进行前端自动化部署

431 阅读5分钟

前言

在本教程中,我将使用 GitHub Actions 实现前端项目的自动化部署到服务器。我将通过一个示例工作流,仓库中的主分支代码变动时自动进行构建、打包,并将构建后的文件传输到指定的服务器。

基本术语介绍:

  • name: 工作流的名称,应该具有描述性,以便团队成员能够快速理解工作流的用途。
  • on: 触发工作流的事件类型,例如 pushpull_requestschedule 等。根据需要选择适当的事件类型,以便在需要时自动触发工作流。
  • jobs: 工作流中的作业,每个作业可以包含一个或多个步骤,用于定义工作流的具体操作。作业可以并行运行,也可以按顺序运行,具体取决于工作流的需求和逻辑。

步骤定义:

  • name: 步骤的名称,用于描述步骤的作用或功能。
  • run: 步骤的具体执行命令或脚本,可以是 Shell 命令、脚本文件路径或自定义命令。
  • env: 步骤的环境变量,用于设置步骤的运行环境。可以包含自定义的环境变量,以便在步骤中使用。
  • if: 步骤的条件判断,用于控制步骤是否执行。可以使用表达式来判断变量、条件和操作符等,从而实现灵活的流程控制。
  • uses: 步骤使用的 Action,可以是 GitHub Marketplace 中的官方 Action,也可以是团队或个人自定义的 Action。用于封装常用的操作或功能,从而简化工作流的编写和维护。

详细的可以去官方文档查看这边我就不多介绍了。

🏷️开始

一、创建工作流🗂️

在 GitHub 仓库中使用 GitHub Actions,首先需要创建一个工作流(workflow)来定义需要执行的自动化任务。

  1. 在仓库的根目录下创建一个名为 .github/workflows 的目录,如果已存在则不需要创建。
  2. .github/workflows 目录下创建一个以 .yml.yaml 为后缀的文件,作为工作流的配置文件,名字可以随便你取。例如 auto_deploy.yml

image.png

当然你也直接通过可视化界面快速创建: image.png

二、配置代码📑

  1. 给工作流取个名字并设置触发条件。
name: AutoDeploy # 设置工作流的名称

on:
  push: # 设置触发事件为 push 事件
    branches:
      - main # 仅当推送到 main 分支时触发
    paths-ignore: # 忽略的文件或目录
      - LICENSE
      - README.md

  1. 工作流作业和步骤。

一个工作流文件可以包含很多个jobs工作,例如下面的示例中有xxx1,xxx2,xxx3三个工作依次执行,每个工作又可以定义很多个步骤。

jobs:
  xxx1:
    ....具体步骤
    
  xxx2:
    ....具体步骤
    
  xxx3:
    ....具体步骤

因为我们这次自动化部署比较简单所以这边我们就命名一个为build的工作。其中runs-on是指定运行环境的。

jobs:
  build:
    runs-on: ubuntu-latest
  1. 给命为build的工作写上具体steps步骤。

想象一下在我们自己部署项目的时候都做了什么?是不是就是将写好的代码build一下然后把打包好的文件放到服务器的目录里。那么在Github Action中亦是如此。
所以思路:拿代码-打包代码-放到服务器

第一步:拿到我们仓库的代码放到前面的ubuntu环境中。我们使用官方提供的action脚本。 actions/checkout

        - name: Checkout 
            uses: actions/checkout@v3

第二步:安装node环境指定使用什么包管理器(自带了npm、yarn、pnpm)。
actions/setup-node

        - name: Setup
            uses: actions/setup-node@v2
            with:
              node-version: 16
              cache: 'npm'

第三步:安装我们项目中的依赖

        - name: Install
            run: npm install

第四步:执行构建(run根据你自己项目自己的构建命令设置)

        - name: Build
            if: ${{ steps.release.outputs.release_created }}
            run: npm run build

第五步: 部署到服务器这里我使用的是Bo-Yi Wu大佬写的脚本appleboy/scp-action

        - name: Appleboy
            uses: appleboy/scp-action@master
            with:
              host: ${{ secrets.USER_HOST }} # 服务器地址:xxx.xxx.xxx.xxx
              username: ${{ secrets.USER_NAME }} # 服务器名字 一般是root
              key: ${{ secrets.KEY }} # 服务器连接密钥
              source: './dist' # 拷贝文件目录
              target: ${{ secrets.USER_TARGET }} # 服务器目标目录

三、配置密钥🔐

上面的这段代码我们没有直接将一些重要的服务器信息明文显示在文件中,这很不安全当然你要直接明文写上也是可以运行的。
设置密钥:

image.png

image.png

建议命名全大写 image.png 密钥KEY:例如pem文件我们用记事本打开后拷贝进去即可。 image.png 将什么每一步的代码合起来并设置好密钥后就完成了整个简单的自动化部署。

四、缓存优化⌛️

前面的配置完成了整个自动化部署,但是在实际使用过程中我们会发现每次Github执行这个工作流的时候都非常的耗时间。于是我们需要给它加上缓存机制,避免重复下载和安装依赖、构建等耗时操作,从而减少整体的执行时间。

image.png

  • 我们通过actions/cache来实现缓存。
    path: 指定要缓存的目录。这里是 **/node_modules,表示缓存所有项目中的 node_modules 目录。
    key:给这个缓存唯一的key。 唯一key生成的方式有很多这里我使用:${{runner.OS}} 表示当前操作系统类型(如 ubuntu、macos、windows)hashFiles('**/package-lock') 表示对项目中所有的 package-lock 文件进行哈希计算,生成一个唯一的缓存键。
    - name: cache
        id: cache-dependencies
        uses: actions/cache@v3
        with:
          path: |
            **/node_modules
          key: ${{runner.OS}}-${{hashFiles('**/package-lock')}}

现在缓存有了,那么我们就可以对步骤进行条件判断如果有缓存就不执行了。 例:

    - name: 安装依赖
        if: steps.cache-dependencies.outputs.cache-hit != 'true'
        run: npm install

🔩完整代码

拷贝进去配置好密钥即可使用

npm版

name: AutoDeploy

on:
  push:
    branches: [master] # master分支push就执行该工作流
    paths-ignore:
      - LICENSE
      - README.md

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: 检出代码
        uses: actions/checkout@v3 # git 克隆到当前机器上
        
      - name: Node环境
        uses: actions/setup-node@v3
        with:
          node-version: 16.x
          cache: 'npm'
          
      - name: 缓存检查
        id: cache-dependencies
        uses: actions/cache@v3
        with:
          path: |
            **/node_modules
          key: ${{runner.OS}}-${{hashFiles('**/package-lock')}}
          
      - name: 安装依赖
        if: steps.cache-dependencies.outputs.cache-hit != 'true'
        run: npm install

      - name: 打包构建
        run: npm run build
      
      - name: 部署
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.USER_HOST }}
          username: ${{ secrets.USER_NAME }}
          key: ${{ secrets.KEY }}
          source: './dist'
          target: ${{ secrets.USER_TARGET }}

yarn版

name: AutoDeploy

on:
  push:
    branches: [master] # master分支push就执行该工作流
    paths-ignore:
      - LICENSE
      - README.md

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: 检出代码
        uses: actions/checkout@v3 # git 克隆到当前机器上
        
      - name: Node环境
        uses: actions/setup-node@v3
        with:
          node-version: 16.x
          cache: 'yarn'
          
      - name: 缓存检查
        id: cache-dependencies
        uses: actions/cache@v3
        with:
          path: |
            **/node_modules
          key: ${{runner.OS}}-${{hashFiles('**/yarn.lock')}}
          
      - name: 安装依赖
        if: steps.cache-dependencies.outputs.cache-hit != 'true'
        run: yarn

      - name: 打包构建
        run: yarn build

      - name: 查看打包后文件
        run: ls -a
      
      - name: 部署
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.USER_HOST }}
          username: ${{ secrets.USER_NAME }}
          key: ${{ secrets.KEY }}
          source: './dist'
          target: ${{ secrets.USER_TARGET }}

pnpm版

name: AutoDeploy

on:
  push:
    branches:
      - main
    paths-ignore:
      - LICENSE
      - README.md

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: 检出代码
        uses: actions/checkout@v3
        
      - name: Node环境
        uses: actions/setup-node@v2
        with:
          node-version: 16

      - uses: pnpm/action-setup@v2
        name: 安装pnpm
        id: pnpm-install
        with:
          version: 8
          run_install: false
          
      - name: Get pnpm store directory
        id: pnpm-cache
        shell: bash
        run: |
          echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT

      - uses: actions/cache@v3
        name: Setup pnpm cache
        with:
          path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-store-
          
      - name: 安装依赖
        if: steps.cache-hit.outputs.cache-hit != 'true'
        run: pnpm install

      - name: 打包构建
        run: pnpm run build
      
      - name: 部署
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.USER_HOST }}
          username: ${{ secrets.USER_NAME }}
          key: ${{ secrets.KEY }}
          source: './dist'
          target: ${{ secrets.USER_TARGET }}

📌注意

  • 配置代码缩进格式必须正确不然会不生效!
  • 尽量不要明文使用敏感信息。要使用Secrets!

总结

通过以上配置和步骤,实现了仓库代码接收推送到 main 分支时自动进行构建和部署的功能,提高了软件开发的效率和自动化程度。当然你可以根据自己的项目情况做更多的操作和限制。