首页 > 代码库 > jenkins+git+maven 增量部署思路以及相关脚本

jenkins+git+maven 增量部署思路以及相关脚本

之前通过jenkins+Git+maven这种方式打war包然后scp到测试环境使用,但是现在项目组要求打增量包,即只部署修改的文件和配置文件。

核心问题:如何获取到变动的文件???

前置条件:初始化部署需要人工进行

操作步骤:

1、配置git从远程端check代码。

技术分享

2、使用maven打包

技术分享

3、把class目录和war包传到部署服务器(因为我们打包和执行deploy的服务器分开的,如果是一台不需要改操作)

技术分享

4、最核心的一步,记录改变的文件的日志。使用的git自带的git diff --stat 命令把修改的文件的名字写到change.log中

技术分享

PS:原图中名为test.sh的shell脚本的源码在最下边

5、新增的文件和修改的通过第四步可以提取name出来但是删除的不可以,所以还要对已经部署但是删除的文件进行检测

技术分享

6、现在我们的测试部署端就已经得到新增+删除的log了,在另服务器端使用Python脚本进行文件的替换代码见下,如果使用过程中有问题或者优化建议欢迎留言讨论。

 

 

[plain] view plain copy
 
 技术分享技术分享
  1. # !/bin/sh  
  2. # auth andre.yang  
  3. dir=$1  
  4. workspace=$2  
  5. cd $workspace  
  6.   
  7.   
  8. str=$(sed -n ‘1,1p‘ $workspace/version.txt)  
  9.   
  10.   
  11. cd $dir  
  12.   
  13.   
  14. cat ${str#*:}.log change.log > change2.log  
  15.   
  16.   
  17. mv change2.log ${str#*:}.log  
  18.   
  19.   
  20. sort ${str#*:}.log |uniq > ${str#*:}_2.log  
  21.   
  22.   
  23. mv ${str#*:}_2.log ${str#*:}.log  

python 脚本见下,注非本人原创在征得同事允许后上传


------------------------------------------------------------------------------华丽的分割线----------------------------------------------------------------


[plain] view plain copy
 
 技术分享技术分享
  1. # coding=utf-8  
  2. # !/usr/bin/env python  
  3. # __author__ = ‘Caroline‘  
  4.   
  5.   
  6. import os  
  7. import glob  
  8. import shutil  
  9. import time  
  10.   
  11.   
  12.   
  13.   
  14. # 用于查找指定文件的路径  
  15. def find_path(filedir, filename):  
  16.     file_path = []  
  17.     for root, dirs, files in os.walk(filedir):  
  18.         if filename in files:  
  19.             path = root + ‘/‘ + filename  
  20.             file_path.append(path)  
  21.   
  22.   
  23.     if len(file_path) == 1:  
  24.         return file_path[0]  
  25.     else:  
  26.         return file_path  
  27.   
  28.   
  29.   
  30.   
  31.   
  32.   
  33. # 对应项目的changelog目录  
  34. CHANGES_DIR = ‘/var/lib/jenkins/changes/tools‘  
  35.   
  36.   
  37. # 最新的代码包目录,代码包目录命名要求,  
  38. # 路径中不能出现相同的目录名  
  39. # 即 /var/lib/jenkins/changes/changes/tools/monkey不允许  
  40. # 存在相同的目录名字changes  
  41. SOURCE_DIR = ‘/var/lib/jenkins/changes/tools/monkey‘  
  42.   
  43.   
  44. #存放源码的目录的名称  
  45. #切记!!!!和需要替换的源码的目录级别要相同  
  46. SOURCE_DIR_NAME = ‘monkey‘  
  47.   
  48.   
  49. # 需要替换的代码包目录  
  50. # 路径中不能出现相同的目录名  
  51. # 即 /var/lib/jenkins/changes/changes/tools/monkey不允许  
  52. # 存在相同的目录名字changes  
  53. #切记!!!!和需要替换的源码的目录级别要相同  
  54. TARGET_DIR = ‘/home/test/ROOT‘  
  55.   
  56.   
  57. # 获取需要删除的文件  
  58. delete_files = glob.glob(‘%s/D*.log‘ % CHANGES_DIR)  
  59.   
  60.   
  61. # 读取删除文件内容  
  62. delete_lines = []  
  63. if len(delete_files) == 1:  
  64.     f = open(delete_files[0], "r")  
  65.     delete_lines = f.readlines()  
  66. else:  
  67.     raise Exception(‘Dfile is not one‘)  
  68.   
  69.   
  70. # 解析文件内容,获取要删除的文件名字  
  71. d_names = []  
  72. for line in delete_lines:  
  73.     # 解析line,获取文件名  
  74.     file_names = line[:-1].split(‘/‘)  
  75.     d_name = file_names[-1]  
  76.     d_names.append(d_name)  
  77.   
  78.   
  79. # 获取需要替换的文件  
  80. modify_files = glob.glob(‘%s/[!D]*.log‘ % CHANGES_DIR)  
  81.   
  82.   
  83. # 读取文件内容  
  84. modify_lines = []  
  85. if len(modify_files) == 1:  
  86.     f = open(modify_files[0], "r")  
  87.     modify_lines = f.readlines()  
  88. else:  
  89.     raise Exception(‘Mfile is not one‘)  
  90.   
  91.   
  92. # 解析文件内容,获取要替换的文件名字  
  93. m_names = []  
  94. for line in modify_lines:  
  95.     # 解析line,获取文件名  
  96.     file_names = line[:-1].split(‘/‘)  
  97.     m_name = file_names[-1]  
  98.     m_names.append(m_name)  
  99.   
  100.   
  101. # step1:替换修改的文件  
  102. # 创建目录用于存放修改前的文件  
  103. modify_dir = ‘%s/modify‘ % CHANGES_DIR  
  104. os.mkdir(modify_dir)  
  105. # 记录替换的文件  
  106. f = open(‘%s/modify.log‘ % modify_dir, ‘w‘)  
  107.   
  108.   
  109. # 开始进行文件替换,并将未替换的文件记录下来,作为增加的文件增加,新建一个列表用于存储替换的文件名字  
  110. m_file_names = []  
  111. for root, dirs, files in os.walk(TARGET_DIR):  
  112.     for file in files :  
  113.         if file in m_names:  
  114.             # 拼接路径  
  115.             full_path = root + ‘/‘ + file  
  116.             # 把修改的文件的全路径写入到modifylogs文件中  
  117.             f.write(‘modify : %s\n‘ % full_path)  
  118.             # mv原来的文件到modify文件夹中  
  119.             shutil.move(full_path, ‘%s/%s‘ %(modify_dir, file))  
  120.             #更换文件,首先遍历,获取新文件路径  
  121.             new_file_path = find_path(SOURCE_DIR, file)  
  122.             #将新文件换到对应target的目录下  
  123.             shutil.copy(new_file_path, full_path)  
  124.             #将该file的名字,写入到m_file_names列表  
  125.             m_file_names.append(file)  
  126.   
  127.   
  128. # 将待添加的文件名字取出  
  129. a_file_names = list(set(m_names) - set(m_file_names))  
  130. print a_file_names  
  131. # 获取在最新的代码包目录中这个文件的绝对路径  
  132. for name in a_file_names:  
  133.     #需要增加的文件的绝对路径  
  134.     full_path = find_path(SOURCE_DIR, name)  
  135.     print full_path  
  136.     #截取该文件的上级路径  
  137.     file_dirs= full_path.split(‘/‘)  
  138.     #找到第一个sourcedirname,获取其索引  
  139.     num = file_dirs.index(SOURCE_DIR_NAME)  
  140.     #对列表进行切片,获取相对路径  
  141.     relative_path = ‘/‘.join(file_dirs[(num+1):])  
  142.     #获取相对文件夹路径  
  143.     relative_dir_path = ‘/‘.join(file_dirs[(num+1):-1])  
  144.     #需要增加至的绝对路径  
  145.     real_path = TARGET_DIR + ‘/‘ + relative_path  
  146.     #需要增加至的绝对文件夹路径  
  147.     real_dir_path = TARGET_DIR+ ‘/‘ + relative_dir_path  
  148.     #创建文件夹  
  149.     os.popen(‘mkdir -p %s‘ % real_dir_path)  
  150.     #记录增加文件的全路径  
  151.     f.write(‘add:%s --  %s \n‘ %(full_path, real_path))  
  152.     #copy 文件至指定位置  
  153.     shutil.copy(full_path, real_path)  
  154. f.close()  
  155.   
  156.   
  157. # step2:删除指定文件  
  158. #创建目录用于存放删除的文件  
  159. delete_dir = ‘%s/delete‘ % CHANGES_DIR  
  160. os.mkdir(delete_dir)  
  161.   
  162.   
  163. # 获取删除文件的全路径并删除  
  164. f = open(‘%s/delete.log‘ % delete_dir, ‘w‘)  
  165.   
  166.   
  167.   
  168.   
  169. for root, dirs, files in os.walk(TARGET_DIR):  
  170.     for file in files:  
  171.         if file in d_names:  
  172.             # 拼接路径  
  173.             full_path = root + ‘/‘ + file  
  174.             # 把删除的文件的全路径写入到deletelogs文件中  
  175.             f.write(‘%s\n‘ % full_path)  
  176.             #将删除的文件转移到指定目录:  
  177.             new_path = ‘%s/%s‘ % (delete_dir, file)  
  178.             shutil.move(full_path, new_path)  
  179. f.close()  
  180.   
  181.   
  182. # step3:处理log文件  
  183. # 最终将所有的log信息打包并加上时间戳  
  184. # 根据时间戳定义压缩文件夹的名字  
  185. log_dir_name = ‘%s/%s‘ % (CHANGES_DIR, time.strftime(‘%Y-%m-%d-%H-%M‘,time.localtime(time.time())))  
  186. os.mkdir(log_dir_name)  
  187. # 将modify的log文件转移至新文件夹内  
  188. shutil.copytree(modify_dir, ‘%s/%s‘ % (log_dir_name, ‘modify‘))  
  189. shutil.rmtree(modify_dir)  
  190. # 将delete的log文件转移至新文件夹内  
  191. shutil.copytree(delete_dir, ‘%s/%s‘ % (log_dir_name, ‘delete‘))  
  192. shutil.rmtree(delete_dir)  
  193. # 将文件夹里的后缀名为log的文件转移到新文件夹内  
  194. shutil.move(delete_files[0], log_dir_name)  
  195. shutil.move(modify_files[0], log_dir_name)  

jenkins+git+maven 增量部署思路以及相关脚本