【问题标题】:How to set project version in maven at build time?如何在构建时在 Maven 中设置项目版本?
【发布时间】:2018-04-20 08:59:25
【问题描述】:

我正在尝试在我们的项目中实现语义版本控制。我测试了 maven semver 插件,但这对我没有帮助,所以请不要问我为什么。我最终最终使用了 maven groovy。它就像一个魅力,但是,当我安装或部署 maven 项目时,存储库中的版本是变量名。

尽管所有人工制品和 jar 文件都以正确的版本打包。

所以请看我的 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mytest.test</groupId>
    <artifactId>test-tag</artifactId>
    <version>${revision}</version> 


    <description>Test</description>

    <properties>
        <ChangeType>TO_BE_SET</ChangeType>
    </properties>


    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.gmaven</groupId>
                <artifactId>gmaven-plugin</artifactId>
                <version>1.5</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>execute</goal>
                        </goals>
                        <configuration>
                            <providerSelection>2.0</providerSelection>
                            <properties>
                                <script>git describe --abbrev=0 --tags</script>
                            </properties>
                            <source>
                                def tagIt = 'git tag -a vXXXX -m "Auto tagged"'
                                def changeType = project.properties.ChangeType
                                def command = project.properties.script
                                def process = command.execute()
                                process.waitFor()
                                def describe = process.in.text.trim()
                                println "Setting revision to: " + describe

                                if(!describe.startsWith("v")) {
                                    describe = "1.0.1"
                                } else {
                                    describe = describe.substring(1)
                                }

                                    project.properties.setProperty('revision', describe)


                            </source>
                        </configuration>
                    </execution>
                </executions>
            </plugin>


            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-compile</id>
                        <phase>none</phase>
                    </execution>
                    <execution>
                        <id>default-testCompile</id>
                        <phase>none</phase>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-testResources</id>
                        <phase>none</phase>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-jar</id>
                        <phase>package</phase>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-test</id>
                        <phase>none</phase>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

版本是 ${revision} 一个在 groovy 脚本中设置的变量名。 groovy 代码所做的是从 GIT 中获取最后一个标签,然后将其设置为属性 'revision'。

最终的 jar 文件已提取正确的版本,但安装到存储库时,文件夹名称和 jar 名称如下:

m2\repository\com\mytest\test\test-tag\${revision}\test-tag-${revision}.jar

我尝试使用以下方法将“修订”默认为一个值:

<properties>
  <revision>1.0.1</revision>
</properties>

但是设置值的常规代码没有效果。

我还为 maven groovy 插件尝试了不同的阶段,但没有运气。我错过了什么吗?谁能帮我解决这个问题?

我想提一下,正如 vatbub 和 StefanHeimberg 提到的那样,我可以使用 versions:set 来设置版本,但这需要我对 GIT 进行额外的提交,这是我试图避免的,想知道我是否可以通过而是写一个 Maven 插件?

【问题讨论】:

  • 你试过版本的maven插件吗?它有一个set 目标,可以修改项目版本。 (more info) 但是,afaik,maven 解析 pom,并且在构建过程中对 pom 所做的更改仅在后续构建中考虑。在这种情况下,您需要调用versions:set,然后第二次调用maven 来执行实际的构建。
  • @vatbub 感谢您的及时回复。 groovy 代码决定了版本,所以我需要执行 groovy-maven-plugin,然后获取输出,然后运行 ​​versions:set,然后再运行 mvn install。不知道我该怎么做!
  • 正如我所说,Maven 在处理构建期间发生的 pom 更改方面非常糟糕。我想最好的解决方案是创建一个轻量级的命令行工具,它只将所需的版本输出到控制台并将输出通过管道传输到versions:set
  • 我最终使用了版本:如你所说的设置。实际上我创建了一个新的插件关闭版本:设置并自定义它以获得最新的标签和其他信息,然后自动设置版本
  • 不是 OP 想要的,但这是 possible with Gradle

标签: java groovy maven-3


【解决方案1】:

使用 Maven,您可以在构建时设置版本

mvn versions:set -DnewVersion=${bamboo.inject.version}

@vatbub 已经在您的问题中发表了评论。

除此之外,我还编写了一个 Shell 脚本,可以在构建管道中使用,以根据 maven 项目版本生成版本,并从构建服务器添加构建号。

https://gist.github.com/StefanHeimberg/c19d7665e8df087845c036fe8b88c4f2

脚本读取 maven 项目版本,添加内部版本号并写入包含所有可用新编号的文本文件。

下一步是将该文本文件注入到构建管道中,并如上所述调用版本插件

pom.xml

类似

<project>

    <groupId>ch.stefanheimberg.example</groupId>
    <artifactId>your-awesome-app</artifactId>
    <version>5.1.2-SNAPSHOT</version>

</project>

<project>

    <groupId>ch.stefanheimberg.example</groupId>
    <artifactId>your-awesome-app</artifactId>
    <version>5.1-SNAPSHOT</version>

</project>

第 1 步:

./generate_version_txt.sh ${bamboo.buildNumber}

第 2 步:

在构建系统中注入生成的version.txt,所有属性都可以在所有任务/插件等中使用...

在我的例子中,Bamboo CI 准备好 version.txt 文件并将文件的内容声明为 bamboo.inject. 前缀下的环境变量。

例如${bamboo.inject.long_version}

第 3 步:

更新 Maven 项目版本

mvn versions:set -DnewVersion=${bamboo.inject.version}

第 4 步:

运行 Maven 构建

mvn clean verify

第 5 步:

运行 Docker 构建

例如,也可以将其用作 docker 标签版本。等等……

docker build --build-arg version=${bamboo.inject.version} --tag your-awesome-app:${bamboo.inject.version} .

示例 Dockerfile:

FROM jboss/wildlfy
ARG version
ADD target/your-awesome-app-${version}.war /opt/jboss/wildfly/standalone/deployments/

我知道在您使用 groovy 脚本的情况下这可能是一个问题/不可能。但也许这是您问题的另一种观点。也可能是另一种解决方案。

(对不起我的英语。但我希望我的意思可以理解)

【讨论】:

  • 谢谢。问题是我可以用 groovy 做同样的事情。我可以将版本写入文件并在versions:set中使用它。但是这个问题是,你将在 GIT 存储库中有一个额外的提交来更改 Pom 文件,我试图避免这种情况,否则这与 maven 发布插件所做的事情是一样的。顺便说一句,投反对票的不是我,是其他人投的。我会等待更多答案,看看是否有人提出了更好的解决方案
  • 投反对票不是问题……这就是社区的运作方式。但我很高兴知道为什么有人投了反对票。一些建设性的反馈将被应用。我知道我的答案不是问题的答案,但可能是解决此问题的另一种方法
  • versions:set 就像一个魅力!正是我需要的!谢谢!
【解决方案2】:

我遇到了类似的问题并最终使用maven flatten plugin 来确保在部署之前从 POM 中删除所有变量。这将删除对字符串 ${revision} 的所有引用并在构建时替换为实际值,而不会干扰原始 POM。

【讨论】:

  • 如果当前父母没有任何其他父母,它工作正常。
猜你喜欢
  • 2019-05-15
  • 1970-01-01
  • 2012-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多