如果项目是标准的maven结构项目,且打包无特别需求,直接执行maven 打个war包,或者直接部署都是很简单的事。
但事实上,很多情况都不是那么理想的。例如,本人项目中就涉及到不同环境的配置文件处理,前后台包的处理,增量包,全量包,主干包的处理,SVN server的操作….
所有的这些,maven 是无法为您定制一套标准流程的。这时,您需要的ant. 任意的想法自行编码实现。
Ant 介绍
著名的打包工具。 Apache 开源项目 http://ant.apache.org/. 它通过执行定义好的一串target流程,完成用户期望的各种任务。
具体介绍可以上官网。具体命令可以查manual. Ant在文档上还算是做得比较细致的。
Ant 库
Ant本身支持很多常用的命令,但也有一些命令不支持或支持得不好. 这时可以引入一些ant库,以强大ant 的功能。
本项目中引入的有: svnlib, ant-contrib, ant-props
此外,项目中需要js压缩,在此引入了 YUI库。
本项目的打包需求
打包:
1) 按不同的部署环境更换配置文件
2) 压缩JS
3) 删除文件
删除一些包中不需要出现的文件
(例如,有些jar包在部署的应用服务器中存在,包中不应再有; 前台包不需要后台文件…)
4) 校验手工维护的增量文件及 svn log 的一致性
5) 打包: 增量包,全量包,主干包
6) 上传包文件到SVN 服务器
部署
7) 部署到应用服务器
Weblogic, 增量包+主干包 或者全量包
打包实现
大致分为两个xml文件. Build.xml 负责打包,提交svn。 Deploy.xml 负责部署工作。
1. Deploy.xml 调用部署脚本,部署增量/全量包
<project name=”projecctName-deploy” default=”deploy”>
<import file=”./build.xml” as=”build” />
<property name=”deployShell-incremental.dir” value=”xxxxx” />
<property name=”deployShell-full.dir” value=”yyyy” />
<target name=”deploy” depends=”build.packAndUpload”>
<if>
<!—分前后台出包à
<then>
<antcall target=”_deploy_withPackType” />
</then>
<else>
<antcall target=”_deploy_noPackType” />
</else>
</if>
</target>
<!—不区分前后台部署à
<target name=” _deploy_noPackType”>
<!—全量包路径à
<property name=”fullZip.dir”
Value=”${basedir}/${workingPath}${package.name.prefix.noType}_full.zip” />
<!—增量包路径à
<property name=”incrementalZip.dir”
Value=”${basedir}/${workingPath}${package.name.prefix.noType}${incrementalZip.subfix}.zip” />
<!—主干包路径. (即上一版本的全量包) à
<property name=”baseline.dir”
Value=”${basedir}/${workingPath}${package.name.prefix.baseline}.zip” />
<if>
<!—如果是部署全量包à
<isset property=”deploy-full” />
<then>
<echo message=”deploy full zip” />
<!—调用全量包部署脚本执行部署à
<exec executable=”${ deployShell-full.dir}”>
<arg value=”${fullZip.dir}” />
</exec>
</then>
<else>
<!—未指定为全量部署,即采用增量部署方式à
<echo message=”deploy base+incremental” />
<exec executable=”${ deployShell-incremental.dir}”>
<arg value=”${baseline.dir}” />
<arg value=”${ fullZip.dir}” /> <!—一般不需要. 为方面部署脚本一并传过去à
<arg value=”${ incrementalZip.dir}” />
</exec>
</else>
</if>
</target>
<!—分前后台包部署à
<target name=”_deploy_withPackType”>
<echo message=”deploy with type” />
<!—定义部署脚本à
<if>
<isset property=”deploy-full” />
<then>
<var name=”shell.dir” value=”${ deployShell-full.dir }” />
</then>
<else>
<var name=”shell.dir” value=” ${ deployShell-incremental.dir}” />
</else>
</if>
<property name=”baseline.dir”
Value=” ${basedir}/${workingPath}${package.name.prefix.baseline}.zip” />
<!—前台全量包,增量包定义à
<property name=”F_full” Value=”..” />
<property name=”F_incremental” Value=”..” />
<!—后台全量包,增量包定义à
<property name=”B_full” Value=”..” />
<property name=”B_incremental” Value=”..” />
<!—调用部署脚本执行分包部署à
<!—可能会觉得,上面脚本定义时,已经特别区分了全量/增量部署脚本,为什么这里的参数又不区分,把所有的包都传过去? 其实跟前面的 “不分前后台部署” 是一样的:确认脚本可能不需要,但传过去也无妨。如果脚本需要验证包什么的,可能会用上。当然,真要觉得别扭,也可能把它们干掉à
<exec executable=”${shell.dir}”>
<arg value=”${ baseline.dir }” />
<arg value=”${ F_full }” />
<arg value=”${ F_incremental }” />
<arg value=”${ B_full }” />
<arg value=”${ B_incremental }” />
</exec>
</target>
可见,deploy脚本还是很清晰的,就是调用个部署脚本,传参给它。因为部署脚本分了两个—分前后台部署的脚本和不分前后台部署的脚本. 所以在调用脚本前,做了个判断。
2. Build.xml
因为build.xml涉及的情况较为复杂,有各种不同的设置组合。这里引入了一个properties文件
2.1 Build-sit.properties (Build-env.properties)
#sit
#source dir or source SVN Server Path
#目前编译直接交由maven处理.执行完后由jenkins调用ant执行后续流程,所以目前采用war路径
#src.svn=http://ip/path/trunk/....
war.dir=./projectName/target/projectName.war
#envirment attributes 配置文件替换目录
env.repaceconfig.foldname=sit
#F:front; B:back; BB:back-batch
#配置是否分前后台出包.如果部分,则直接把该属性注释掉
package.types=F,B
#设置打包不包括的文件清单. 如不设置则不处理
#_F 存在时,打前台包优先取_F文件. 如果找不到_F,则取exclude.filelist对象对应文件
exclude.filelist=./excludeFileList.txt
exclude.filelist_F=./excludeFileList_F.txt
exclude.filelist_B=./excludeFileList_B.txt
#compress js file. if "true", compress
#不设置则不压缩
js.commpress=true
#设置打包增量文件清单. 如果是只打打全量包,不需要设置. _F,_B文件同上述exclude文件效果
incremental.filelist=./version/filelist.txt
incremental.filelist_F=./version/filelist_F.txt
incremental.filelist_B=./version/filelist_B.txt
#zip files upload path. if not exists, ignore upload
svn.upload.path=https://ip:port/path
svn.username=xxxx
svn.password=yyy
2.2 build.xml
<project name="projectName" default="packAndUpload"
xmlns:props="antlib:org.apache.ant.props">
<!-- pass by argument propFile -Dname=value -->
<propertyfile="${buildProperty}"/>
<propertyname="libPath"value="./lib/"/>
<!--