# 背景
有一个 monorepo 微前端项目,需要一次构建3个项目,放在根目录下的packages文件夹下,分别是rdm、rdm-old、rdm-new,在测试分支打包,分别生成自己的 dist/test,正式服则是 dist/prod,正式服构建到 A 服务器的 rdm、rdm-old、rdm-new 文件夹,测试服到 B 服务器的 rdm、rdm-old、rdm-new 文件夹。现在,我们希望在一次CI/CD流程中构建并部署多个子应用(rdm, rdm-new, rdm-old),同时这些应用需要被部署到不同服务器上的不同的 FTP 目录。
用直观的方式呈现如下图:
# 方案
为了实现这个需求,我们可以在.gitlab-ci.yml
文件中设置一个共同的构建阶段,然后针对不同的环境(测试服和正式服)和不同的子应用设置不同的部署阶段。
# 配置 gitlab-ci.yml
# 定义CI/CD的阶段
stages:
- build # 构建阶段
- deploy # 部署阶段
# 定义一些全局变量,用于SSH连接和部署
variables:
SSH_USER: "用户名"
SSH_PASSWORD: "用户密码"
SSH_OPTIONS: "-o StrictHostKeyChecking=no"
# 定义一个模板,用于SSH部署
.deploy_template: &deploy_template
stage: deploy
script:
- echo "Deploying to $TARGET_SERVER in $DEPLOY_PATH"
- sshpass -p "$SSH_PASSWORD" ssh $SSH_USER@$TARGET_SERVER "mkdir -p $DEPLOY_PATH"
- sshpass -p "$SSH_PASSWORD" scp -r $SSH_OPTIONS ./dist/$DEPLOY_TYPE/* $SSH_USER@$TARGET_SERVER:$DEPLOY_PATH
# RDM 构建和部署
rdm-build:
stage: build
script: # 构建脚本
- cd packages/rdm
- pnpm install
- pnpm run build:$CI_COMMIT_REF_NAME # 假设你有一个脚本来根据分支构建到不同的目录
- | # 使用管道符来在单行中写多条命令,如果是主分支,将dist目录重命名为dist/prod
if [ "$CI_COMMIT_REF_NAME" == "main" ]; then
mv dist dist/prod
else
mv dist dist/test
fi
artifacts: # 指定要保留的构建产物
paths:
- packages/rdm/dist/prod/ # 如果需要包含主分支的产出
- packages/rdm/dist/test/ # 如果需要包含非主分支的产出
rdm-deploy-prod:
<<: *deploy_template
variables: # 覆盖模板中的变量
TARGET_SERVER: "正式服-服务器 A 地址"
DEPLOY_PATH: "/rdm" # 部署路径
DEPLOY_TYPE: "prod" # 部署类型
only: # 仅当提交到prod分支时运行
- prod
rdm-deploy-test:
<<: *deploy_template
variables:
TARGET_SERVER: "测试服-服务器 B 地址"
DEPLOY_PATH: "/rdm"
DEPLOY_TYPE: "test"
except:
- main
# RDM-OLD
rdm-old-build:
stage: build
script:
- cd packages/rdm-old
- pnpm install
- pnpm run build:$CI_COMMIT_REF_NAME # 假设你有一个脚本来根据分支构建到不同的目录
- | # 使用管道符来在单行中写多条命令
if [ "$CI_COMMIT_REF_NAME" == "main" ]; then
mv dist dist/prod
else
mv dist dist/test
fi
artifacts:
paths:
- packages/rdm-old/dist/prod/ # 如果需要包含主分支的产出
- packages/rdm-old/dist/test/ # 如果需要包含非主分支的产出
rdm-old-deploy-prod:
<<: *deploy_template
variables:
TARGET_SERVER: "正式服-服务器 A 地址"
DEPLOY_PATH: "/rdm-old"
DEPLOY_TYPE: "prod"
only:
- prod
rdm-old-deploy-test:
<<: *deploy_template
variables:
TARGET_SERVER: "测试服-服务器 B 地址"
DEPLOY_PATH: "/rdm-old"
DEPLOY_TYPE: "test"
except:
- main
# RDM-NEW
rdm-new-build:
stage: build
script:
- cd packages/rdm-new
- pnpm install
- pnpm run build:$CI_COMMIT_REF_NAME # 假设这个脚本会根据分支名称构建到不同的目录,但实际上它不会改变dist的目录名
- | # 使用管道符来在单行中写多条命令
if [ "$CI_COMMIT_REF_NAME" == "main" ]; then
mv dist dist/prod
else
mv dist dist/test
fi
artifacts:
paths:
- packages/rdm-new/dist/prod/ # 如果需要包含主分支的产出
- packages/rdm-new/dist/test/ # 如果需要包含非主分支的产出
rdm-new-deploy-prod:
<<: *deploy_template
variables:
TARGET_SERVER: "正式服-服务器 A 地址"
DEPLOY_PATH: "/rdm-new"
DEPLOY_TYPE: "prod"
only:
- prod
rdm-new-deploy-test:
<<: *deploy_template
variables:
TARGET_SERVER: "测试服-服务器 B 地址"
DEPLOY_PATH: "/rdm-new"
DEPLOY_TYPE: "test"
except:
- main
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132