基于Jenkins + Git的PHP项目编译脚本
本文针对的是了解或已经在使用Jenkins和Git的开发者或团队。
本团队使用了Jenkins作为持续集成平台,Git作为版本管理工具,而本人负责的项目是PHP项目,所谓发布项目就是复制文件。
通常有两种发布方式:全量发布和增量发布。
这两种发布方式并没有本质的区别,主要区别在于不同的应用场景。
全量发布:代码改动比较大,基本上覆盖了项目的大部分代码,这个时候可以选择把整个项目打包,当然可能会排除掉少量文件或目录(通常需要排除配置文件)。另外需要注意的是如果有运行期目录比如用于存放临时文件则需要保持其空框架,但如果项目有上传文件等的目录,则不太合适全量发布,因为那样意味着需要把已上传文件备份并恢复,如果文件数量比较大,则是一项很耗时的工作。
全量发布意味着发布时通常会把之前的代码删除或重命名。
增量发布:代码改动不大,则可以直接指定改动的文件或文件夹。
增量发布意味着发布时不需要删除原来的代码,而是直接COPY覆盖。
结合Jenkins和Git,具体实现思路如下:
在源码根目录维护三个文本文件:VERSION,V_INCLUDE, V_EXCLUSE
其中VERSION存放每次要发布的版本号;
V_INCLUDE用于存放增量发布时要发布的文件(夹)列表,一个一行;
V_EXCLUDE用于存放全量发布时要排除的文件(夹)列表,一个一行。
(后面两个文件以V开头是为了出现在VERSION文件的附近,不容易被遗忘)。
在Jenkins中创建两个任务:全量发布任务、增量发布任务。
全量发布任务的脚本中,先从Git获取代码,然后从VERSION读取版本号,从V_EXCLUSE读取要排除的文件列表。
增量发布任务的脚本中,先从Git获取代码,然后从VERSION读取版本号,从V_INCLUSE读取要包含的文件列表。
下面给出全量发布的脚本:
# 定义变量 root_path=$PWD code_name="HiCloudShop" # 清理历史数据 rm -rf release* || echo "no dir" #download code if [ -d $code_name ]; then rm -rf $code_name fi # 从Git获取代码 git clone ssh://xxx@xxx.com:29418/xxx/$code_name # 获取版本号 cd $code_name versionname=`cat VERSION` version=$versionname # 创建release目录 mkdir ${root_path}/release_$version # 生成Git info cp /xxx/sh_script/git_info.sh . chmod +x git_info.sh ./git_info.sh mv git_info.txt git_info_${JOB_NAME}.txt cp git_info_${JOB_NAME}.txt ${root_path}/release_$version/ rm -rf .git # 压缩源码 cd $root_path cat ${root_path}/${code_name}/V_EXCLUDE | awk -v code_name=$code_name '/^(.+)$/{print " --exclude="code_name"/"$1}'| xargs tar czvf $code_name.tgz $code_name # 把源码转移到release目录 mv $code_name.tgz ${root_path}/release_$version/
tar行用到了awk和xargs:
先用cat取出V_EXCLUDE文件的内容(需要排除的文件列表);然后用awk在每个文件名前面缀上源码文件夹的名称(因为我们需要在源码文件夹的上一层执行tar);然后使用xargs把这个列表传给tar作为参数。
其中awk使用了-v参数把shell中code_name的值传到awk。
PS: 之前tar中是使用-X参数来提供需要排除的文件列表,但是这个参数的解释跟我们的需求不一致:-X匹配目录内所有的文件或文件夹,而我们需要的是相对跟目录的路径。详细点说,如果给出的是index.php,-X会把目录内所有的index.php文件排除,而我们只是想排除跟目录的index.php
下面是增量发布代码(跟全量发布代码类似):
# 定义变量 root_path=$PWD code_name="HiCloudShop" # 清理历史数据 rm -rf release* || echo "no dir" #download code if [ -d $code_name ]; then rm -rf $code_name fi # 从Git获取代码 git clone ssh://xxx@xxx.com:29418/xxx/$code_name # 获取版本号 cd $code_name versionname=`cat VERSION` version=$versionname # 创建release目录 mkdir ${root_path}/release_$version # 生成Git info cp /xxx/sh_script/git_info.sh . chmod +x git_info.sh ./git_info.sh mv git_info.txt git_info_${JOB_NAME}.txt cp git_info_${JOB_NAME}.txt ${root_path}/release_$version/ rm -rf .git # 压缩源码 cd $root_path cat ${root_path}/${code_name}/V_INCLUDE | awk -v code_name=$code_name '{print code_name"/"$1}' | xargs tar czvf $code_name.tgz # 把源码转移到release目录 mv $code_name.tgz ${root_path}/release_$version/