# CI&CD

做自动化部署可以分为本地部署和 Jenkins 部署。

公司的源码是放在 Gitlab 上,测试那边使用 Jenkins 做的 CI。下面先介绍怎么完成本地推送代码到 Gitlab 后自动触发 Jenkins 完成构建部署。

# Jenkins

Jenkins 上创建基本的构建任务这里就不说了,主要讲怎么配置触发器和 Gitlab 配合完成自动构建。

Jenkins 上构建触发器有很多种方式,如果安装了 Gitlab Plugin 可以选择这个选项。如果没有安装,可以选择触发远程构建选项。这两个本质都是提供一个 webhook 的 url 给到外部,可以直接通过访问这个 url 触发 Jenkins 的构建。

这里选择触发远程构建来实现, token 设置为 luckypanda-front,JENKINS_URL 是 Jenkins 服务的地址。通过浏览器输入 JENKINS_URL/view/Front/job/LUCKY-PANDA-FRONT/build?token=luckypanda-front 可以测试是否能触发 Jenkins 构建

JENKINS_URL/view/Front/job/LUCKY-PANDA-FRONT/build?token=luckypanda-front

1
2

接下来配置 Gitlab

# Gitlab

Gitlab 支持自定义 webhook,在项目/settings/Integrations 里创建一个 webhook, URL 就填写上 Jenkins 上设置的。

点击 addWebhook。添加成功后可以测试一下连通性。如果不行,可能是 Jenkins 配置问题,需要给匿名用户添加 build 权限。

# 本质

各种 CI 工具实现 Git 提交自动部署本质上都是利用了 Git hooks 的特性。Git 代码仓库是一个裸库,通过自定义 hooks 实现执行不同 events 时执行对应的 hooks 脚本,hooks 脚本对远程 CI 服务器发起请求,完成自动化构建任务。

# 本地的 deploy 脚本

首先可以使用 scipty 扩展项目脚本,在.sh 文件中我们可以写如下的部署命令。 由于服务器可能没有权限配置免密,使用的是 sshpass 来输入密码。这里需要注意的一个问题是,! 是个特殊字符,如果密码中包含这个字符就需要做转义处理,否则执行会报错。另外,本地脚本执行 rm 命令时尤其需要注意,尽量写绝对路径,不要写相对路径,如果对 shell 脚本不熟悉,很有可能写出来的变量为空的情况,而如果是 root 权限的话,会导致 remove 掉服务器所有的内容,这是致命的。

#!/usr/bin/env sh

#抛出遇到的错误
set -e

cur_date="`date +%Y-%m-%d`"
echo $cur_date
server_file="server-${cur_date}.tar.gz"
client_file="client-${cur_date}.tar.gz"

if [ ! -f $server_file ];then
  echo "$server_file 文件不存在"
else
  echo "删除$server_file"
  rm -f $server_file
fi


if [ ! -f $client_file ];then
  echo "$client_file 文件不存在"
else
  echo "删除$client_file"
  rm -f $client_file
fi


echo "开始构建${pwd}"

npm run build:test

echo "打包完成"
echo "开始压缩"

tar -zcvf $server_file -C ./dist .
tar -zcvf $client_file -C ./dist/assets .

echo "压缩完成,开始上传服务器"
server_host="root@192.168.0.221"
server_port="22"
server_dist="/scss/LuckyPanda"
server_pwd="********"

client_host="wtttest@192.168.0.154"
client_port="22"
client_dist="/images/lpn-front/assets"
client_pwd="********"

# 检查服务器目录是否存在
sshpass -p "$server_pwd" ssh -p $server_port $server_host "mkdir -p $server_dist/"

sshpass -p "$client_pwd" ssh -p $client_port $client_host "mkdir -p $client_dist/"

# 上传
sshpass -p "$server_pwd" scp -P $server_port $server_file $server_host:$server_dist/

sshpass -p "$client_pwd" scp -P $client_port $client_file $client_host:$client_dist/

echo "资源上传成功,开始部署"

sshpass -p "$server_pwd"  ssh -p $server_port $server_host "tar -xvf $server_dist/$server_file -C $server_dist/"

sshpass -p "$client_pwd" ssh -p $client_port $client_host "tar -xzf $client_dist/$client_file -C $client_dist/"

sshpass -p "$server_pwd" ssh -p $server_port $server_host "rm  $server_dist/$server_file"

sshpass -p "$client_pwd" ssh -p $client_port $client_host "rm  $client_dist/$client_file"


# 安装服务端依赖
# sshpass -p "$server_pwd" ssh -p $server_port $server_host "cd $server_dist/; npm install;"

# 重启服务
sshpass -p "$server_pwd" ssh -p $server_port $server_host " cd $server_dist/; pm2 restart pm2.json"



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
最后更新时间: 1/28/2021, 1:30:19 PM