一、背景
通常一个团队开发的代码会分环境运行,线下测试环境和线上生产环境当然不能使用同一套资源,例如数据库、redis、ftp等都需要专用。针对这种情况,jenkins在做自动编译打包部署时,就需要我们能够支持针对不同环境部署替换不同的配置文件,例如数据库配置文件、redis配置文件等。本文将介绍如何使用ant脚本编译时进行配置文件替换。
二、解决方案
通过ant脚本的Copy Task实现文件的复制;通过Ant工具的Copy任务可以让程序在Windows和Linux/UNIX下对文件和目录进行复制操作;
1、单个文件复制
<copy file="sourfile.txt" tofile="copyfile.txt"/>
在当前目录复制sourfile.txt,并把复制的文件命名为copyfile.txt;
<copy file="sourfile.txt" todir="../some/other/dir"/>
把当前目录文件下的sourfile.txt复制到与当前目录同级的some目录的/other/dir子目录下。这里“..”代表相对路径(当前目录的上一级目录)。
2、对文件目录进行复制:
<copy todir="../new/dir">
<fileset dir="src_dir"/>
</copy>
把src_dir目录复制到../new/dir目录下。有时对文件进行复制时需要对文件进行备份。下面举一个复制文件时对文件进行备份的例子。
<copy todir="../backup/dir">
<fileset dir="src_dir">
<exclude name="**/*.java"/>
</fileset>
<globmapper from="*" to="*.bak"/>
</copy>
把src_dir目录及其子目录下所有非Java文件复制到../backup/dir目录下,并重命名为bak文件,以作备份。
3、执行copy task时使用文件过滤(一个复制文件的同时替换文件中的特殊符号)
<copy todir="../backup/dir">
<fileset dir="src_dir"/>
<filterset>
<filter token="TITLE" value="Foo Bar"/>
</filterset>
</copy>
把src_dir目录下的所有文件复制到../backup/dir目录,并在所有文件中查找并替换@TITLE@为Foo Bar。
当要进行新产品发布时通过需要替换文件中的版本信息和时间信息。
说明:在Ant工具中还提供了copydir和copyfile这两个特定的任务,分别用于对目录和文件进行复制。但自从有了Copy任务后,这两个任务已过期,不建议再使用,应该统一使用Copy任务。
其余详情可参考http://ant.apache.org/manual/Tasks/copy.html
三、具体实施
1、将替换使用的文件上传到gitlab
先将替换文件放置到工程根目录下,本工程新建copy_conf文件目录,存放替换文件,如下:
copy_conf文件夹内替换文件如下:
被替换的文件存放路径:(工程根目录下的src目录下)
2、修改ant编译的build.xml脚本,去自动抓取copy_conf文件夹中文件
<target name="copyTest">
<copy todir="src">
<fileset dir="copy_conf">
<include name="**/*.*" />
</fileset>
</copy>
</target>
target:来规定copy任务的指定顺序。
3、上传到gitlab,开启jenkins构建即可
ant编译执行的顺序:
copyTest-->clean-->init-->build-->warFile-->build
大坑:
如果我们上述copy_conf文件夹中的.properties文件没有发生修改,或者是修改后未提交到gitlab,那么ant脚本中的
<target name="copyTest">任务就不会执行。只有当jenkins检测到gitlab中copy_conf文件夹中的文件发生了变化,它才会执行文件替换工作。错误运行结果如下:
而正常的运行结果应该是:
解决方案:
1、放弃<target name="copyTest">任务,将配置文件替换的工作放到init初始化任务中去执行;
2、在init初始化时,新建一个配置文件中转站(reconf_dir文件夹),将copyTest文件夹中的文件复制到reconf_dir文件夹中;
3、将reconf_dir文件夹中的配置文件复制到WebRoot/WEB-INF/classes文件夹中,为打war包做好准备;
4、每次执行ant脚本构建时,先删除reconf_dir文件夹,然后新建reconf_dir文件夹,最后执行第二步的拷贝。
最后附上项目的build.xml文件(注:只包含target部分)
<target name="clean" >
<delete dir="WebRoot/WEB-INF/classes"/>
<delete dir="reconf_dir"/> <!--删除配置文件中转站文件夹 -->
</target>
<target name="init" depends="clean">
<mkdir dir="WebRoot/WEB-INF/classes"/>
<mkdir dir="reconf_dir"/> <!--创建配置文件中转站文件夹 -->
<echo message="copy properties to reconf_dir"/>
<!--复制copy_conf文件夹中的替换配置文件到reconf_dir文件夹 -->
<copy includeemptydirs="false" todir="reconf_dir">
<fileset dir="copy_conf">
<include name="*.properties" />
</fileset>
</copy>
<!--复制src源代码里面的内容到classes -->
<echo message="copy2"/>
<copy includeemptydirs="false" todir="WebRoot/WEB-INF/classes">
<fileset dir="src">
<exclude name="**/*.launch"/>
<exclude name="**/*.java"/>
<exclude name="jdbc.properties"/>
<exclude name="param.properties"/>
<exclude name="FTP.properties"/>
</fileset>
</copy>
<echo message="copy3"/>
<!--复制reconf_dir文件夹中的配置文件到WebRoot/WEB-INF/classes -->
<copy includeemptydirs="false" todir="WebRoot/WEB-INF/classes">
<fileset dir="reconf_dir">
<include name="*.properties" />
</fileset>
</copy>
</target>
<target depends="clean" name="cleanall"/>
<target depends="warFile" name="build"/>
<target name="build-subprojects"/>
<target depends="init" name="build-project"> <!-- build -->
<echo message="${ant.project.name}: ${ant.file}"/>
<!--在javac中添加encoding=“utf-8” -->
<!-- 定义任务,编译src文件夹中的java文件,编译后的class文件放到创建的文件夹下。-->
<javac debug="true" debuglevel="${debuglevel}" destdir="WebRoot/WEB-INF/classes" source="${source}" target="${target}" encoding="utf-8" includeAntRuntime="false">
<src path="src"/>
<classpath refid="CellplanNew.classpath"/>
</javac>
</target>
<!--生成war包 -->
<target name="warFile" depends="build-project"> <!-- 打包 -->
<!-- 删除原有war包。 -->
<echo message="warFile build"/>
<delete dir="${basedir}/${warFileName}" />
<!-- 建立新war包。 -->
<war destfile="${basedir}/${warFileName}" webxml="${basedir}/WebRoot/WEB-INF/web.xml">
<!-- 将非jar和非class文件拷贝到war包的对应路径下。-->
<fileset dir="${basedir}/WebRoot">
<include name="**/**.*" />
<exclude name="**/*.jar"/>
<exclude name="**/*.class"/>
</fileset>
<!-- 将jar和class文件拷贝到war包的对应路径下。-->
<lib dir="${basedir}/WebRoot/WEB-INF/lib" />
<classes dir="WebRoot/WEB-INF/classes" />
</war>
</target>
版权声明:本文为博主原创文章,未经博主允许不得转载。
https://blog.csdn.net/ChenLeihappy/article/details/80103916