前言
公司一直用的 GitLab 管理代码,同时也配了 CICD, 每次开发完提交代码到远程仓库,就会触发自动部署,等个几分钟就能在研发环境或者测试环境看到部署完成的项目,非常的方便。请教了一下团队中负责 CI/CD 的同事,看完大佬写的文章后深有感触,于是乎决定将自己平时开发的 记账本app 项目也加上自动化部署。
最开始使用自己的服务器搭建 GitLab,结果性能太差,服务器直接宕机...无奈,那我就用 GitHub Actions 完成了自动化部署。
在看本文前,我们先了解一下几个概念
CI/CD
CI - 持续集成(Continuous Integration)
CD - 持续交付 (Continuous Delivery)
CD - 持续部署 (Continuous Deployment)
Devops
DevOps维基百科定义DevOps(Development和Operations的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。
概述
看完本文你会学到什么?
- GitHub CI CD
- GitHub Actions
- 自动化部署方案
接下里我将分别讲述 手动部署、脚本部署、 Github Action 部署,一步步带你了解自动化。
手动部署
没有自动化部署前,我们是怎样部署前端项目的呢?
- 打包代码 (例如:npm run build)
- 打开 FTP 工具 (例如:FileZilla),
- 登录到服务器
- 找到对应的服务器前端静态目录以及本地目录
- 上传文件
没有自动化部署的项目部署流程往往复杂繁琐。那么能不能通过一个脚本自动执行以上所有操作呢,当然可以,万能的 shell 脚本总能帮你解决各种问题。
脚本部署
首先创建一个 scripts/release.sh 文件。脚本内容也很简单:
#!/usr/bin/bash
# 本地路径
DIST=dist
# 服务器地址
SERVER_HOST=119.29.19.xxx
# 服务器路径
TARGET_DIST=/www/wwwroot/
# 打包完,上传到服务器
npm run build && \
scp -r ./$DIST/* root@$SERVER_HOST:$TARGET_DIST
此时,我们只要执行 sh scripts/release.sh,就能完成部署。为了更方便,我们可以把这个命令执行放到 package.json 文件中。
接下来,我们在 package.json 中加入一条命令
{
"scripts": {
"release": "sh scripts/release.sh"
},
}
需要部署时我们间接执行一下 npm run release 就能完成部署,是不是变得简单很多。通过上诉的方法,以此类推,我们还能够写出多种多样的 shell 脚本帮助我们自动化完成更多的事情,你会发现很多大型仓库里都在用这种自动化的方式,例如 Element,感兴趣的同学可以去看看。
有心的同学发现使用上面的 scripts/release.sh 脚本部署有一个问题,就是每次部署都需要输入密码。但是我们直接将密码写到 shell 脚本中又觉得不太安全。还有就是写脚本自动化流程写脚本也很麻烦,有没有共享的脚本,配置参数就能用,那岂不是美哉!
针对上面的问题,等我们学完下面的 GitHub Actions 就变得豁然开朗。
Github Actions 部署
什么是 Github Actions? 它是一个持续集成和持续交付(CI/CD)平台。 那么它是怎么实现自动化呢?在上面的脚本部署中,我们是需要手动执行 npm run release ,而在 Github Actions 中会提供一些钩子,检测到仓库某个特定活动触发,就会执行这些脚本, GitHub 把这些触发钩子称为事件,这些脚本称为 actions,同时,官方也提供了一个类似 npm.cn 这样的公共市场,在这里面你可以搜到别人提交的 actions,这样你就可以很方便复用别人写的脚本。
基本概念
- workflow(工作流程):指整个持续集成的流程,包含执行脚本任务、执行触发事件等
- Events (事件):触发流程的钩子,例如提交代码触发,新建 Issues 触发等等。
- Jobs (任务):每一个工作流程包含一个或多个任务,任务按顺序执行,每一个任务都会执行 shell 脚本。
- Steps (步骤):每一个
Job包含一个或多个Step, Step 按顺序执行。 - Actions(动作): 每一个
Step包含一个或多个Action, 按顺序执行。 - Runners(执行环境):
workflow运行时的服务器,每一个Runner可以运行一个Job.
这里的
Runners多说两句,是相当不错,可以简单理解为 GitHub 给你提供了一个虚拟机,在上面执行各种 shell 脚本。为什么说不错呢,两个点:
1、白嫖的服务器,配置还不错。买过服务器的小伙伴大概都知道,这配置搁哪个云服务器厂商费用不得几千一年。
2、前端直接使用npm install,根本不需要cnpm的类似代理。可能是因为服务器本身就是在国外吧。
Runner 可选环境以及硬件配置
编写 workflow 文件
workflow 文件采用的是 YAML 语言编写,如果你还不了解,可以先看看 YAML 语言教程。
- 创建一个 github 仓库
- 在仓库里
.github/workflows/目录下创建一个 release.yml
name: release
on: [push] # 仓库提交时触发
jobs:
release-job: # 发布任务
runs-on: ubuntu-latest # 运行系统环境
steps: # 步骤
- uses: actions/checkout@v2 # 使用公共的 action
- uses: actions/setup-node@v2
with:
node-version: '14'
- run: echo '发布' # shell 脚本
上面代码中,name 为 workflow 名称,on 指定了触发事件,jobs 下面我们自定义了一个 release-job 任务,任务指定了运行环境是 ubuntu, 同时,任务的执行步骤,第一个 uses 表示使用公共 actions/checkout@v2 签出代码,这一步就相当于把 github 仓库的代码拉到当前环境磁盘中,第二个 uses 表示在当前环境安装 nodejs 同时使用 with 指定了 node 版本,最后使用 run 执行自定义 shell 脚本。
- 提交文件到远程仓库
接下来你就可以在仓库的 Actions 选项卡下面看到刚刚触发的流程日志。
实战-使用 Github Actions 部署前端项目到腾讯云
- 编写 workflow 文件(建议直接在 github.com 仓库在线编辑,编辑时右侧会有一些建议 action 和编写文档参考)。
在 .github/workflows 下新建release.yml 文件。
name: release
on:
push:
branches: master # master 分支提交时触发
jobs:
build:
runs-on: ubuntu-latest # 运行环境
steps:
- name: 签出代码
uses: actions/checkout@master
- name: 安装 nodejs
uses: actions/setup-node@v2
with:
node-version: "14"
- name: 安装依赖
run: npm install
working-directory: client-vue/mobile # working-directory 指定 shell 命令运行目录
- name: 前端项目打包
run: npm run build
working-directory: client-vue/mobile
- name: 发布腾讯云
uses: wlixcc/SFTP-Deploy-Action@v1.0 # 使用 SFTP 协议上传到腾讯云
with:
username: 'root'
server: '${{ secrets.TENCENT_SERVER_HOST }}'
ssh_private_key: '${{ secrets.TENCENT_SERVER_PRIVATE_KEY }}'
local_path: 'client-vue/mobile/dist/*'
remote_path: '/www/wwwroot/www.ailan.top/'
args: "-o ConnectTimeout=5"
上面 yam 文件根据 name 和备注大家应该都大部分都能看懂,这里重点说一下最后一个 step(发布到腾讯云)
- name: 发布腾讯云
uses: wlixcc/SFTP-Deploy-Action@v1.0 # 使用 SFTP 协议上传到腾讯云
with:
username: 'root'
server: '${{ secrets.TENCENT_SERVER_HOST }}'
ssh_private_key: '${{ secrets.TENCENT_SERVER_PRIVATE_KEY }}'
local_path: 'client-vue/mobile/dist/*'
remote_path: '/www/wwwroot/xxx/'
args: "-o ConnectTimeout=5"
uses: wlixcc/SFTP-Deploy-Action@v1.0:
这里使用的一个第三方 actions, 只有actions/开头的才表示官方的 actions, 后面单独会教大家如何搜索和复用 action。
with::
表示咱们引用的这个 actions 需要的那些参数。参数可以去看该 actions 的文档。
server: '${{ secrets.TENCENT_SERVER_HOST }}':
secrets是什么?secrets 是 GitHub 的一个加密仓库,在下图的位置管理,这样我们就可以把服务器地址、密码等比较敏感的内容放在 secrets 里管理,在 release.yml 文件中,我们可以使用${{ secrets.TENCENT_SERVER_HOST }}引用。
上面配置文件中还有一个 ssh_private_key,需要注意一下,首先需要在自己的云服务上生成的一个 ssh key, 私钥存在 secrets 里,公钥存在 GitHub 设置的 SSH Keys 中。
更多的 GitHub Actions 语法可以看官方文档。
如何找到适合的 actions ?
首先我们需要了解,actions 可以放在代码仓库里,如 actions/checkout@master 完整路径表示 https://github.com/actions/checkout, @master 表示的是 master 分支。放在代码仓库有一个好处就是我们可以指定版本,例如固定使用某个版本:actions/setup-node@v2, v2 代表的 tag,当然 @ 后面还可以跟 commit ID。
通过下面两个地方可以快速找到合适的 actions:
awesome-actions
A curated list of awesome actions to use on GitHub
总结
纵观近几年,整个软件开发运作流程发生了一些变化,从刚开始的 敏捷开发到如今的 Devops,再到当下热门的 AIOps。这是一个趋势,所以在这个大环境背景下,多学习一点相关的知识只会百里无一害,技多不压身。
本文提到的 GitHub CI/CD 只是 Devops 某一个环境的简单的应用。其他替代的应用场景还有很多,例如 GitLab CI/CD;Saas 化的自动化运维平台,例如腾讯的蓝鲸智云。
终究的目的只有一个:提效、解放劳动力。
让应用交付从人工到自动化的转变,在提升企业应用交付效率的同时,输出运维价值。