How to get maven version in Jenkins email notification when using emailext - jenkins-pipeline

How to get maven version in Jenkins email notification using emailext. I need to print the maven version, project is using, in the email notification.
Please suggest.

If I am getting this right ,you can simply run the command and put it in a varible and use it in the text you are sending. eg.
mvnVersion = sh (
script: "mvn -version",
returnStdout: true
).trim()
emailText = "this is the mvn version - ${mvnVersion}"
if you want any specific information you can always use replaceAll() to get it .

Added below code to my groovy email template. It worked, fetched the maven version from the project pom in the email.
<% def variable = new XmlSlurper().parse(new File("/var/jenkins_home/jobs/projectName/pom.xml"))
def param = new hudson.model.StringParameterValue("MAVEN_VERSION", variable.prerequisites.maven.toString())
def version = param.getValue() %>
<tr>
<td>Maven:</td>
<td>${version}</td>
</tr>

Related

I want to run many SOAPUI project xmls using Gradle script, in Linux

I want to run the SOAPUI project xmls using Gradle script. The GRADLE script should read the project xmls from soapuiInputs.properties file and run automatically all. Please guide me step by step how to create Gradle script to run the SOAPUI projects in Linux server.
Note: We use SOAPUI version 5.1.2.
Probably the simple way is to call the SOAPUI testrunner directly from gradle as Exec task, like you can do from cli.
In gradle you can define the follow tasks (Note that I try it on windows but to do the same on linux as you ask simply you've to change the paths):
// define exec path
class SoapUITask extends Exec {
String soapUIExecutable = 'C:/some_path/SoapUI-5.2.1/bin/testrunner.bat'
String soapUIArgs = ''
public SoapUITask(){
super()
this.setExecutable(soapUIExecutable)
}
public void setSoapUIArgs(String soapUIArgs) {
this.args = "$soapUIArgs".trim().split(" ") as List
}
}
// execute SOAPUI
task executeSOAPUI(type: SoapUITask){
// simply pass the project path as argument,
// note that the extra " are needed
soapUIArgs = '"C:/location/of/project.xml"'
}
To run this task use gradle executeSOAPUI.
This task simply runs a SOAPUI project, however testrunner supports more parameters which you can pass to soapUIArgs string in executeSOAPUI task, take a look here.
Instead of this if you want to deal with more complex testing there is a gradle plugin to launch SOAPUI project, take a look on it here
Hope this helps,

How to upload file to artifactory generic repository with gradle?

I build app distribution with gradle, which a tar file contains everything needed. I created a generic repository in artifactory. I want to upload the tarball to the generic repository.
By looking up this documentation
http://www.jfrog.com/confluence/display/RTF/Gradle+Artifactory+Plugin
I didn't find a way to do so.
I am a new gradle and artifactory user, can anyone give me guide.
task uploadDistroTar(type: org._10ne.gradle.rest.RestTask) {
httpMethod = 'PUT'
uri = 'http://x.x.x.x:8081/artifactory/repo/foo.tar'
username = 'admin'
password = 'passwd'
requestContentType = groovyx.net.http.ContentType.BINARY
requestBody = new File("build/distributions/foo.tar").bytes
}
The easiest way will be to use the Gradle REST plugin. Just use the PUT request to upload the file to the repository you want.
More modern solution is to use Artifactory Java Client:
Artifactory artifactory = ArtifactoryClientBuilder.create()
.setUrl("ArtifactoryUrl")
.setUsername("username")
.setPassword("password")
.build();
java.io.File file = new java.io.File("fileToUpload.txt");
File result = artifactory.repository("RepoName").upload("path/to/newName.txt", file).doUpload();
Finally I find the solution by read the plugin's source code,
just set:
preemptiveAuth = true

groovy.lang.MissingPropertyException: No such property: manager for class: Script1

I am trying to invoke Groovy inside Hudson (using groovy plugin) to get some properties for our build. But I am getting this exception:
groovy.lang.MissingPropertyException: No such property: manager for class: Script1
I get this with the following line:
def buildNUmber = manager.build.number
This happens when I run as an inline command within Jenkins as well as using a script:
I tried the solution below, but it fails during the declaration itself (line two):
Binding binding = new Binding();
binding.setVariable("manager", manager);
GroovyShell shell = new GroovyShell(binding);
shell.evaluate(new File("d:/dev/others/hudson/userContent/ScriptStuff.groovy").text);
The above is run using: Groovy command. And when I run the build it errors and complains about the line - binding.setVariable("manager", manager);
When I use the Groovy script file, then it complains about:
def buildNumber = manager.build.number
Both errors are :
groovy.lang.MissingPropertyException: No such property: manager for class: Script1
Tried everything mentioned in this thread as well:
I am using Hudson 2.2.1 and Groovy 2.1.3. What could be wrong?
manager is provided by certain Groovy script plugins, but not all. To make your script generic, use the Jenkins/Hudson API instead:
import hudson.model.*
def build = Thread.currentThread().executable
def buildNumber = build.number
...
Just in case it helps, if you are using the 'Execute System Groovy Script', you don't need to use the 'manager' variable. This worked for me -
def workspace = build.getEnvVars()["WORKSPACE"]
One of the reasons groovy.lang.MissingPropertyException: is thrown when you are using a variable outside of its scope or you haven't defined that variable.
Maybe I'm missing some part of your code, but where do you define the manager? If that's the complete Groovy script, you're trying to bind a variable which isn't declared anything, so it isn't surprising that it fails.
Just define a manager it that's what you want, like:
def manager = "my manager" // probably not what you want
This should solve your current error.

project version from maven to sonar using hudson

i am using maven2 , hudson and sonar
while doing sonar analysis - i would like some way to append the Hudson build# to the maven version of the project
The project version changes every 2 weeks - so take an example in the first 2 weeks :
<version>abc-SNAPSHOT</version>
after two weeks the next version could be something like :
<version>xyz-SNAPSHOT</version>
what I want is to append the build# to the version already present in pom - which is being picked up and passed to sonar
NOTE:
-Dsonar.projectVersion=xyz-SNAPSHOT-${BUILD_NUMBER}
Here - I am hardcoding the version and dynamically passing the build#
what I want is to be able to dynamically pick up the version from maven ( without changing it ) and simply appending the build# dynamically
any ideas of how this can be achieved ?
Thanks,
satish
You can use Groovy script to read the version and put on environment variable:
Getting Maven Version in Jenkins
I used this script on time to parse the version:
def project = new XmlParser().parse("/pom.xml")
def artifactId = project.artifactId.text().trim()
def version = project.version.text().trim()
println "ArtifactId: [" + artifactId + "]"
println "Version: [" + version + "]"
After set "Additional properties" field with:
-Dsonar.projectVersion=${MAVEN_VERSION}-${BUILD_NUMBER}
If Jenkins don't get the variable, try install:
https://wiki.jenkins-ci.org/display/JENKINS/EnvInject+Plugin
You can use this Jenkins feature: https://github.com/jenkinsci/jenkins/pull/933/files
Basically you can access env variables at build, mapped by Jenkins from Maven GAV info
POM_DISPLAYNAME
POM_DISPLAYNAME
POM_VERSION
POM_GROUPID
POM_ARTIFACTID
POM_PACKAGING
POM_RELATIVEPATH
This is not really a Sonar issue. It's Maven project versioning.
Snaphots are designed to be dynamic. You'll discover under the hood that Maven is saving time-stamped versions in your Maven repository (I don't know how these time-stamps could be passed onto Sonar, which perhaps is what you'd like). Snapshot builds are ideal for CI jobs. software that is never used by non-developers.
What's I'd recommend is either stop using snapshots (build a "release" each time), or just accept the fact that there are two kinds of build in Maven. My rule is that if the code is being used by others then it's no longer a snapshot and should be treated as a release. This creates challenges for emerging methodologies like continuous deployment..... If every build goes to production (or production copy) then snapshots become irrelevant.
Building a release everytime is not that bad. First of all naming convention, I'd recommend:
<major>.<minor>.<patch>.<hudson build num>
The Maven's release plugin will automate most of the pain in managing the details of the release (updating the POM, tagging your SCM system). Finally there is also a useful M2_Release plugin that enables you to trigger a release from Hudson GUI.
Thanks To Andre for pointing me to the other link
I did try it but was running into some issues as noted in the comments
Assuming what I have done is just a workaround and there is a better solution ?
( I am using Hudson )
So I defined a new Job in Hudson ( Build a Maven 2/3 project (Legacy) )
Here I defined a "Groovy PostBuild"
Copied the code in the link that Andre pointed me to :
import hudson.model.*;
import hudson.util.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def mavenVer = currentBuild.getParent().getModules().toArray()[0].getVersion();
def newParamAction = new hudson.model.ParametersAction(new
hudson.model.StringParameterValue("MAVEN_VERSION", mavenVer));
currentBuild.addAction(newParamAction);
I then "Trigger parameterized build on other projects " and mentioned the job in which I wanted the maven version as mentioend in the pom
Defined a parameter - ${MAVEN_VERSION}
I was then able to get the value of this parameter in the "other" job
So first thanks to Andre - he provided me a solution
I am curious to know if this is a good approach
another question I have is ( which maybe I will start a new thread ) is - how does a Hudson "Free style" job differ from a "Maven 2/3 legacy project"
The reason I ask is the same Groovy script failed in a "free style" while it worked in a "Maven legacy"
Thanks,
satish
Had the same need and solved as suggested with Groovy parsing the pom.
import jenkins.util.*;
import jenkins.model.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def workspace = currentBuild.getModuleRoot().absolutize().toString();
def project = new XmlSlurper().parse(new File("$workspace/pom.xml"))
def param = new hudson.model.StringParameterValue("project.version", project.version.toString())
currentBuild.addAction(new hudson.model.ParametersAction(param));
Add this script as a post step of type "Execute system Groovy script" (so it's not needed to install Groovy) and paste the code in the "Groovy command".

Getting Project Version from Maven POM in Jenkins

Is there any way a Jenkins build can be aware of the Maven version number of a project after processing the POM?
I've got some projects where versioning is controlled by Maven, and in a post-build job we'd like to create a Debian package and call some shell scripts. What I need is for the version number that Maven used to be available as a Jenkins environment variable so I can pass it to post-build actions.
To be clear, I'm not needing to know how to get Jenkins to pass a version number to Maven; instead I want Maven to pass a version number to Jenkins!
You can use the ${POM_VERSION} variable, which was introduced with https://issues.jenkins-ci.org/browse/JENKINS-18272
After a lot of digging around (I never realised how poorly-documented Jenkins is!) I found a quite trivial solution.
Install the Groovy plugin
Add a Post Step to your Maven build of type Execute **system** Groovy script
Paste in the following snippet of Groovy:
Script:
import hudson.model.*;
import hudson.util.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def mavenVer = currentBuild.getParent().getModules().toArray()[0].getVersion();
def newParamAction = new hudson.model.ParametersAction(new hudson.model.StringParameterValue("MAVEN_VERSION", mavenVer));
currentBuild.addAction(newParamAction);
The build environment variable called MAVEN_VERSION will now be available for substitution into other post-build steps in the usual manner (${MAVEN_VERSION}). I'm using it for Git tagging amongst other things.
As other answers already pointed out, if you are using the Maven project type, you have access to the $POM_VERSION variable. But if you are not, you can use this sequence of steps (ugly but reliable). Doing it this way relies on the same version of maven to determine the pom version (while handling complex parent/child pom inheritance where <version> may not even be present for the child).
Maven step with this goal:
org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version -l version.log
Shell step: (You may need to adjust the path to version.log depending on your hierarchy)
echo "POM_VERSION=$(grep -v '\[' version.log)" > props.properties
Inject Environment Variables step (Environment Injector Plugin):
Properties File Path: props.properties
Now you can use $POM_VERSION as if this were a Maven project.
What this does: Uses maven to print out the version together with a mess of output, then greps out the mess of output leaving just the version, writes it to a file using properties file format and then injects it into the build environment. The reason this is better than a one-liner like mvn ..... | grep -v '\[' is that using a Maven step does not make assumptions about the installed maven versions and will be handled by the same auto-installation as any other maven steps.
I used Pipeline Utility Steps plugin in a declarative pipeline job to get Maven version. In the example below I use script variable instead of environment variable, because that can be modified and passed between stages.
def TAG_SELECTOR = "UNINTIALIZED"
pipeline {
agent any
stages {
stage('Build') {
steps {
sh "mvn --batch-mode -U deploy"
script {
TAG_SELECTOR = readMavenPom().getVersion()
}
echo("TAG_SELECTOR=${TAG_SELECTOR}")
}
}
}
}
Note: You must approve the getVersion() method after creating the job in Manage jenkins > In-process Script Approval.
See also:
readMavenPom documentation
We used the Groovy Postbuild Plugin.
String regex = '.*\\[INFO\\] Building .+ (.+)';
def matcher = manager.getLogMatcher(regex);
if (matcher == null) {
version = null;
} else {
version = matcher.group(1);
}
Adding this to Jenkins for use later is a bit tricky. Give this a shot, although I remember this causing us some headaches. (Sorry, we did this a long time ago)
def addBuildParameter(String key, String value) {
manager.build.addAction(new hudson.model.ParametersAction(new hudson.model.StringParameterValue(key,value)));
}
Had the same need and solved as suggested with Groovy parsing the pom.
import jenkins.util.*;
import jenkins.model.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def workspace = currentBuild.getModuleRoot().absolutize().toString();
def project = new XmlSlurper().parse(new File("$workspace/pom.xml"))
def param = new hudson.model.StringParameterValue("project.version", project.version.toString())
currentBuild.addAction(new hudson.model.ParametersAction(param));
Add this script as a post step of type "Execute system Groovy script" (so it's not needed to install Groovy) and paste the code in the "Groovy command".
Execute the Maven Plugin "exec-maven-plugin" in "Execute Shell" as a "Conditional step" worked for me:
mvn -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec
Integrate in Jenkins:
-> "Add post-build step"
-> "Conditional steps (single or multiple)"
-> "Execute Shell:"
export MY_POM_VERSION=`mvn -q -Dexec.executable="echo"
-Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` && [[
"${MY_POM_VERSION}" == "THE_VERSION_TO_BE_MATCHED" ]] && echo
"CONDITION_IS_MET"
-> "Steps to run if condition is met"
-> Add any build step you need
Notes:
THE_VERSION_TO_BE_MATCHED has to exchanged with your version
'&& echo "CONDITION_IS_MET"' is only for debugging purposes. For the same purpose you can add a '&& echo "MY_POM_VERSION=${MY_POM_VERSION}"' after the mvn command in order to understand what's going on.
This approach is more reliable than a "grep" and it could be an alternative if the Jenkins Ruby Plugin is not installed.
You could also do :
MAVEN_VERSION=`grep A -2 -B 2 "<your_project_name>" pom.xml | grep version | cut -d\> -f 2 | cut -d\< -f 1`-commit-"`echo $GIT_COMMIT`"
Explanation: assuming that you have your project name within a line or two above/below version like a normal pom:
<groupId>org.apache.bigtop</groupId>
<artifactId>bigpetstore</artifactId>
<version>1.0-SNAPSHOT</version>
Then you can easily grep for the artifactId, use the "before/after" grep actions to suck in the version with it, and then grep the version out and use the simple unix "cut" command to splice out the content between "version" tags.
I like the Jenkins-groovy integration, but this is alot easier and will work even on a build server which you dont have control over (i.e. because bash is universal).
Solution:
POM_VERSION=$( \
xmlstarlet sel \
-N x='http://maven.apache.org/POM/4.0.0' \
-t \
-v '//x:project/x:version/text()' \
pom.xml \
)
Explanation:
You can do this in a one-liner using a command-line XPath tool, such as those mentioned at "How to execute XPath one-liners from shell?". I chose XMLStarlet, but they all have similar syntax.
When parsing a POM, you have to account for namespaces. The docs here helped me figure this out.
In order to get the text for an element in XPath, you use the text() function as explained at XPath: select text node.
My POM looks like this:
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo.bar</groupId>
<artifactId>foobar</artifactId>
<version>1.0.6-SNAPSHOT</version>
<packaging>jar</packaging>
The downside here is that if the namespace changes, you have to change the command.
Using 'Execute System Groovy Script' as follows:
import jenkins.util.*;
import jenkins.model.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def projectManager = build.getProject()
def file = projectManager.getWorkspace().child("pom.xml");
def project = new XmlSlurper().parseText(file.readToString())
def param = new hudson.model.StringParameterValue("currentVersion", project.version.toString())
currentBuild.addAction(new hudson.model.ParametersAction(param));
By using Execute System Groovy script you have direct access to the build, from which you can get the project and thus the "child" file in this case pom.xml.
You won't have to create a new file and as you can see it offers very powerful access to every file within the workspace.
Based on #Akom`s answer the pre steps to have POM_VERSION are:
"Inject environment variables" with property
file your_property_file. Note if you select "Inject environment variables to the build process" the file needs to exist in the jenkins workspace.
run in a pre step execute shell the follwing
bash script.
Script
mvn org.apache.maven.plugins:maven-help-plugin:evaluate -Dexpression=project.version -l project_version
# grep for the version pattern rather than not mentioning '\['
echo "POM_VERSION=$(grep -E '^[0-9.]+(-SNAPSHOT)?$' project_version)" > your_property_file

Resources