对应增量更新部署,网上有很多方案,比如:

jenkins高级篇 pipeline 系列之-—06 实现自动打增量包 - 雨 燕 - 博客园

Shell脚本结合Git实现增量项目部署 - 掘金

结合网上的方案以及公司项目架构,我最后采用简单的shell脚本方式来实现。这里记录脚本:

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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#! /bin/bash


# 开始版本号
start_revision=
# 截止版本号
end_revision=
# 工程目录
project_path=
# 增量文件输出目录
out_path=$PWD


# 忽略文件后缀
ignoreFile="sql,sh,groovy,gdsl"


# 忽略的路径(需填写相对应工程目录的相关路径)
ignorePath="config/,doc/,logs/,tools/,shell/"


#
# 生成class文件所在路径(相对应工程目录)
default_target_paths=target/classes


# class需要包括复制到目标目录
default_webInfo_classes_paths=WEB-INF/classes


# 静态文件目录
default_content_paths=WebContent


# java文件后缀名
default_java_file=java




readme="工具描述:比较svn两个revision版本的差异,自动把差异的文件和文件路径拷贝到指定目录。
参数列表:
-p (必选:有参数) 工程目录,运行svn命令和文件拷贝的目录。注意,必须在本地已通过svn获取到工程代码
-s (必选:有参数) svn revision 的开始版本号。注意,截止版本号默认为-p参数路径下的revision版本号,请确保路径正确且已更新最新代码。
-e (可选:有参数) svn revision 的截止版本号。可不填,不填默认为最新版本号
-o (可选:有参数) 文件拷贝的输出目录,会自动在该目标目录下创建时间戳临时目录,若不填,则默认在当前目录输出。
-i (可选:有参数) 表示需要忽略的文件后缀,多个后缀之间用逗号隔开。不填默认为sql,sh,groovy,gdsl
-t (可选:有参数) 表示需要忽略的路径,多个路径之间用逗号隔开,这里的路径是相对与工程目录的路径。不填默认为config/,doc/,logs
-j (可选:无参数) 是否要保存原始差异文件(非编译后的class文件,为了后面jacoco做准备),默认不报存
-h 帮助说明


示例:
./vnDiffAndCopyFile.sh -p /Users/wangxin/Documents/CODE/Innotek/SPMS/NewSpms -s 10520
"


# 获取最新的svn版本
getSvnEndRevision(){
if [ ! ${end_revision} ]; then
end_revision=$(cd $1; svn info --show-item revision)
fi
}




while getopts "p:s:o:e:i:jh" arg #选项后面的冒号表示该选项需要参数
do
case $arg in
s)
start_revision=$OPTARG
;;
p) #参数存在$OPTARG中
project_path=$OPTARG
if [ ! -d "${project_path}" ]; then
echo "错误:工程路径不存在(${project_path})"
exit 1
fi
getSvnEndRevision ${project_path}
;;
o)
out_path=$OPTARG
if [ ! -d "${out_path}" ]; then
echo "错误:目标路径不存在(${out_path})"
exit 1
fi
;;
e)
end_revision=$OPTARG
;;
i)
ignoreFile=$OPTARG
;;
t)
ignorePath=$OPTARG
;;
j)
# 是否保存java文件
isSaveJava=true
;;
h)
echo "${readme}"
exit 1
;;
?) #当有不认识的选项的时候arg为?
echo "参数错误 如需帮助请输入参数 -h"
exit 1
;;
esac
done


if [ ! ${start_revision} ]; then
echo "错误:起始版本号未输入! 请输入 -s 参数. 示例可见 -h 参数"
exit 1
fi


if [ ! ${project_path} ]; then
echo "错误:工程目录未输入! 请输入 -p 参数指定具体工程目录. 示例可见 -h 参数"
exit 1
fi


if [ ! $(grep '^[[:digit:]]*$' <<< "${start_revision}") ]; then
echo "起始版本号不能为非数字:${start_revision}"
exit 1
fi


if [ ! $(grep '^[[:digit:]]*$' <<< "${end_revision}") ]; then
echo "结束版本号不能为非数字:${end_revision}"
exit 1
fi


# 进行svndiff操作
echo "起始版本号:${start_revision}"
echo "截止版本号:${end_revision}"
if [ ${start_revision} -ge ${end_revision} ]; then
echo "结果:版本无差异!"
exit 1
fi


# ------ 把差异的文件复制到相应文件夹中 ------


# 切换到工程目录
cd ${project_path}


# 获取diff文件列表
# 如果有需要忽略的后缀文件,则先忽略到该后缀名的文件
if [ ! ${ignoreFile} ]; then
# 起始版本号减1,为了包含该版本号
temp_files=$(svn diff -r$(( start_revision-1 )):${end_revision} | grep Index: | sed -E 's#Index: ##g')
#temp_files=$(svn diff -r${start_revision}:${end_revision} --summarize --no-auth-cache | awk '{print $2}s') # 该命令会输出提交的文件夹路径(不采纳)


else
# 把过滤的文件去除
ignoreFile=$(echo "${ignoreFile}" | sed -E 's#,#|#g') # ,换成|
temp_files=$(svn diff -r$(( start_revision-1 )):${end_revision} | grep Index: | sed -E 's#Index: ##g' | grep -E -v "(${ignoreFile})$" )
fi


# 过滤掉目录下的所有文件
if [ ${ignorePath} ]; then
ignorePath=$(echo "${ignorePath}" | sed -E 's#,#|#g') # ,换成|
temp_files=$(echo "${temp_files}" | grep -E -v "^(${ignorePath})")
fi


# 增量文件复制
cd $out_path
pathName=$(date "+%Y%m%d%H%M%S") # 目录起始名


# 是否要保存java文件
if [ ${isSaveJava} ]; then
# 读取每一行,创建目录,统一放在for_java目录下
# PS: echo 后的变量尽量加引号,不加引号不会变量里的字符串的换行符换成空格
echo "${temp_files}" | while read line; do mkdir -p ${pathName}/for_java/$(dirname $line);done

# 复制差异文件(原始文件)
cd ${project_path}
echo "${temp_files}" | while read line; do cp -af ${line} ${out_path}/${pathName}/for_java/$(dirname $line);done
fi


# ------ 开始保存增量文件(class文件和其他静态文件) ------
echo "${temp_files}" | while read line
do
#src_path=${line%/*}
file_name=${line##*/} # test.txt
file_type=${file_name##*.} # txt
file_class_name=${file_name%.*} # test


first_path_name=${line%%/*} # src
echo "${first_path_name}"
if [ "${first_path_name}" = "src" ]; then
file_target_src_path=$(echo ${line} | awk -F 'src/' '{print $2}') # 去掉"src/"后,保留右边的文件路径
dir_target_src_path=$(dirname $file_target_src_path) # 去掉文件名的路径
cd ${out_path}
mkdir -p ${pathName}/for_build/${default_webInfo_classes_paths}/${dir_target_src_path}

if [[ ${file_type} = ${default_java_file} ]]; then
# 如果是java文件,则需从target目录下拷贝class文件到目标目录
cd ${project_path}
# 这里使用*通配符匹配文件,可以把内部类的编译文件也找到
cp -af ${default_target_paths}/${dir_target_src_path}/${file_class_name}* ${out_path}/${pathName}/for_build/${default_webInfo_classes_paths}/${dir_target_src_path}
else
# 如果不是java文件,但又在src目录下的,则直接拷贝到目标目录
cd ${project_path}
cp -af ${line} ${out_path}/${pathName}/for_build/${default_webInfo_classes_paths}/${dir_target_src_path}
fi
else
if [ "${first_path_name}" = "${default_content_paths}" ]; then
# 如果是WebContent目录下的文件
file_to_copy_path=$(echo ${line} | awk -F "${default_content_paths}/" '{print $2}') # 去掉"WebContent/"后,保留右边的文件路径
cd ${out_path}
mkdir -p ${pathName}/for_build/$(dirname $file_to_copy_path)


cd ${project_path}
cp -af ${line} ${out_path}/${pathName}/for_build/$(dirname $file_to_copy_path)
fi
fi
done




# 保存差异文件信息到文件
echo "# 工程目录:${project_path} ; 开始版本号:${start_revision}, 截止版本号: ${end_revision}; 创建时间: $(date "+%Y-%m-%d %H:%M:%S")" > $out_path/$pathName/patch.text
echo "# ------ 以下为差异文件列表 ------" >> $out_path/$pathName/patch.text
echo "$temp_files" >> $out_path/$pathName/patch.text