从git分支中获取maven artifact版本

我们有一个工作stream程需求,这基本上意味着我们需要在git中从当前分支外部定义一个模块的工件版本。

也就是说,如果我们在git的master分支,我需要<version>master-...</version> ,如果我们在bugfixX分支,我需要<version>bugfixX-....</version>为这个pom.xml生成的工件。

我以前发现https://github.com/koraktor/mavanagaiata可以提供SHA-1哈希作为一个属性,它从文档中可以看出,它也可以提供分支,所以也许如果它可以足够早的运行我们可以设置该属性的过程,只需把<version>${our.version}</version>放在pom中即可。 如果可能的话,我非常希望看到一个有效的pom.xml文件(并奖励500点奖励)。

如果没有,我想我们是进入预处理或“混帐检查”做一些额外的魔术钩(我还没有尝试过,工作代码将会很好)。

我们有一个顶级的pom,可以在构build这个function的模块之前生成一个“..”的属性文件。

有关如何解决这个问题的任何build议?

事实上,Maven不能在其他目标的运行中改变自己项目的版本。 最重要的是,就我所知,Maven不支持<version>标签中的任意属性。 因此,需要执行单独的执行来运行将更改POM版本的目标。 有各种各样的插件可以做到这一点 – 对于这种情况下,可以使用versions插件versions:set目标 – http://mojo.codehaus.org/versions-maven-plugin/set-mojo.html

所以,可以这样执行,例如:

 mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$branch-SNAPSHOT 

$branchvariables必须包含当前的Git分支名称; 它可以用git rev-parse提取,就像这样:

 branch=$(git rev-parse --abbrev-ref HEAD) 

但是,仍然需要以某种方式执行它。 你可以手动做,但是很麻烦。 所以,我的猜测是,最强大的解决scheme将是从Git方面来解决这个问题。 那是 – 一个Git钩子。 这里是完成的Git post-checkout挂钩,它将完成这项工作(与上面相同的代码,只有当分支签出时才运行钩子,而不是只有单个文件):

 #!/bin/bash echo 'Will change the version in pom.xml files...' # check if the checkout was to checkout a branch if [ $3 != '1' ] then echo 'git checkout did not checkout a branch - quitting';exit fi # get current branch name branch=$(git rev-parse --abbrev-ref HEAD) version=$branch-SNAPSHOT # run maven versions plugin to set new version mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$version echo 'Changed version in pom.xml files to $version' 

把这个内容放到文件PROJECTDIR\.git\hooks\post-checkout文件中。 注意钩子文件应该是可执行的来运行它( chmod +x post-checkout )。

关于versions插件的一些注意事项 – 这是非常灵活的,并支持许多选项,并有其他几个目标可能会有所帮助,这取决于您的项目结构(您是否使用父母的父母,孩子有自己的版本,或者他们从派生父母等)。 所以,上面的钩子可能会稍微修改,以支持您使用versions插件的其他目标或通过指定其他参数的特定情况。

优点:

  • 强大的
  • 不需要在pom.xml文件中改变任何东西来完成这个工作
  • 这个“function”可以通过停用钩子来closures(移除或不可执行) – 同样,在pom.xml中不需要改变

缺点:

  • 一个人不能强制他人使用钩子 – 它应该在克隆repo之后手动安装(或者,如果Git用户害怕触摸.git目录内的东西,可以提供一个脚本来安装钩子)。

UPDATE

以下是更复杂的钩子版本,它不仅将版本设置为分支名称,而且还保留旧版本的后缀。 例如,提供了旧版本的master-1.0-SNAPSHOT ,切换到feature1分支会将项目的版本更改为feature1-1.0-SNAPSHOT 。 这个bash脚本几乎没有什么问题(需要名称中没有短划线( - )的分支名称,只接受root pom的版本),但是可以给出一个钩子如何扩展的概念:给定mvn和bash命令可以提取和更新POM中相当多的信息。

 #!/bin/bash echo 'Will change the version in pom.xml files...' # check if the checkout was to checkout a branch if [ $3 != '1' ] then echo 'git checkout did not checkout a branch - quitting';exit fi # get current branch name branch=$(git rev-parse --abbrev-ref HEAD) # get current version of the top level pom current_version=$(mvn help:evaluate -Dexpression=project.version | grep -v '\[.*') # extract version suffix suffix=$(echo $current_version | cut -d \- -f 2) # build new version version=$branch-$suffix # run maven versions plugin to set new version mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$version echo 'Changed version in pom.xml files to $version' 

对不起,重新提出这个问题,并发布最近的另一个解决scheme,但它确实可以dynamic地改变Maven版本,并使用一些gitfunction,有点像git describe会做。

这样做的项目是jgitver-maven-plugin (免责声明;我是作者) ,它使用jgitver一个基于jgit的库来从git信息派生maven项目版本。

在这里输入图像说明

这是一个非常容易使用的maven扩展

 ... <build> <extensions> <extension> <groupId>fr.brouillard.oss</groupId> <artifactId>jgitver-maven-plugin</artifactId> <version>0.1.0</version> </extension> </extensions> ... </build> ... 

该扩展也可以用作插件扩展,然后允许更多的configuration,例如,如果你不想使用SNAPSHOTS。 请参阅项目页面以获取完整使用场景的说明。

还有一个可用的gradle插件 ,大致相同。


[编辑1] :回答ThorbjørnRavn Andersen评论

该插件不会修改原始的pom文件或build.gradle文件。
对于maven插件,在maven对象模型的内存中进行修改,并写入临时目录中的临时文件。 计算仅基于git元数据(标签,提交,…)。
这个非修改允许不污染git历史。 当你对git commit感到满意的时候,把它标记为git tag -a xyzmvn deploy :就是这样。
您的项目文件中的版本现在是无用的,例如可以设置为0。

截至今天,由于IDEA-155733,最近的EAP版本的IntelliJ与maven插件一起工作。 Eclipse和Netbeans没有问题。


如果足够在工件文件名中设置git标签和版本信息,则可以使用maven-jgit-buildnumber-plugin :

 <build> <finalName>${artifactId}-${git.buildnumber}</finalName> <plugins> <plugin> <groupId>ru.concerteza.buildnumber</groupId> <artifactId>maven-jgit-buildnumber-plugin</artifactId> <version>1.2.7</version> <executions> <execution> <id>git-buildnumber</id> <goals> <goal>extract-buildnumber</goal> </goals> <phase>prepare-package</phase> </execution> </executions> </plugin> <!-- more plugins --> </plugins> </build> 

你有没有尝试过使用这个插件?: https : //github.com/ktoso/maven-git-commit-id-plugin 。 您可以将其configuration为生成一个属性文件,其中包含有关您的repo状态的所有相关信息:

  • 描述
  • 的commitid
  • buildUserName
  • buildUserEmail
  • 构build时
  • commitUserName
  • commitUserEmail
  • commitMessageShort
  • commitMessageFull
  • commitTime

你有没有检查过buildnumber-maven-plugin ,它给了你使用git版本号的机会。 但是你需要不同的东西。 此外,我会build议做一件事情,如:

  1.0.0-SNAPSHOT 1.0.0-SNAPSHOT 

在主人身上

在一个分支上,你可以简单的更改版本

  1.0.0-BF-SNAPSHOT