git Maven Release Plugin 在 Jenkins Pipeline 中的使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39161285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Maven Release Plugin use in Jenkins Pipeline
提问by frinux
I'm using Jenkins Pipeline to automatically build and deploy my Java apps. I also use maven-release-plugin to perform Maven deploy to Artifactory.
我正在使用 Jenkins Pipeline 自动构建和部署我的 Java 应用程序。我还使用 maven-release-plugin 将 Maven 部署到 Artifactory。
The problem is my Jenkinsfile (or Jenkins Pipeline Configuration) :
问题是我的 Jenkinsfile(或 Jenkins 管道配置):
- We commit a version 0.1.00-SNAPSHOT on release branch
- Jenkins Pipeline get the code, and perform maven release
- Maven Release changes the version to 0.1.00
- Maven Release tags GIT branch, commit and deploy the artifact
- Maven Release changes the version to 0.2.00-SNAPSHOT and commit
- Jenkins Pipeline detect a change in GIT, so triggers a new build
- 我们在发布分支上提交了 0.1.00-SNAPSHOT 版本
- Jenkins Pipeline 获取代码,并执行maven发布
- Maven Release 将版本更改为 0.1.00
- Maven Release 标记 GIT 分支,提交和部署工件
- Maven Release 将版本更改为 0.2.00-SNAPSHOT 并提交
- Jenkins Pipeline 检测到 GIT 中的更改,因此触发新构建
You understood that the last step creates an infinite loop, even if there is no useful commit.
你知道最后一步会创建一个无限循环,即使没有有用的提交。
Here is the interesting part of my Jenkinsfile :
这是我的 Jenkinsfile 有趣的部分:
sshagent([git_credential]) {
sh "${maven_bin} --settings ${maven_settings} -DreleaseVersion=${release_version} -DdevelopmentVersion=${development_version} release:prepare release:perform -B"
}
How can I break the loop (avoid Jenkins to trigger new build when Maven commits on GIT)?
如何打破循环(避免 Jenkins 在 Maven 上提交 GIT 时触发新构建)?
Thanks
谢谢
采纳答案by frinux
Thanks to @Daniel Omoto comment, I found out that Jenkins provides option for GIT polling. One is exactly what I needed (and the provided example is for maven-release-plugin!):
感谢@Daniel Omoto 评论,我发现 Jenkins 提供了 GIT 轮询选项。一个正是我需要的(并且提供的示例适用于 maven-release-plugin!):
回答by Dennis Hoer
IMHO with the advent of git and pull requests, I don't think using maven-release-plugin or maven-version-plugin with a Jenkins pipeline is a good idea.
恕我直言,随着 git 和 pull requests 的出现,我不认为将 maven-release-plugin 或 maven-version-plugin 与 Jenkins 管道一起使用是个好主意。
Using Multibranch Pipeline with the versioning technique mentioned here is more in line with continuous delivery: https://axelfontaine.com/blog/dead-burried.html
使用 Multibranch Pipeline 和这里提到的版本控制技术更符合持续交付:https://axelfontaine.com/blog/dead-burried.html
Using the versioning technique above, the pom.xml now looks like this:
使用上面的版本控制技术, 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>
You can now produce releases on your Jenkins server very easily by configuring a Multibranch Pipeline with a Jenkinsfile to build on all branches and deploy only from master branch:
您现在可以通过使用 Jenkinsfile 配置多分支管道以在所有分支上构建并仅从主分支部署,从而非常轻松地在 Jenkins 服务器上生成版本:
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}'
}
}
}
}
See https://jenkins.io/blog/2017/02/07/declarative-maven-project/#set-upon how to configure a Multibranch Pipeline.
有关如何配置多分支管道的信息,请参阅https://jenkins.io/blog/2017/02/07/declarative-maven-project/#set-up。
With this technique you develop only on non-master branches. Then create a pull request to merge your changes back to master branch. This should then deploy your artifact automatically to your artifact repository.
使用这种技术,您只能在非主分支上进行开发。然后创建一个拉取请求将您的更改合并回主分支。然后这应该自动将您的工件部署到您的工件存储库。
Addendum
附录
When publishing to a Maven repository using the above method, the pom.xml will not have the proper version. To get Maven to publish the proper version, use the flatten-maven-plugin: http://www.mojohaus.org/flatten-maven-plugin/usage.html.
使用上述方法发布到 Maven 存储库时,pom.xml 将没有正确的版本。要让 Maven 发布正确的版本,请使用 flatten-maven-plugin:http: //www.mojohaus.org/flatten-maven-plugin/usage.html。
Also, check out: https://maven.apache.org/maven-ci-friendly.html
回答by Daniel F?hr
In case somebody has the same problem with the loop or that subsequent builds get triggered BUT has a Trigger who starts the jenkins pipeline on every push to the repository (Instead of polling).
如果有人对循环有同样的问题,或者后续构建被触发,但有一个触发器,它在每次推送到存储库时启动 jenkins 管道(而不是轮询)。
Here is who I did it: I checked if the last commit contains "[maven-release-plugin]" in the comment.
这是我做的:我检查了最后一次提交是否在评论中包含“[maven-release-plugin]”。
Code in jenkinsfile:
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...>
}
回答by anydoby
This is is what we put as a first stage in our pipeline:
这是我们在管道中作为第一阶段的内容:
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')
}
}
You will need to install https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/plugin to read maven pom, or just put a fixed description for the skipped build. The build following the release will have grey colour.
您需要安装https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/插件来读取 maven pom,或者只是为跳过的构建添加固定描述。发布后的构建将具有灰色。
回答by user2131878
A solution can be to change the post-receive hook that is calling the notification URL of jenkins:
解决方案可以是更改调用 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