Maven Release Plugin use in Jenkins Pipeline
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!):
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.
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.
Using Multibranch Pipeline with the versioning technique mentioned here is more in line with continuous delivery: https://axelfontaine.com/blog/dead-burried.html
Using the versioning technique above, the pom.xml now looks like this:
<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:
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-up on how to configure a Multibranch Pipeline.
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.
Also, check out: https://maven.apache.org/maven-ci-friendly.html
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).
Here is who I did it: I checked if the last commit contains "[maven-release-plugin]" in the comment.
Code in 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...>
}