赞
踩
最近有在陆续地为自己的“全栈个人博客网站”增添一些新的功能,但每次开发完毕后都需要手动地将整个项目重新部署到服务器,且该过程十分繁琐。诸如:将前端代码打包到指定路径(生产环境);在本地压缩代码并上传到服务器;在服务器解压代码并移动到指定路径;进入工程文件夹并安装项目依赖;执行指令以重新运行项目等。部署成功之后,如果发现某些被漏掉的BUG,则要继续重复上述流程,繁琐至极。
那么,有没有什么办法能够将上述重新部署的流程自动化呢?
当然有,而且有很多方法!由于该项目是托管到GitHub上的,因此采用“GitHub Actions”方案来实现。最终效果为:每次开发完毕后,我们只需要将整个“前后端”项目push到GitHub,项目就会被自动化部署到服务器。
Workflow(工作流)
即工作流程,是一个可配置的自动化过程,它将运行一个或多个任务。 工作流程由工程根目录/.github/workflows
路径下的 YAML 文件定义,在该文件中我们可以监听某些事件,当事件被触发后则会进入到对应的工作流程。
Job(任务)
一个工作流程中包含一个或多个任务,一个任务由若干个步骤组成。
Step(步骤)
一个任务可以包含一个或多个步骤,且上述步骤会被依次执行。
Action(动作)
每个步骤可以包含一个或多个动作,诸如一些实际的指令(npm install
等)。
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
要等待 job1
和 job2
完成。最终运行顺序为:job1
、job2
、job3
。
jobs.<job_id>.runs-on
该字段用来指定任务将在哪个虚拟环境中运行。如果使用 GitHub 托管的运行器,每个作业将在 runs-on
指定的虚拟环境的新实例中运行。
runs-on: ubuntu-latest
可用的 GitHub 托管的运行器类型包括:
虚拟环境
-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
项目预览:http://hechunxu.tech
项目描述:即“全栈个人博客网站”,前端使用 Vue2.x,后端使用 NodeJS & Express。如下是该项目的主要工程目录结构。
client(前端工程目录)—— 可执行命令
npm run serve
:开发环境下启动项目(本地)npm run build
:生产环境下打包代码(打包结果的存放路径为:/server/public/
)server(后端工程目录)—— 可执行命令
npm run server
:开发环境下启动项目(本地)当访问对应的 URL 地址时,该后端工程会进入
/server/public/
目录获取对应的前端页面及静态资源。
注意:
- 期望效果:每次开发完毕后,我们只需要将整个“前后端”项目push到GitHub,项目就会被自动化部署到服务器。
- 基础前提:已预先将项目成功托管到了GitHub上,并且此前已经手动地完成了服务器端的首次部署(即保证在服务器端已搭建好项目所需的运行环境)。则可继续如下步骤。
进入GitHub上的对应仓库,点击“Actions”以进入“GitHub Actions”开始页,接着点击“setup a workflow your self”以新建默认的yaml文件。
点击“Start commit”按钮,在弹出框中输入自定义的commit信息,并点击“Commit new file”按钮以提交上述操作。
上述步骤完成之后,一方面,可发现该项目的根目录下新增了一个.github/workflows
目录,其中存放着一个main.yaml
配置文件;另一方面,可发现现在已经成功执行了一次工作流程(如下图所示)。
此时,已经成功地在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.
阅读上述默认文件内容时,记得参照上文所讲的相关概念及语法。相信你一定可以理解的!!!
话不多说,完整的配置内容如下:
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@master、appleboy/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
为新版项目启动时的进程名,必须与旧版的保持一致)
此时,当前工作流程结束,项目将会成功地重新部署 ~~~
出于安全考虑,在配置 yaml 文件的内容时,我们并没有直接将服务器的 IP、服务器的用户名、服务器的密码等信息直接写在文件中,而是需要从 GitHub 的 secrets 中读取。那么,GitHub secrets 的配置方法如下:
点击“Settings”进入设置页,点击左侧菜单栏的“Secrets — Actions”菜单项进入 secret 添加页,点击右上角的“New repository secret”按钮,即可添加自定义的 secret。
按照下图提示配置自定义的 secret,并点击“Add secret”按钮确定添加。
添加成功后,就可以看到如下结果。
完成上述步骤之后,我们便可以在本地修改项目源码,并推送到GitHub的远程main分支,以测试上述“GitHub Actions”配置是否生效。
当我们push成功之后,对应的actions便会被自动运行,帮助我们自动化重新部署项目。可在GitHub的UI界面中查看其运行情况。
如果部署成功之后,会出现以下结果。
如果部署失败,会在对应工作流程运行的详情页中输出详细的报错信息,可以根据报错信息定位问题所在并解决。
以上便是本文的全部内容,相信你已经能够让自己的项目实现“GitHub Actions”自动化部署啦!若有疑问,欢迎在评论区交流!!!
PS:本文内容仅供交流学习,转载请注明出处。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。