如何从 ant 构建脚本查找最新的 git 提交哈希?
我目前正在开发一个新的开源项目,并将其存储在 github 上。我想扩展现有的 ANT 构建文件,以允许我创建编号的构建。我想象我会用“ant buildnum -Dnum=12”之类的东西启动构建。
我希望生成的 jar 在其清单文件中包含两个关键信息:
我知道如何创建 build.number 行。然而,我不确定最好的蚂蚁管道来查找最新的 git commit hash,这是我想要填写的值。
我为 github 上的一个项目编写了以下 ant 目标。用途:
<available file=".git" type="dir" property="git.present"/>
<target name="git.revision" description="Store git revision in ${repository.version}" if="git.present">
<exec executable="git" outputproperty="git.revision" failifexecutionfails="false" errorproperty="">
<arg value="describe"/>
<arg value="--tags"/>
<arg value="--always"/>
<arg value="HEAD"/>
</exec>
<condition property="repository.version" value="${git.revision}" else="unknown">
<and>
<isset property="git.revision"/>
<length string="${git.revision}" trim="yes" length="0" when="greater"/>
</and>
</condition>
</target>
例如用于扩展模板文件中的标记
@repository.version@
:
<target name="index.html" depends="git.revision" description="build index.html from template">
<copy file="index.html.template" tofile="index.html" overwrite="yes">
<filterchain>
<replacetokens>
<token key="repository.version" value="${repository.version}" />
</replacetokens>
</filterchain>
</copy>
</target>
此命令始终返回工作文件夹的最后一次提交 SHA1,当您并不总是从 HEAD 构建时很有用。该命令应该在 Windows 和 *nix 系统上运行
<exec executable="git" outputproperty="git.revision">
<arg value="log" />
<arg value="-1" />
<arg value="--pretty=format:%H" />
</exec>
这就是您要找的吗?
git rev-parse HEAD
我实际上使用了两个答案。我写的蚂蚁代码如下
<target name="getgitdetails" >
<exec executable="git" outputproperty="git.tagstring">
<arg value="describe"/>
</exec>
<exec executable="git" outputproperty="git.revision">
<arg value="rev-parse"/>
<arg value="HEAD"/>
</exec>
<if>
<contains string="${git.tagstring}" substring="cannot"/>
<then>
<property name="git.tag" value="none"/>
</then>
<else>
<property name="git.tag" value="${git.tagstring}"/>
</else>
</if>
</target>
我编写了一个 Ant 任务来确定构建版本,而无需显式调用 Git 命令,因此我不需要安装它(在 Windows 上我还需要将其包含在
PATH
中)。版本控制工作流程:
master
。master
上的标签。)在一家大公司,我发现
<exec> git command-line
很快就遇到了问题,一些开发人员使用GUI,一些开发人员在不同的地方安装了不同的命令行版本,一些有其他问题。我意识到,要走的路是一个纯 Java 解决方案,其依赖项是项目构建系统的一部分,就像我们之前使用 Svnkit for Subversion 一样。
一个条件是只允许“主流”库依赖项。 我们可以使用 JGit 库,但分散在 github 等地方的许多 git ant 任务 项目被排除在外。
我们使用的解决方案是结合使用 build.xml 和 JGit 库。
<!-- GIT version info -->
<target name="git-revision" depends="bootstrap" if="vcs.git" unless="vcs.revision" >
<!-- Path for jgit script in git-version -->
<path id="jgit-classpath">
<fileset dir="${build.libs}/jgit">
<include name="*.jar"/>
<include name="*.sh"/>
</fileset>
</path>
<script language="graal.js" classpathref="jgit-classpath">
<![CDATA[
var out = java.lang.System.out;
out.println("Please ignore any 'CLASSPATH element ... is not a JAR' warnings above.\n");
var db = new org.eclipse.jgit.lib.RepositoryBuilder()
.readEnvironment()
.findGitDir()
.build();
var git = new org.eclipse.jgit.api.Git(db);
project.setProperty("git.branchname", db.getBranch());
project.setProperty("git.buildname", db.getBranch().replace(/\//g, "-"))
var oid = db.resolve("HEAD");
var shortHash = oid.abbreviate(7).name();
var status = git.status().call();
var stagedChanges = status.getAdded().size() +
status.getChanged().size() +
status.getRemoved().size();
project.setProperty("git.uncommitted", stagedChanges);
var unstagedChanges = status.getMissing().size() +
status.getModified().size() +
status.getUntracked().size();
project.setProperty("git.unstaged", unstagedChanges);
if (!status.isClean()) {
shortHash += "+M"+(stagedChanges + unstagedChanges);
}
project.setProperty("git.revision", shortHash);
db.close();
]]>
</script>
<propertycopy property="vcs.buildname" from="git.buildname" silent="true" />
<propertycopy property="vcs.branch" from="git.branchname" silent="true" />
<propertycopy property="vcs.revision" from="git.revision" silent="true" />
${build.libs}/jgit
是使用 Ivy(bootstrap
任务)在 <ivy:retrieve ...
目标中设置的:
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra" xmlns:mvn="http://maven.apache.org" >
<configurations defaultconfmapping="compile->default">
<conf name="default" />
<conf name="compile" />
<!-- Configs for build tools - separate configs allow these to be fetched to separate subdirs. -->
<conf name="ant" />
<conf name="jgit" />
</configurations>
<dependencies>
<!-- Build tools - use transitive=true to fetch these -->
<dependency org="ant-contrib" name="ant-contrib" rev="1.0b3" conf="ant->default" />
<dependency org="com.jcraft" name="jsch" rev="0.1.53" conf="ant->default" />
<dependency org="org.mozilla" name="rhino" rev="1.7.7.1" conf="jgit->default" />
<dependency org="org.eclipse.jgit" name="org.eclipse.jgit.pgm" rev="4.8.0.201706111038-r" conf="jgit->default" transitive="false" >
<artifact name="org.eclipse.jgit.pgm" ext="sh" />
</dependency>
<dependency org="org.graalvm.js" name="js" rev="22.1.0.1" conf="jgit->default" />
<dependency org="org.graalvm.js" name="js-scriptengine" rev="22.1.0.1" conf="jgit->default" />
</dependencies>
</ivy-module>