我想通过 gitlab CI 构建 docker 镜像,项目版本作为标签:
docker build -t dockerimage:VERSION-IN-POM .
在 Jenkins 的管道中,我得到了这样的版本:
${pom.version}
是否可以从 gitlab CI 以类似、方便的方式读取版本?还是我必须为此编写脚本?
假设你在构建环境中有 maven,你可以使用 maven 帮助插件和 grep 来提取版本。
VERSION=$(mvn --non-recursive help:evaluate -Dexpression=project.version | grep -v '[.*')
echo $VERSION
这对我的变量有用:gitlab-ci.yml
mvn -Dexec.executable='echo' -Dexec.args='${project.version}' --non-recursive exec:exec -q
Gitlab-CI 没有提供这样的舒适感,相反,它让你使用 shell 脚本做任何你想做的事情。在命令脚本中做到这一点并不难。你可以安装 xmllint(apt install libxml2-utils
在 Ubuntu 上(,然后你可以通过一个简单的查询来获取它:
xmllint --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()' pom.xml
所以这两条线都可以解决:
- apt install libxml2-utils
- docker build -t dockerimage:$(xmllint --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()' pom.xml) .
另一个直接获取版本信息的 maven 命令行替代方案
mvn --non-recursive help:evaluate -Dexpression=project.version -q -DforceStdout
您可以使用 sed 或 grep。
它比使用mvn --non-recursive help:evaluate ...
更快
获取项目 ID
grep -m1 '<artifactId>' pom.xml | grep -oP '(?<=>).*(?=<)'
获取版本
grep -m1 '<version>' pom.xml | grep -oP '(?<=>).*(?=<)'
如果您使用的是 docker,则某些映像没有最新版本的 grep,因此您需要使用带有 cut 的创意解决方案,例如:
grep -m1 '<artifactId>' pom.xml |cut -d '<' -f2 |cut -d '>' -f2
您可以在.gitlab-ci.yml
文件中使用以下命令:
VERSION=$(mvn --non-recursive help:evaluate -Dexpression=project.version -q -DforceStdout)
echo $VERSION
此外,您可以通过将Dexpression=project.version
更改为Dexpression=project.artifactId
和Dexpression=project.groupId
来获得groupId
和artifactId
有关更多信息,请参阅 maven 文档以获取帮助:评估。
正如 Ivan 在他的帖子中指出的那样,这在我的脚本中有效:
-RELEASE_VERSION=xmllint --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()' pom.xml
-echo $RELEASE_VERSION
如果你知道项目名称,这里是另一种使用shell的方法;是从./target目录下创建的目标.jar文件中剪切版本。
注意:这只有在成功构建命令后才有效:
cd target
version=`ls <PROJECT_NAME>*.jar`
version=${version#<PROJECT_NAME>}
version=${version%.jar}
cd ..
echo $version
我最终使用了
vars:
stage: prepare
script:
- echo "POM_VERSION=$(mvn -Dexec.executable='echo' -Dexec.args='${project.version}' --non-recursive exec:exec -q)" > vars.env
- echo "POM_NAME=$(mvn -Dexec.executable='echo' -Dexec.args='${project.name}' --non-recursive exec:exec -q)" >> vars.env
- echo "POM_GROUP_ID=$(mvn -Dexec.executable='echo' -Dexec.args='${project.groupId}' --non-recursive exec:exec -q)" >> vars.env
- echo "POM_ARTIFACT_ID=$(mvn -Dexec.executable='echo' -Dexec.args='${project.artifactId}' --non-recursive exec:exec -q)" >> vars.env
artifacts:
reports:
dotenv: vars.env
这是Maven帮助的解决方案:评估但有一个正则表达式(参见命令中的"-E"(:
export VERSION=$(mvn --non-recursive help:evaluate -Dexpression=project.version | grep -E '^[0-9]+.[0-9]+.[0-9]+(-[A-Z]+)?$')
echo $VERSION
它将能够在Maven命令的输出中找到例如5.0.1-SNAPHOT或仅5.0.1或5.0.1-GA。
在这种逼真的 Maven 输出上测试:
Downloaded from fodfin: http://your.server/artifactory/com/thoughtworks/xstream/xstream/1.4.11.1/xstream-1.4.11.1.jar (621 kB at 369 kB/s)
[INFO] No artifact parameter specified, using 'be.test.super.package:the-application:pom:5.0.1-SNAPSHOT' as project.
[INFO]
5.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15.127 s
[INFO] Finished at: 2022-10-06T14:40:29+02:00
[INFO] ------------------------------------------------------------------------
jobname:
stage: stage
before_script:
- export "MAVEN_ID=$(mvn help:evaluate -Dexpression=project.id -q -DforceStdout)"
- >
IFS=: read -r MAVEN_GROUPID MAVEN_ARTIFACTID MAVEN_PACKAGING MAVEN_VERSION <<< ${MAVEN_ID}
script:
- >
echo -e "groupId: ${MAVEN_GROUPID}nartifactId: ${MAVEN_ARTIFACTID}nversion: ${MAVEN_VERSION}npackaging: ${MAVEN_PACKAGING}"
mvn help:evaluate -Dexpression=project.id -q -DforceStdout
以下列格式打印项目标识信息:com.group.id:artifactid:packaging:version
MAVEN_ID
变量使用基于冒号(:
(的IFS
作为分隔符进行解析,以获取常见的maven变量,如artifactId,groupId,版本和打包(解释(- 稍后可以在代码中使用这些变量,例如用于回显值
- 这样 Maven 只需执行 1 次即可获取信息,可以加快流水线
- IFS 是一个 bash 功能,因此相应的 GitLab 运行器应该安装 bash 。