How to access maven property from Jenkins? - maven

I have a maven project in which I have a property. I want to access it from Jenkins.
POM snippet:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<timestamp>${build.time}</timestamp>
<outputFolder>C:/AutomationTestReports/${project.name}/ExecutionReport${timestamp}</outputFolder>
</properties>
This output folder property gets evaluated at runtime. I want to access this property in Jenkins to navigate to the output folder which gets generated as per the time stamp. For this to happen I need to capture this output folder property in Jenkins, which I am not able to do.
Using this output folder only I will be able to navigate to the folder to access the result file.
Question: How to access Maven properties from Jenkins job?

In the current version of Jenkins there is a nice and simple way to achieve this using "readMavenPom()".
For example, I want to read the version of the pom.xml file. But if it is using the newer maven "revision" practice, I need to read that "revision" value from the properties defined in the pom.xml.
def pomVersion = readMavenPom().version // read version
if (pomVersion.equals("\${revision}")) // using revision strategy, read revision property
{
pomVersion = readMavenPom().properties['revision']
}
So the best way is to use
readMavenPom().properties['PROPETY_NAME']

Jenkins Maven jobs provide by default some maven properties to be used during job configuration, however it doesn't provide any easy access to further properties defined into the pom file.
Hence, a custom approach is required. Here is a working solution which makes use of a groovy script and could be used to transform any defined Maven property into a new Jenkins variable at build time, to be then further used in additional post build steps.
Pre-requirements to this solution are:
Groovy is installed in the Jenkins server (easy step, just download it, unzip, set it to the path
The Jenkins Groovy Plugin is installed in Jenkins (easy step, Manage Jenkins > Manage Plugins, Available Plugins, install it, then configure it under Manage Jenkins > Configure System > Groovy, to make it point to the installation of step above
You can then add to the project pom the following to is build/plugins section:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>write-project-properties</goal>
</goals>
<configuration>
<outputFile>${project.build.directory}/build.properties</outputFile>
</configuration>
</execution>
</executions>
</plugin>
What are we doing? Simply using the properties-maven-plugin and its write-project-properties goal to write the project properties into a new file under the target folder (target\build.properties). Note: properties in this file will already be interpolated.
This new file will be harmless for your build and project, ignored by any other build step, removed as part of a mvn clean invocation, but yet really helpful for Jenkins.
Then, in the concerned Jenkins job you can add a new Post Steps > Execute system Groovy script (and not an Execute Groovy script, bear the difference) pointing to a new groovy file you can store where desired or type into the console the following groovy code:
import hudson.model.*;
import hudson.util.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def props = new Properties();
new File(currentBuild.workspace.toString()+"\\target\\build.properties").withInputStream {
stream -> props.load(stream);
}
println "detected from properties: "+props.get("outputFolder");
def newParamAction = new ParametersAction(new StringParameterValue("outputFolder", props.get("outputFolder")));
currentBuild.addAction(newParamAction);
What is this script doing? Simply reading the property file, printing to the console the outputFolder property as a log (to be removed, optionally) and then set it as a new Jenkins job variable with the same name (to be changed if required).
You can then use in further post build steps the ${outputFolder} new variable (or the %outputFolder% in Windows commands) and it will be correctly present.
As an example, you can debug it via a new Post Steps > Execute Windows Batch command and simply echo it. Here is a screenshot:
As output of a sample Jenkins job you would then have:
detected from properties: C:/AutomationTestReports/sample-project/Execution_(2016-04-24_12-11-13UTC)
[workspace] $ cmd /c call C:\dev\tomcat-7\temp\hudson6024790907972070905.bat
C:\Users\user-name\.jenkins\jobs\sample-maven\workspace>echo C:/AutomationTestReports/sample-project/Execution_(2016-04-24_12-11-13UTC)
C:/AutomationTestReports/sample-project/Execution_(2016-04-24_12-11-13UTC)
C:\Users\user-name\.jenkins\jobs\sample-maven\workspace>exit 0
Finished: SUCCESS

A quick and dirty solution.
Add an 'Execute Shell' step, and assign the property's value into a variable:
outputFolderVar=$(awk -F '[<>]' '/outputFolder/{print $3}' pom.xml)

environment {
OUTPUT_FOLDER = "${sh(script: 'mvn help:evaluate -Dexpression=outputFolder -q -DforceStdout', returnStdout: true)}"
}
pipeline-utility-steps

Related

Not able to pass the dynamic value from eclipse to POM

Passing the version to POM.xml.
It shows warning. 'version' contains an expression but should be a constant.
I have to remove this.
I have one Ant project and another maven project. I made one runconfiguration for Ant project where I made one variable with some value suppose 13.2.1
by opting external tool configuration that variable come in list now.now able to pass that variable like -Dversion="${versionjar}".
its working perfactly.
since this versionjar is already set in eclipse. I want to use this while I want to run the maven project by runconfiguration.
want to pass in create manage and runconfiguration like in goal section install -Dversion="${versionjar}" but its not working .
I have to set this variable here also by add button.
How can I pass the variable from eclipse command line like :install -version="${version}"? version is vailable in eclipse variable list while "${version}" is properly send to pom when it is hard coded.
"${version}" is not resolving when send in goals section of run configuration
I'm facing problem when passing the eclipse variable from command line configuration.
in POM
<version>${version}</version>
<packaging>jar</packaging>

How can I specify path to jtl files when I want to publish graph (from jmeter-graph-maven-plugin) in teamcity?

I use jmeter-maven-plugin (version 1.10.0) to run JMeter test - first I run it from IntelliJ, then from TeamCity (for both - command: mvn jmeter-graph:create-graph)
When I want to use the following configuration for jmeter-graph-maven-plugin:
<plugin>
<groupId>de.codecentric</groupId>
<artifactId>jmeter-graph-maven-plugin</artifactId>
<version>0.1.0</version>
<configuration>
<inputFile>${project.build.directory}/jmeter/results/*.jtl</inputFile>
<graphs>
<graph>
<pluginType>TransactionsPerSecond</pluginType>
<outputFile>${project.build.directory}/jmeter/results/TPS.png</outputFile>
</graph>
</graphs>
</configuration>
</plugin>
it works from IntelliJ, but in TeamCity I get:
ERROR: java.lang.IllegalArgumentException: Cannot find specified JTL file: /project/XX/opt/team-city-8.0.5/buildAgent/work/xxxxx/JMeter/target/jmeter/results/*.jtl
Result file exists (and it is previous used in xml-maven-plugin - even configuration is *.jtl - xml plugin works correctly in TeamCity).
When I use specific file name (so e.g. 20150317test-result.jtl instead of *.jtl) it works also from TeamCity.
How can I use general file name? Or maybe there is an option in jmeter-maven-plugin to define some fixed jtl file name (and then use it in jmeter-graph-maven-plugin)?
I did workaround for this issue.
I changed jmeter-graph-maven-plugin configuration to:
<inputFile>${project.build.directory}/jmeter/results/${fileName}.jtl</inputFile>
and now I run it using mvn jmeter-graph:create-graph -DfileName=%profile% (where profile name is the same as jmx test file).

JavaFX Self Installer With Inno Setup 5 - Allow user to change install directory

I am using Ant to build a self deploying EXE for a JavaFX application.
Currently Inno Setup places the EXE here: C:\Users\username\AppData\Local\application name
I would like to place this in a different location, and provide the user the option to override this. However I can't seem to find the ant settings to change this.
Is this possible?
Thanks!
Actually you can't change this using ANT. However, as you already know the deploy mechanism uses Inno Setup and you can modify its behaviour.
During the fx:deploy ANT task a default ApplicationName.iss file is created. This default file contains e.g. the setting, which is responsible for the install directory. This default file is only created, if you don't provide any customized on your own. So, I would recommend to run the ANT script, copy the default file and modify it. If you enable the verbose flag of the fx:deploy task you can use the console output to find out, where the default file is created and where the ANT task searches for your customized file before creating the default one:
<fx:deploy
...
verbose="true">
<fx:info title="${appname}" vendor="${vendor}"/>
...
</fx:deploy>
In my case I found the default file in
C:\Users\gfkri\AppData\Local\Temp\fxbundler3627681647438085792\windows
and had to put the customized file to
package/windows/ApplicationName.iss
relative to the ANT build script.
If you got so far, you'll find the line DisableDirPage=Yes in your ApplicationName.iss file. Change it to DisableDirPage=No and the user gets the possibility to change the install directory.
Further you will find the parameter DefaultDirName. If you want to install your Application to C:\Program File\ApplicationName by default you can use the constant {pf} e.g.: DefaultDirName={pf}\ApplicationName.
The original answer is not true anymore, because that feature got added to the JDK (just dont know when, but it was there when using 1.8.0u60 or so).
Just add <installdirChooser> as some <bundleArguments> and set it to true:
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>8.4.0</version>
<configuration>
<mainClass>your.mainclass</mainClass>
<verbose>true</verbose>
<bundleArguments>
<identifier>SOME-GUID-USED-FOR-UPDATE-DETECTION</identifier>
<installdirChooser>true</installdirChooser>
</bundleArguments>
</configuration>
</plugin>
Disclaimer: I'm the maintainer of the javafx-maven-plugin

Is there a way to set the Maven version number dynamically?

I would like to use Maven to produce an artifact in zip format. To give you some background; my project includes an APS package (Application Packaging Standard, used to provision cloud applications on the Parallels platform). This package is a zip file that contains a combination of XML as well as PHP files. It is generated by an APS plugin from within Eclipse and its name always includes the version and release number of its contents.
What I am trying to do is generate a zip file with Maven that would be kind of a release candidate that will be eventually sent to customers and would include not only the actual APS package but also other files such as README, User Guide.pdf, etc;. I would like the name of this zip file to contain the version number of the version number of the APS package. Currently I can generate this manually by using something like "mvn -Dversion=1.2.3-4 package" but I would like to automate the process and ideally run this from Jenkins.
Basically, my strategy is to run a script that would extract the version number from the initial APS package, once that is done, my script can invoke Maven and can pass this parameter to it so it can generate the final zip with the proper version number. This is fine but again, I need to run this script manually and I am looking for an automated process.
My question is; is it possible to invoke this script from within Maven and use its return as a parameter to set the version name (or the name of the file that will be generated) at run time? As I mentioned, I would like eventually Jenkins to handle this. It can pick up the pom file but I am not sure how it could kind of "auto configure" itself to have the proper version number.
Thanks is advance.
From jenkins build you can use profile with ${BUILD_NUMBER}:
<profile>
<id>jenkins</id>
<build>
<finalName>${artifactId}-${version}-${BUILD_NUMBER}</finalName>
</build>
</profile>
Then run in jenkins:
clean install -Pjenkins
I use the SVN (or any source versioning system) version to identify the software builds.
By simply executing this
REVISION=`svn info | grep '^Revision:' | sed -e 's/^Revision: //'`
on the sourcers folder you get the right value in $REVISION, then you can use it for your maven build
mvn -Dversion=1.2.3-$REVISION package
easy and clean

Activate a profile based on environment

Here's my scenario:
Maven 2.0.9 is our build system
We install code to multiple environments
All of our environment-specific properties are contained in property files, one for each environment
We currently read these properties into maven using the properties-maven-plugin; this sub-bullet is not a requirement, just our current solution
Goal:
Perform certain parts of the build (ie. plugin executions) only for certain environments
Control which parts are run by setting values in the environment-specific property files
What I've tried so far:
Maven allows plugins executions to be put inside pom profiles, which can be activated by properties; unfortunately these must be system properties - ie. from settings.xml or the command-line, not from properties loaded by the properties-maven-plugin
If possible, we'd like to keep everything encapsulated within the build workspace, which looks something like this:
project
pom.xml
src
...
conf
dev.properties
test.properties
prod.properties
build-scripts
build.groovy <-- the script that wraps maven to do the build
install.groovy <-- ... wraps maven to do the install
Running a build looks like:
cd build-scripts
./build.groovy
./install.groovy -e prod
Is there any possible way to accomplish these goals with the version of maven we are using? If not, is it possible with a newer version of maven?
This isn't possible using just Maven. (See also How to activate profile by means of maven property?) The reason is that profiles are the first thing evaluated before anything else to determine the effective POM.
My suggestion is to write some preprocessor that parses your environment specific property files and converts them to the required system properties before launching Maven. This script can be included in your ~/.mavenrc so that it runs automatically before Maven is launched. Here is an example script that that assumes the properties file is in a fixed location:
properties=`cat /etc/build-env.properties`
while read line; do
MAVEN_OPTS="$MAVEN_OPTS -D$line"
done <<< "$properties"
If the properties file is not fixed, you'll just need to add something to the script to discover the location (assuming it is discoverable).

Resources