likes
comments
collection
share

使用 GitHub Actions 自动化部署 全栈个人博客项目

作者站长头像
站长
· 阅读数 42

引言

最近有在陆续地为自己的“全栈个人博客网站”增添一些新的功能,但每次开发完毕后都需要手动地将整个项目重新部署到服务器,且该过程十分繁琐。诸如:将前端代码打包到指定路径(生产环境);在本地压缩代码并上传到服务器;在服务器解压代码并移动到指定路径;进入工程文件夹并安装项目依赖;执行指令以重新运行项目等。部署成功之后,如果发现某些被漏掉的BUG,则要继续重复上述流程,繁琐至极。

那么,有没有什么办法能够将上述重新部署的流程自动化呢?

当然有,而且有很多方法!由于该项目是托管到GitHub上的,因此采用“GitHub Actions”方案来实现。最终效果为:每次开发完毕后,我们只需要将整个“前后端”项目push到GitHub,项目就会被自动化部署到服务器。

概念初探

  • Workflow(工作流)

    即工作流程,是一个可配置的自动化过程,它将运行一个或多个任务。 工作流程由工程根目录/.github/workflows路径下的 YAML 文件定义,在该文件中我们可以监听某些事件,当事件被触发后则会进入到对应的工作流程。

  • Job(任务)

    一个工作流程中包含一个或多个任务,一个任务由若干个步骤组成。

  • Step(步骤)

    一个任务可以包含一个或多个步骤,且上述步骤会被依次执行。

  • Action(动作)

    每个步骤可以包含一个或多个动作,诸如一些实际的指令(npm install等)。

使用 GitHub Actions 自动化部署 全栈个人博客项目

语法简述

  • name

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

    name: GitHub Actions Test
    
  • on

    触发工作流程(workflow)的事件,更多可用事件的列表,请参阅“触发工作流程的事件”。

    # 单个事件
    on: push # 将任何分支push到仓库时,将运行具有上述 on 值的工作流程
    
    # 多个事件
    on: [push, fork] # 将任何分支push到仓库或有人fork仓库时,将运行具有上述 on 值的工作流程
    
    # 筛选器
    on:
      push:
        branches:
          - main # 当main分支发生push操作时,将执行所属工作流程
    
  • jobs

    jobs 包含当前工作流程中的所有任务,每个任务会在 runs-on 指定的运行器环境中运行,常用的关键字段如下:

    • jobs.<job_id>

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

      jobs:
        my_first_job:  # <job_id>,任务id
          name: My first job
        my_second_job:
          name: My second job
      
    • jobs.<job_id>.name

      该字段用以指定当前任务的名称,且其将会展示在 GitHub 对应的 UI 界面上。

      jobs:
        my_first_job:  
          name: My first job  # <job_id>.name,任务名称
        my_second_job:
          name: My second job
      
    • jobs.<job_id>.needs

      该字段用以指定各个任务之间的依赖关系。

      jobs:
        job1:
        job2:
          needs: job1
        job3:
          needs: [job1, job2]
      

      上述代码中,job1 必须在 job2 开始之前成功完成,而 job3 要等待 job1job2 完成。最终运行顺序为:job1job2job3

    • jobs.<job_id>.runs-on

      该字段用来指定任务将在哪个虚拟环境中运行。如果使用 GitHub 托管的运行器,每个作业将在 runs-on 指定的虚拟环境的新实例中运行。

      runs-on: ubuntu-latest
      

      可用的 GitHub 托管的运行器类型包括:

      使用 GitHub Actions 自动化部署 全栈个人博客项目

      虚拟环境-latest是 GitHub 提供的最新稳定映像,可能不是操作系统供应商提供的最新版本的操作系统。

    • jobs.<job_id>.steps

      每个任务会包含一系列步骤,称为 steps。 在步骤中,可以运行命令、运行设置任务,或者运行您的仓库等操作。 并非所有步骤(step)都会运行操作(action),但所有操作(action)都会作为步骤(step)运行。

      每个步骤一般会包含下面三个字段:

      jobs.<job_id>.steps.name:该步骤的名称。
      jobs.<job_id>.steps.run:该步骤需要执行的命令,如 npm install
      jobs.<job_id>.steps.env:该步骤所需的环境变量。
      

      当然,也可以使用其他大佬封装好的 action,详见 actions 市场

      steps:
        - name: Use extra action
        - uses: actions/checkout@v3
      

      更多语法,详见官方文档:GitHub Actions

部署流程

1. 项目概览

  • 项目预览:hechunxu.tech

  • 项目地址:github.com/Allen-He/my…

  • 项目描述:即“全栈个人博客网站”,前端使用 Vue2.x,后端使用 NodeJS & Express。如下是该项目的主要工程目录结构。

    • client(前端工程目录)—— 可执行命令

      • npm run serve:开发环境下启动项目(本地)
      • npm run build:生产环境下打包代码(打包结果的存放路径为:/server/public/
    • server(后端工程目录)—— 可执行命令

      • npm run server:开发环境下启动项目(本地)

      当访问对应的 URL 地址时,该后端工程会进入/server/public/目录获取对应的前端页面及静态资源。

      使用 GitHub Actions 自动化部署 全栈个人博客项目

2. 开始部署

注意:

  • 期望效果:每次开发完毕后,我们只需要将整个“前后端”项目push到GitHub,项目就会被自动化部署到服务器。
  • 基础前提:已预先将项目成功托管到了GitHub上,并且此前已经手动地完成了服务器端的首次部署(即保证在服务器端已搭建好项目所需的运行环境)。则可继续如下步骤。

新建 .yml 文件

  1. 进入GitHub上的对应仓库,点击“Actions”以进入“GitHub Actions”开始页,接着点击“setup a workflow your self”以新建默认的yaml文件。

    使用 GitHub Actions 自动化部署 全栈个人博客项目

  2. 点击“Start commit”按钮,在弹出框中输入自定义的commit信息,并点击“Commit new file”按钮以提交上述操作。

    使用 GitHub Actions 自动化部署 全栈个人博客项目

  3. 上述步骤完成之后,一方面,可发现该项目的根目录下新增了一个.github/workflows目录,其中存放着一个main.yaml配置文件;另一方面,可发现现在已经成功执行了一次工作流程(如下图所示)。

    使用 GitHub Actions 自动化部署 全栈个人博客项目

    使用 GitHub Actions 自动化部署 全栈个人博客项目

  4. 此时,已经成功地在GitHub上的项目工程目录中创建好了yaml文件。然后,在本地执行一次git pull命令以同步远程main分支的最新代码,即可在本地通过 VSCode 编辑器查看并配置 main.yml 文件的内容。main.yml 文件的初始内容如下:

    # This is a basic workflow to help you get started with Actions
    name: CI
    
    # Controls when the workflow will run
    on:
      # Triggers the workflow on push or pull request events but only for the "main" branch
      push:
        branches: [ "main" ]
      pull_request:
        branches: [ "main" ]
    
      # Allows you to run this workflow manually from the Actions tab
      workflow_dispatch:
    
    # A workflow run is made up of one or more jobs that can run sequentially or in parallel
    jobs:
      # This workflow contains a single job called "build"
      build:
        # The type of runner that the job will run on
        runs-on: ubuntu-latest
    
        # Steps represent a sequence of tasks that will be executed as part of the job
        steps:
          # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
          - uses: actions/checkout@v3
    
          # Runs a single command using the runners shell
          - name: Run a one-line script
            run: echo Hello, world!
    
          # Runs a set of commands using the runners shell
          - name: Run a multi-line script
            run: |
              echo Add other actions to build,
              echo test, and deploy your project.
    

    阅读上述默认文件内容时,记得参照上文所讲的相关概念及语法。相信你一定可以理解的!!!

配置 .yml 文件

话不多说,完整的配置内容如下:

name: Auto Deploy # 当前工作流程的名称
on: 
  push: 
    branches: 
      - main # 只要push到main分支,就会触发该工作流程
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      # 使用别人封装好的的action,用于clone该仓库的源码到工作流中
      - name: Checkout
        uses: actions/checkout@v3

      # 在工作流中安装node环境(必需,这样才能在后续工作流程中运行 npm install 等指令,否则会报错)
      - name: Setup node
        uses: actions/setup-node@v3
        with:
          node-version: 16 # 指定node版本
          
      # 打包代码生成环境
      - name: Build
        run: |
          cd client # 进入前端侧的工程目录
          npm install # 安装依赖
          npm run build # 打包前端代码到生产环境(目标路径为:server/public)

      # 同步server目录下的后端代码到服务器(目标路径:/home/nginx/myBlogServer)
      - name: Deploy
        uses: cross-the-world/scp-pipeline@master
        with:
          host: ${{ secrets.MY_HOST }} # 服务器IP(需要在GitHub上自行配置对应的secret)
          user: ${{ secrets.MY_USER }} # 服务器用户名
          pass: ${{ secrets.MY_PASS }} # 服务器密码
          connect_timeout: 10s
          local: './server/*' # 源路径(工作流)
          remote: /home/nginx/myBlogServer # 目标路径(服务器)
      
      # 在服务器端执行相关指令
      - name: Executing remote ssh commands
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.MY_HOST }} # 服务器IP(需要在GitHub上自行配置对应的secret)
          username: ${{ secrets.MY_USER }} # 服务器用户名
          password: ${{ secrets.MY_PASS }} # 服务器密码
          script: |
            cd /home/nginx/myBlogServer # 进入服务器中的端工程所在的目录
            export NODE_HOME=/root/.nvm/versions/node/v12.19.0  # 可使用`whereis node`查询node所在的目录
            export PATH=$PATH:$NODE_HOME/bin # 重新定义node的环境变量(必需,这样才能在后续工作流程中运行 npm install 等指令,否则会报错)
            npm install # 安装项目依赖
            pm2 delete myBlogServer # 删除旧的进程
            pm2 start --name myBlogServer npm -- run server # 启动新的进程

上述代码中所用的第三方Actions,在 Actions 市场 都可以找到使用文档,如:cross-the-world/scp-pipeline@masterappleboy/ssh-action@master 等。

上述配置的整体思路为:

  • 监听main分支的push事件,当上述事件被触发(即本地向远程仓库的main分支push最新代码时)时,运行名为"Auto Deploy"的工作流程。

  • 该工作流程中有一个名为“build-and-deploy”的任务,且该任务运行在“ubuntu-latest”虚拟环境下。通过依次执行其包含的多个步骤,可实现整个自动化部署功能。

    • 使用actions/checkout@v3将对应仓库的源码克隆到当前工作流中

    • 使用actions/setup-node@v3在工作流中安装node环境(必需运行该步骤,这样当前工作流的后续步骤才可以运行npm install等指令,否则会报错)

    • 从根目录进入到前端工程目录client,安装项目依赖,并将前端代码打包到“后端工程目录client”中的public文件夹中(后续,该后端工程在服务器本地启动之后,便会按早预期从public文件夹下获取到最新的前端页面及静态资源)

    • 使用cross-the-world/scp-pipeline@master将“后端工程目录client”中的所有内容通过scp传输到服务器端的指定路径下

    • 使用appleboy/ssh-action@master在服务器端执行一系列指令操作:

      • 进入上述后端工程所在路径

      • 重新定义node的环境变量(防止后续执行 npm 指令时报错)

      • 安装项目依赖

      • 执行pm2 delete myBlogServer指令删除旧的进程(myBlogServer为旧版项目启动时的进程名)

      • 执行pm2 start --name myBlogServer npm -- run server指令启动新的进程(myBlogServer为新版项目启动时的进程名,必须与旧版的保持一致)

        此时,当前工作流程结束,项目将会成功地重新部署 ~~~

配置 GitHub Secrets

出于安全考虑,在配置 yaml 文件的内容时,我们并没有直接将服务器的 IP、服务器的用户名、服务器的密码等信息直接写在文件中,而是需要从 GitHub 的 secrets 中读取。那么,GitHub secrets 的配置方法如下:

  1. 点击“Settings”进入设置页,点击左侧菜单栏的“Secrets --- Actions”菜单项进入 secret 添加页,点击右上角的“New repository secret”按钮,即可添加自定义的 secret。

    使用 GitHub Actions 自动化部署 全栈个人博客项目

  2. 按照下图提示配置自定义的 secret,并点击“Add secret”按钮确定添加。

    使用 GitHub Actions 自动化部署 全栈个人博客项目

    添加成功后,就可以看到如下结果。

    使用 GitHub Actions 自动化部署 全栈个人博客项目

功能测试

完成上述步骤之后,我们便可以在本地修改项目源码,并推送到GitHub的远程main分支,以测试上述“GitHub Actions”配置是否生效。

当我们push成功之后,对应的actions便会被自动运行,帮助我们自动化重新部署项目。可在GitHub的UI界面中查看其运行情况。

使用 GitHub Actions 自动化部署 全栈个人博客项目

使用 GitHub Actions 自动化部署 全栈个人博客项目

使用 GitHub Actions 自动化部署 全栈个人博客项目

如果部署成功之后,会出现以下结果。

使用 GitHub Actions 自动化部署 全栈个人博客项目

使用 GitHub Actions 自动化部署 全栈个人博客项目

如果部署失败,会在对应工作流程运行的详情页中输出详细的报错信息,可以根据报错信息定位问题所在并解决。

总结

以上便是本文的全部内容,相信你已经能够让自己的项目实现“GitHub Actions”自动化部署啦!若有疑问,欢迎在评论区交流!!!

参考文档

PS:本文内容仅供交流学习,转载请注明出处。

转载自:https://juejin.cn/post/7110472489007841311
评论
请登录