我正在尝试使用Ant和MSBuild自动化我的项目(java和。net)的构建过程。我读过有关它们的文章,知道如何用Ant和MSBuild编写构建脚本。但是我想知道,对于编写构建脚本有什么指导方针或最佳实践吗?以下是我发现的两个问题,但我还想听听其他开发者的看法。
- 在编写构建脚本时,只需依赖位于源代码控件和在工作文件夹中可用检查来源。不要写构建脚本
- 如果一个项目包含一组子系统,每个子系统有它自己的构建脚本,只需调用项目的构建文件即可子系统的构建脚本。此外,这些文件应该导入一个公共构建文件,其中包含诸如编译、测试、包等目标。
我也看到了这篇文章,但它详细说明了写作任务的方式。我需要更多高层次的指导方针,如上所述。
以下是我从答案中收集到的指导方针:
- 在干净的环境中运行每个构建。这意味着每个构建脚本都需要一个
clean
目标。 构建脚本通常包括 - 如果一个产品有不同的开发线(如开发、发布),它们都应该具有相同的构建脚本。但是,不同的参数应该传递给这些脚本。
- 在开发线上执行的构建通常包含编译,打包、部署和安装步骤。而是建立在释放的基础上行包括进一步的步骤,例如标记产品和生成变更日志/发布说明。
- 构建脚本也应该保持在源代码控制中。
- 尽量保持所有的构建信息在构建脚本,而不是在持续集成服务器(Bamboo, TeamCity等)
- 如果你的构建使用了一个将来可能会改变的参数(例如复制构建结果的网络地址),不要硬编码构建脚本。相反,可以使用构建参数对其进行更多的控制容易。
compile
, package
和test
目标。如果您正在构建VisualStudio应用程序,您最好使用msbuild
而不是Ant。msbuild
命令将使用开发人员创建的解决方案文件进行构建,并且基本上模拟他们所做的相同构建。
如果你真的想自动化一切,看看Jenkins。它有一个插件,可以执行msbuild
,并将自动触发构建每次有人做出改变。我使用msbuild
和Ant与Jenkins的组合。我使用msbuild
进行构建,然后使用Ant收集并压缩所有构建的工件。然后,人们可以直接从Jenkins下载构建的工件。
现在,对于Java应用程序,必须使用Ant。我使用以下指南
- 每个构建脚本需要一个
clean
目标。此目标删除在构建过程中添加的任何文件,将工作目录返回到clean
发生之前的状态。 在使用目标名时,我遵循Maven的做法,所以我的目标是像clean、compile和package这样的名字。 - 同样遵循Maven的指导方针,我所有的构建文件都放在
target
目录中。这样,我的clean命令可以简单地执行<delete dir="${target.dir}/>
,并将所有内容清理得漂亮而闪亮。 - 如果我有子项目,每个子项目有自己的
build.xml
文件。我的主build.xml
文件只是调用所有子项目的build.xml
文件。 - 使用常春藤。它易于设置和使用。您不再有在源存储库中存储jar文件的问题,或者丢失您所依赖的jar文件的哪个版本的问题。 见鬼,如果可以的话,使用Maven并完成它。不幸的是,大多数较老的项目优化比它的价值更困难。
- 使用Jenkins作为持续构建服务器进行构建。并且,所有离开部门的构建(UAT, QA和保护构建)必须是Jenkins构建。
- 鼓励开发人员编写单元测试。事实上,Jenkins可以执行单元测试并在其构建页面上显示其结果。
- 使用其他东西,如checkstyle, PMD, CPD, Findbugs和其他代码验证产品。当然,Jenkins可以运行每一个,并显示漂亮的图表,可以用来向你的经理展示你的工作有多努力。
对你上面提到的第二个要点做一个评论:
如果一个项目包含一组子系统,并且每个子系统都有自己的自己的构建脚本,项目的构建文件应该只调用构建子系统的脚本。
每个子系统应该有自己的构建文件,但是该文件应该导入一个公共的构建文件。通用的构建文件将包含诸如编译、测试、包等目标。
http://ant.apache.org/manual/Tasks/import.html子系统构建文件非常简单,不包含重复,只包含特定于该子系统的信息(例如compile.classpath)。
在MSBuild中,目标应该尽可能指定输入和输出(以启用依赖计算)。如果有必要,使用Returns属性来指定一个目标,该目标返回的项与用于依赖项计算的项不同。
应该使用项转换(对于简单的、基于路径的转换)或另一个目标(对于更复杂的转换)来生成给定目标的输入和输出项。
For MSBuild pre-4。对于您在.targets文件中定义的目标,请考虑使用以下模式,以使消费者能够在您定义的目标之前注入他们自己的目标:
<PropertyGroup>
<MyTargetDependsOn>
Target1;
Target2;
SomeOtherTarget
</MyTargetDependsOn>
</PropertyGroup>
<Target
Name="MyTarget"
DependsOnTargets="$(MyTargetDependsOn)">
</Target>
这使得消费者可以在指定的目标之前注入他们自己的目标,只需修改MyTargetsDependsOn属性的值:
<PropertyGroup>
<MyTargetDependsOn>
$(MyTargetDependsOn);
YetAnotherTarget
</MyTargetDependsOn>
</PropertyGroup>
<Target
Name="YetAnotherTarget">
</Target>
在MSBuild 4。