Search code examples
mavenjenkinsmaven-3pom.xml

How to access maven property from Jenkins?


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?


Solution

  • 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:

    enter image description here

    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