我有一组来自不同 git 存储库的 java 项目,我想用 Jenkins 构建它们。
它们都共享相同的 ant 构建脚本,该脚本通过 ant 导入机制使用项目特定的配置部分(例如编译类路径)。
目前我手动进行此共享,但这在更改公共部分时非常容易出错。
所以我的问题是:在 jenkins 服务器上跨多个构建作业管理共享 ant 构建脚本的好方法是什么?
我有一组来自不同 git 存储库的 java 项目,我想用 Jenkins 构建它们。
它们都共享相同的 ant 构建脚本,该脚本通过 ant 导入机制使用项目特定的配置部分(例如编译类路径)。
目前我手动进行此共享,但这在更改公共部分时非常容易出错。
所以我的问题是:在 jenkins 服务器上跨多个构建作业管理共享 ant 构建脚本的好方法是什么?
正如@whiskeyspider 所说,这不是一个不常见的问题,它不仅限于詹金斯。在我看来,这也是阻碍大型遗留 ANT 构建的问题之一。随着时间的推移,由于有理由担心它会破坏依赖构建,因此更改通用逻辑变得越来越难。
将通用逻辑保存在单独的存储库或 git 子模块中是合理的建议,因为它启用了对该逻辑的版本控制。另一种选择是将通用逻辑打包为ANT 库
<project ... xmlns:common="antlib:com.example.commonbuild">
<taskdef uri="antlib:com.example.commonbuild">
<classpath>
<fileset dir="${lib.dir}" includes="commonbuild-1.0.jar"/>
</classpath>
</taskdef>
..
..
<target name="build">
<common:compileAndPackage srcDir="${src.dir}" buildDir="${build.dir}" jarFile="${build.dir}/${ant.project.name}.jar"/>
</target>
虽然看起来更复杂,但我坚持创建这些类型的常见任务可以使构建文件更具可重用性和可读性。它还使您的组织的定制是什么变得一目了然。我发现它对于隐藏可能涉及讨厌的嵌入式脚本的实现细节特别有用。
最后,我非常喜欢使用ivy来管理我的 3rd 方依赖项。这意味着我可以轻松地从我的存储库中下载构建所需的任何版本的通用逻辑。
├── build.xml
└── src
└── com
└── example
└── commonbuild
└── antlib.xml
<antlib>
<macrodef name="compileAndPackage">
<attribute name="srcDir"/>
<attribute name="buildDir"/>
<attribute name="jarFile"/>
<sequential>
<mkdir dir="@{buildDir}/classes"/>
<javac srcdir="@{srcDir}" destdir="@{buildDir}/classes" includeantruntime="false"/>
<jar destfile="@{jarFile}" basedir="@{buildDir}/classes"/>
</sequential>
</macrodef>
</antlib>
笔记:
只需将 XML 文件 jar 起来:
<target name="build" description="Create jar">
<jar destfile="${build.dir}/commonbuild-${version}.jar" basedir="${src.dir}"/>
</target>
我的构建逻辑还会将此 jar 文件发布到我的存储库中,以便其他构建可以使用ivy将其拉下。也意味着通用的构建逻辑可以有一个单独的正式的发布管理生命周期(在大型组织中非常重要)
几个想法...
这个答案不是 Jenkins 特有的,应该可以移植到其他构建服务器。
我自己也找到了另一种选择:
将通用构建脚本中的“可覆盖”部分声明为“中性”元素,例如,对于路径定义,定义一个空路径:
<path id="additional-classpath" />
可以选择在中性定义之后导入另一个构建脚本以使其覆盖现有的:
<import file="compile-classpath.xml" optional="true" />
在导入的文件中,您现在可以定义元素以满足要构建的项目的个人需求。