拉出 pom.xml 中的版本
Pulling out the version in the pom.xml
我想在我的 pom.xml
文件中附加 Jenkins 内部版本号。我可以通过 Maven Version plugin 执行此操作,但首先我需要 pom.xml
文件中的原始版本。
为了做到这一点,我正在使用命令 xmllint --xpath '/project/version/text()' pom.xml
命令。但是,我不断收到 XPath set is empty
这是示例 pom.xml
文件:
<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>
<artifactId>das-artifact</artifactId>
<name>das-name</name>
<version>4.2</version>
</project>
这是我的输出:
$ xmllint --nsclean --xpath '/project/version/text()' pom.xml
XPath set is empty
$
但是,如果我将 xmlns
元素更改为 fooxmlns
,它会起作用:
这是示例 pom.xml
文件:
<project fooxmlns="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>
<artifactId>das-artifact</artifactId>
<name>das-name</name>
<version>4.2</version>
</project>
这是我的输出:
$ xmllint --nsclean --xpath '/project/version/text()' pom.xml
4.2$
我不太熟悉 xmllint
可以做的所有事情。我可以让它忽略 xmlns
命名空间属性吗?
通常有两种解决方案,要么按照@A_Di-Matteo建议的路径(但我建议至少使用 Maven 3.3.9 或 3.4.0,如果已发布),或者你可以通过build-helper-maven-plugin 如下所示:
mvn build-helper:parse-version versions:set \
-DnewVersion=${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}-WhatEverYouLikeToAdd \
versions:commit
这是我所做的:
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.das-group</groupId>
<artifactId>das-artifact</artifactId>
<version>1.1.0-123</version>
<profiles>
<profile>
<id>arse-version</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<id>parse-version</id>
<goals>
<goal>parse-version</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>validate</phase>
<id>set-version</id>
<goals>
<goal>set</goal>
<goal>commit</goal>
</goals>
</execution>
</executions>
<configuration>
<newVersion>${parsedVersion.osgiVersion}-${BUILD_NUMBER}</newVersion>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
我创建了一个配置文件 arse-version
(这实际上是在我的公司 pom.xml 中,它是我们所有项目的父级),它添加了 build-helper-maven-plugin
和 versions-maven-plugin
插件。我将它们都设置为在 validate
生命周期中执行。
现在,要在 Jenkins 中设置附加了内部版本号的版本,我可以执行这个:
$ mvn -Parse-version -DBUILD_NUMBER=$BUILD_NUMBER validate
这在管道构建和 Jenkinsfile
中非常有效。不需要单独的 shell 或 Python 脚本。无需担心 xpath
或 xmllint
是否以特定方式安装和工作(它在我的 Mac 和 Linux 上的工作方式不同)。
我的主要问题是版本号一直在重建,而不是拿走那里的东西。如果开发人员将版本设置为 1.0
而这是构建 #23,我将获得版本 1.0.0-23
。如果开发者放 1.2-3, I get
1.2.3-23`。因此,我将简单地告诉所有开发人员,他们现在必须使用标准的三部分版本编号方案。
简洁明了。感谢 的回答。
注意:编辑以添加 commit
目标。这将从工作区中删除 backup pom.xml。
回答实际问题:
基于@djeikyb 在 xml - xmllint failing to properly query with xpath - Stack Overflow 的务实评论,这对我有用:
sed < pom.xml '2 s/xmlns=".*"//g' | xmllint --xpath '/project/version/text()' - 2>/dev/null
而且我仍然感到困惑,为什么 xml 使用我认为是为该任务设计的工具进行这样的解析,如果没有这种混乱,实际上就无法工作......
对每个 xml 节点使用 local-name()
函数。
Old-XPath: /project/version/text()
New-XPath: /*[local-name()="project"]/*[local-name()="version"]/text()
现在 运行 在 bash shell 你会得到
$ xmllint --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()' pom.xml
1.0.0-SNAPSHOT
我想在我的 pom.xml
文件中附加 Jenkins 内部版本号。我可以通过 Maven Version plugin 执行此操作,但首先我需要 pom.xml
文件中的原始版本。
为了做到这一点,我正在使用命令 xmllint --xpath '/project/version/text()' pom.xml
命令。但是,我不断收到 XPath set is empty
这是示例 pom.xml
文件:
<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>
<artifactId>das-artifact</artifactId>
<name>das-name</name>
<version>4.2</version>
</project>
这是我的输出:
$ xmllint --nsclean --xpath '/project/version/text()' pom.xml
XPath set is empty
$
但是,如果我将 xmlns
元素更改为 fooxmlns
,它会起作用:
这是示例 pom.xml
文件:
<project fooxmlns="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>
<artifactId>das-artifact</artifactId>
<name>das-name</name>
<version>4.2</version>
</project>
这是我的输出:
$ xmllint --nsclean --xpath '/project/version/text()' pom.xml
4.2$
我不太熟悉 xmllint
可以做的所有事情。我可以让它忽略 xmlns
命名空间属性吗?
通常有两种解决方案,要么按照@A_Di-Matteo建议的路径(但我建议至少使用 Maven 3.3.9 或 3.4.0,如果已发布),或者你可以通过build-helper-maven-plugin 如下所示:
mvn build-helper:parse-version versions:set \
-DnewVersion=${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}-WhatEverYouLikeToAdd \
versions:commit
这是我所做的:
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.das-group</groupId>
<artifactId>das-artifact</artifactId>
<version>1.1.0-123</version>
<profiles>
<profile>
<id>arse-version</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<id>parse-version</id>
<goals>
<goal>parse-version</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>validate</phase>
<id>set-version</id>
<goals>
<goal>set</goal>
<goal>commit</goal>
</goals>
</execution>
</executions>
<configuration>
<newVersion>${parsedVersion.osgiVersion}-${BUILD_NUMBER}</newVersion>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
我创建了一个配置文件 arse-version
(这实际上是在我的公司 pom.xml 中,它是我们所有项目的父级),它添加了 build-helper-maven-plugin
和 versions-maven-plugin
插件。我将它们都设置为在 validate
生命周期中执行。
现在,要在 Jenkins 中设置附加了内部版本号的版本,我可以执行这个:
$ mvn -Parse-version -DBUILD_NUMBER=$BUILD_NUMBER validate
这在管道构建和 Jenkinsfile
中非常有效。不需要单独的 shell 或 Python 脚本。无需担心 xpath
或 xmllint
是否以特定方式安装和工作(它在我的 Mac 和 Linux 上的工作方式不同)。
我的主要问题是版本号一直在重建,而不是拿走那里的东西。如果开发人员将版本设置为 1.0
而这是构建 #23,我将获得版本 1.0.0-23
。如果开发者放 1.2-3, I get
1.2.3-23`。因此,我将简单地告诉所有开发人员,他们现在必须使用标准的三部分版本编号方案。
简洁明了。感谢
注意:编辑以添加 commit
目标。这将从工作区中删除 backup pom.xml。
回答实际问题:
基于@djeikyb 在 xml - xmllint failing to properly query with xpath - Stack Overflow 的务实评论,这对我有用:
sed < pom.xml '2 s/xmlns=".*"//g' | xmllint --xpath '/project/version/text()' - 2>/dev/null
而且我仍然感到困惑,为什么 xml 使用我认为是为该任务设计的工具进行这样的解析,如果没有这种混乱,实际上就无法工作......
对每个 xml 节点使用 local-name()
函数。
Old-XPath: /project/version/text()
New-XPath: /*[local-name()="project"]/*[local-name()="version"]/text()
现在 运行 在 bash shell 你会得到
$ xmllint --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()' pom.xml
1.0.0-SNAPSHOT