Home > Back-end >  How to specify classifications from .properties file in Jenkins Cucumber report?
How to specify classifications from .properties file in Jenkins Cucumber report?

Time:09-22

It's straightforward to set hardcoded values in the plugin's Advanced > Presentation > Classifications section, but a value like ${FOO} is displayed literally as ${FOO} instead of expanding.

I set FOO like so in the build shell script, but it does not get displayed in the report.

export FOO=hello

I then tried creating my own .properties file:

echo buildVersion=$LAST_BUILD_VERSION >> report-vars.properties
echo greeting=hola >> report-vars.properties
echo classifications.message=hello >> report-vars.properties
 
cat report-vars.properties

find . -name '*\.properties'

In Console Output below, I can confirm the Cucumber report plugin is finding the .properties file:

[CucumberReport] Copied 2 properties files from workspace

Based on the find output above, the two files must be

  • ./sonar-project.properties, and
  • ./report-vars.properties

Since those are the only .properties files present.

I have token-macro:2.6 installed.

CodePudding user response:

Use the "Build other projects" step in Post-build Actions section of the job, to choose the "processing job." Let's call it Add-Classifications.

In the Execute shell section, it will do the following:

# Get the first line of its own log
# Parse for the calling job name
# Parse for the calling job's build number
# Redefine the job name with ${UPSTREAM_JOB_NAME#*0m} [1]
# Repeat for the build number
# `cd` to the calling job's directory
# cd to cucumber-html-reports/
# Use `ex` to insert the contents of your "callback file." [2][3]

[1] This is to skip over Jenkins' ha:/// link reference and color codes, which are hidden (echo $VAR | cat -v) and onerous.

[3] Callback file? What? Read on for details.

[2] The ex piece is like so:

ex - overview-features.html << EOF
/id=\"classifications\"/;  r ../add-fields.phtml
wq!
EOF

Referencing [3], you need a "callback file." Each job using a callback file should have a uniform name (add-fields.phtml), to make the Add-Classifications job as generic as possible.

Something like this at the end of the Execute shell section of the calling job:

DYNAMIC_CLASSIFICATION=$(curl...)

... # Invoking a build or tests, etc.

cat << EOF > ${JOB_DIR}/add-fields.phtml
  <tr >
    <th>Build (or SHA or changing field)</th>
    <td>${DYNAMIC_CLASSIFICATION}</td>
  </tr>
EOF

A little bit of HTML wizardry--er, stitchery--with ex goes a long way.

The job needs to run on master node in order to access $JENKINS_HOME.

Open problems

  • The Cucumber link to .../$BUILD_NUMBER/cucumber-html-reports/overview-features.html is downloaded as an empty page instead of loading a webpage.
  • Should only run jobs on master node, unless "Build other project" synchronizes job to same slave node as calling job, with same $JENKINS_HOME access

CodePudding user response:

We can specify custom classifications by using a pipeline. Create a new Jenkins Pipeline (New Item > Pipeline) and convert your existing job.

A general pipeline may take the following form

@NonCPS
def readLines = { content ->
  def keyValue = []
  content.eachLine { line ->
    keyValue << line
  }
  return keyValue
}

node {
  stage('checkout') {
    git ...
  }
  stage('build') {
    withCredentials(...) {
      sh '''
...
cat << EOF > dynamic.properties
dynamicVar=$(curl ...)
EOF
'''
    }
  }
  stage('post-build') {
    def jenkins_home = manager.getEnvVariable('JENKINS_HOME')
    ...
    def prop_dir = ...

    def contents = readFile("${prop_dir}/dynamic.properties")
    def keyValues = readLines(contents)

    def dynamicVar = keyValues[0].split("=")[1]

    cucumber buildStatus: 'UNSTABLE',
                fileIncludePattern: '**/*.json',
                fileExcludePattern: '',
                jsonReportDirectory: '',
                failedStepsNumber: '0',
                skippedStepsNumber: '0',
                pendingStepsNumber: '0',
                undefinedStepsNumber: '0',
                failedScenariosNumber: '0',
                failedFeaturesNumber: '0',
                sortingMethod: 'ALPHABETICAL',
                trendsLimit: 10,
                classifications: [
                    [
                        'key': 'One such dynamic var',
                        'value': "${dynamicVar}"
                    ]
                ]
  }
}

New to pipelines? Click "Pipeline syntax" link in the left sidebar of a finished job. There are plenty of examples in the Snippet Generator.

Implementation Notes

  • Write all necessary variables to a .properties file in the build stage.
  • Build up the path to the .properties file referencing various Jenkins env vars.
  • Specify dynamic classification values with double-quoted interpolation.
  • Groovy Sandbox may or may not need to be disabled

Other questions

  • Why can't we use a callback file? Jenkins checksum prevents links to modified files, even if you modify the checksum to the new value in build.xml.
  • Why can't we use only groovy-postbuild plugin? The pipeline syntax for Cucumber Reports is specific to Jenkins Pipeline. You don't get that with just the plugin. And, you need to create a new job as a Pipeline. So you would still need to use the Cucumber Reports sample pipeline syntax anyway.

References

  • Related