Maven Release Plugin 在 Jenkins Pipeline 中的使用
Maven Release Plugin use in Jenkins Pipeline
我正在使用 Jenkins Pipeline 自动构建和部署我的 Java 应用程序。我还使用 maven-release-plugin 执行 Maven 部署到 Artifactory。
问题是我的 Jenkinsfile(或 Jenkins 管道配置):
- 我们在发布分支上提交版本 0.1.00-SNAPSHOT
- Jenkins Pipeline获取代码,执行maven发布
- Maven Release 将版本更改为 0.1.00
- Maven 发布标签GIT 分支、提交和部署工件
- Maven Release 将版本更改为 0.2.00-SNAPSHOT 并提交
- Jenkins Pipeline 检测到 GIT 中的变化,因此触发新构建
您了解最后一步会创建一个无限循环,即使没有有用的提交也是如此。
这是我的 Jenkinsfile 中有趣的部分:
sshagent([git_credential]) {
sh "${maven_bin} --settings ${maven_settings} -DreleaseVersion=${release_version} -DdevelopmentVersion=${development_version} release:prepare release:perform -B"
}
我如何打破循环(避免 Jenkins 在 Maven 在 GIT 上提交时触发新构建)?
谢谢
感谢 ,我发现 Jenkins 提供了 GIT 轮询的选项。一个正是我所需要的(提供的示例是针对 maven-release-plugin 的!):
一个解决方案可以是更改调用 jenkins URL 通知的 post-receive 挂钩:
#!/bin/bash
git_log=$(git log --branches -1)
if ! [[ $git_log =~ .*maven-release-plugin.* ]] ;
then
curl http://buildserver:8080/git/notifyCommit?url=ssh://git@server:22/projects/Name.git;
fi
以防有人遇到与循环相同的问题或后续构建被触发但有一个触发器在每次推送到存储库时启动 jenkins 管道(而不是轮询)。
这是我做的:我检查了最后一次提交是否在评论中包含“[maven-release-plugin]”。
jenkinsfile 中的代码:
def lastCommit = sh returnStdout: true, script: 'git log -1 --pretty=%B'
if (lastCommit.contains("[maven-release-plugin]")){
sh "echo Maven release detected" //dont trigger build
} else {
sh "echo Last commit is not from maven release plugin" //do build steps
<..build Job...>
}
恕我直言,随着 git 和拉取请求的出现,我认为将 maven-release-plugin 或 maven-version-plugin 与 Jenkins 管道一起使用不是一个好主意。
使用Multibranch Pipeline和这里提到的版本控制技术更符合持续交付:
https://axelfontaine.com/blog/dead-burried.html
使用上面的版本控制技术,pom.xml 现在看起来像这样:
<project>
...
<version>${revision}</version>
<properties>
<!-- Sane default when no revision property is passed in from the commandline -->
<revision>0-SNAPSHOT</revision>
</properties>
<scm>
<connection>scm:git:your-git-repo-url</connection>
</scm>
<distributionManagement>
<repository>
<id>artifact-repository</id>
<url>your-artifact-repo-url</url>
</repository>
</distributionManagement>
<build>
<plugins>
<plugin>
<artifactId>maven-scm-plugin</artifactId>
<version>1.9.5</version>
<configuration>
<tag>${project.artifactId}-${project.version}</tag>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
您现在可以非常轻松地在 Jenkins 服务器上生成版本,方法是使用 Jenkinsfile 配置多分支管道以在所有分支上构建并仅从主分支部署:
pipeline {
agent any
environment {
REVISION = "0.0.${env.BUILD_ID}"
}
triggers {
pollSCM('')
}
options {
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '30'))
}
tools {
maven '3.5.2'
jdk 'jdk8'
}
stages {
stage ('Initialize') {
steps {
sh '''
echo "PATH = ${PATH}"
echo "M2_HOME = ${M2_HOME}"
'''
}
}
stage ('Build') {
steps {
sh 'mvn clean package'
}
}
stage ('Deploy') {
when {
branch 'master'
}
steps {
script {
currentBuild.displayName = "${REVISION}"
}
sh 'mvn deploy scm:tag -Drevision=${REVISION}'
}
}
}
}
请参阅https://jenkins.io/blog/2017/02/07/declarative-maven-project/#set-up了解如何配置多分支管道。
使用这种技术,您只能在非主分支上进行开发。然后创建一个拉取请求以将您的更改合并回 master 分支。这应该会自动将您的工件部署到您的工件存储库。
附录
使用上述方法发布到 Maven 存储库时,pom.xml 将没有正确的版本。要让 Maven 发布正确的版本,请使用 flatten-maven-plugin:http://www.mojohaus.org/flatten-maven-plugin/usage.html.
这是我们在管道中放置的第一阶段:
stage('Check commit message') {
when { changelog '.*\[maven-release-plugin\].*' }
steps {
script {
pom = readMavenPom file: 'pom.xml'
currentBuild.displayName = pom.version
currentBuild.result = 'NOT_BUILT'
}
error('Skipping release build')
}
}
您需要安装 https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/ 插件来读取 maven pom,或者只是为跳过的构建添加一个固定的描述。发布后的版本将呈灰色。
我正在使用 Jenkins Pipeline 自动构建和部署我的 Java 应用程序。我还使用 maven-release-plugin 执行 Maven 部署到 Artifactory。
问题是我的 Jenkinsfile(或 Jenkins 管道配置):
- 我们在发布分支上提交版本 0.1.00-SNAPSHOT
- Jenkins Pipeline获取代码,执行maven发布
- Maven Release 将版本更改为 0.1.00
- Maven 发布标签GIT 分支、提交和部署工件
- Maven Release 将版本更改为 0.2.00-SNAPSHOT 并提交
- Jenkins Pipeline 检测到 GIT 中的变化,因此触发新构建
您了解最后一步会创建一个无限循环,即使没有有用的提交也是如此。
这是我的 Jenkinsfile 中有趣的部分:
sshagent([git_credential]) {
sh "${maven_bin} --settings ${maven_settings} -DreleaseVersion=${release_version} -DdevelopmentVersion=${development_version} release:prepare release:perform -B"
}
我如何打破循环(避免 Jenkins 在 Maven 在 GIT 上提交时触发新构建)?
谢谢
感谢
一个解决方案可以是更改调用 jenkins URL 通知的 post-receive 挂钩:
#!/bin/bash
git_log=$(git log --branches -1)
if ! [[ $git_log =~ .*maven-release-plugin.* ]] ;
then
curl http://buildserver:8080/git/notifyCommit?url=ssh://git@server:22/projects/Name.git;
fi
以防有人遇到与循环相同的问题或后续构建被触发但有一个触发器在每次推送到存储库时启动 jenkins 管道(而不是轮询)。
这是我做的:我检查了最后一次提交是否在评论中包含“[maven-release-plugin]”。
jenkinsfile 中的代码:
def lastCommit = sh returnStdout: true, script: 'git log -1 --pretty=%B'
if (lastCommit.contains("[maven-release-plugin]")){
sh "echo Maven release detected" //dont trigger build
} else {
sh "echo Last commit is not from maven release plugin" //do build steps
<..build Job...>
}
恕我直言,随着 git 和拉取请求的出现,我认为将 maven-release-plugin 或 maven-version-plugin 与 Jenkins 管道一起使用不是一个好主意。
使用Multibranch Pipeline和这里提到的版本控制技术更符合持续交付: https://axelfontaine.com/blog/dead-burried.html
使用上面的版本控制技术,pom.xml 现在看起来像这样:
<project>
...
<version>${revision}</version>
<properties>
<!-- Sane default when no revision property is passed in from the commandline -->
<revision>0-SNAPSHOT</revision>
</properties>
<scm>
<connection>scm:git:your-git-repo-url</connection>
</scm>
<distributionManagement>
<repository>
<id>artifact-repository</id>
<url>your-artifact-repo-url</url>
</repository>
</distributionManagement>
<build>
<plugins>
<plugin>
<artifactId>maven-scm-plugin</artifactId>
<version>1.9.5</version>
<configuration>
<tag>${project.artifactId}-${project.version}</tag>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
您现在可以非常轻松地在 Jenkins 服务器上生成版本,方法是使用 Jenkinsfile 配置多分支管道以在所有分支上构建并仅从主分支部署:
pipeline {
agent any
environment {
REVISION = "0.0.${env.BUILD_ID}"
}
triggers {
pollSCM('')
}
options {
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '30'))
}
tools {
maven '3.5.2'
jdk 'jdk8'
}
stages {
stage ('Initialize') {
steps {
sh '''
echo "PATH = ${PATH}"
echo "M2_HOME = ${M2_HOME}"
'''
}
}
stage ('Build') {
steps {
sh 'mvn clean package'
}
}
stage ('Deploy') {
when {
branch 'master'
}
steps {
script {
currentBuild.displayName = "${REVISION}"
}
sh 'mvn deploy scm:tag -Drevision=${REVISION}'
}
}
}
}
请参阅https://jenkins.io/blog/2017/02/07/declarative-maven-project/#set-up了解如何配置多分支管道。
使用这种技术,您只能在非主分支上进行开发。然后创建一个拉取请求以将您的更改合并回 master 分支。这应该会自动将您的工件部署到您的工件存储库。
附录
使用上述方法发布到 Maven 存储库时,pom.xml 将没有正确的版本。要让 Maven 发布正确的版本,请使用 flatten-maven-plugin:http://www.mojohaus.org/flatten-maven-plugin/usage.html.
这是我们在管道中放置的第一阶段:
stage('Check commit message') {
when { changelog '.*\[maven-release-plugin\].*' }
steps {
script {
pom = readMavenPom file: 'pom.xml'
currentBuild.displayName = pom.version
currentBuild.result = 'NOT_BUILT'
}
error('Skipping release build')
}
}
您需要安装 https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/ 插件来读取 maven pom,或者只是为跳过的构建添加一个固定的描述。发布后的版本将呈灰色。