Jenkins pipeline: I have a pipeline p1
that triggers a job j1
and then job j2
. I want some parameters that are set by j1
I had a similar issue. I had to do it by having the jobs J1, J2 create properties files then acquire those files using "Copy Artifact" in the main pipeline P1. Then convert the properties into Java properties (which may require some script approval in Jenkins). It would be nice if the Jenkins Pipeline could return parameters directly in code (perhaps there is away to do this, but I don't know it). The return from a build step is a RunWrapper, it does not seem to have a way to return a custom result that I can see (unless we used some existing property like build description).
So I had something like this:
// Pipeline code in P1
// Build J1 and get result.
def j1BuildResult = build job: 'J1', parameters: [string(name: 'J1_PROP', value: 'FOO')], propagate: true, wait: true
// Get results of J1
step([$class : 'CopyArtifact', filter: 'j1-result.properties',
fingerprintArtifacts: true,
flatten : true,
projectName : 'J1',
selector : [$class : 'SpecificBuildSelector', buildNumber: buildResult.getNumber().toString()]])
// Load J1 properties (you may need to turn off sandbox or approve this in Jenkins)
Properties j1Props = new Properties()
j1Props.load(new StringReader(readFile('j1-result.properties')))
// Build J2
def j2BuildResult = build job: 'J2', parameters: [string(name: 'J2_PROP', value: j1Props.someProperty)], propagate: true, wait: true
// Get results of J2
step([$class : 'CopyArtifact', filter: 'j2-result.properties',
fingerprintArtifacts: true,
flatten : true,
projectName : 'J2',
selector : [$class : 'SpecificBuildSelector', buildNumber: buildResult.getNumber().toString()]])
// Load J2 properties (you may need to turn off sandbox or approve this in Jenkins)
Properties j2Props = new Properties()
j1Props.load(new StringReader(readFile('j2-result.properties')))
You can get build parameters together with environment variables using
def buildProperties = runWrapper.rawBuild.getEnvironment()
It is a groovy map. Target parameters can be received with
String someProperty = buildProperties.someProperty
Restrictions: need to allow method hudson.model.Run getEnvironment
in "In-process Script Approval" and call this code inside node
closure (because of rawBuild
).
I've also tried runWrapper.rawBuild.getAction(ParametersAction.class)
but it requires to many imports into Jenkinsfile.
Note: runWrapper.getBuildVariables()
returns nothing for me.
It can be done using "env". If you manage to make j1
add its information into the build's env
.
If j1
was a pipeline you could to env.MYKEY=MYVALUE
.
For a freestyle-job it should work using the EnvInject plugin (didn't try).
In p1
then you will get a map with that information if you out of the build result.
So, if you do in p1
something line this:
// somewhere in your pipeline, i.e. p1:
def j1BuildResult = build job: 'J1'
def j1EnvVariables = j1BuildResult.getBuildVariables();
then j1EnvVariables
will be a map containing the variables you set in j1
.
PS: how to pass that info to as parameters p2
is e.g. covered here.
This can help:
https://javadoc.jenkins.io/plugin/workflow-support/org/jenkinsci/plugins/workflow/support/steps/build/RunWrapper.html
From the documentation:
getBuildVariables
public Map<String,String> getBuildVariables()
throws AbortException
Get environment variables defined in the build. This does not report build parameters for parameterised builds, only the build environment. If a child job is a Pipeline job (WorkflowRun), any variables set during script execution are captured and reported. Throws: AbortException
You can get the result of the build pipeline by
def myjob=build job: 'testy', propagate: true, wait: true, parameters: [string(name: 'ENV', value: 'jamshaid'), string(name: 'Repo', value: 'khalid')]
echo "${myjob.getResult()}"
My first answer is not exactly an answer to your question, however I was trying to do something similar, but all I needed was a 'yes/no' answer to a question.
My second answer MIGHT help you, or others, as it would work...
First answer: Run a sub job that 'fail's for a 'no' answer, and 'succeed's for a 'yes' answer.
Just be sure to set 'propagate: false' in your job run. Here's a cut and paste:
def getos = build job: 'internal_is_host_running_linux',
parameters: [[$class: 'StringParameterValue',
name:'HOST',value: HOST]],propagate: false,wait:true
def linuxTest = getos.getResult()
if (linuxTest != "SUCCESS") {
// NOT success, meaning NOT booted Linux
I'm sure there's 100 better ways to do this, but this works.
Second answer that might work would be to get the console output of the sub job and search it for the data you want.
Here's how to get the console output from the subjob, at least this worked for me:
def job = build job: 'internal_run_remote_command',
wait: true, propagate: false,
parameters: [[$class: 'StringParameterValue',
name: 'HOST', value: HOST],
[$class: 'StringParameterValue',
name: 'stageos', value: stageos]]
// put the standard output from the subjob into our output:
def checklog2 = job.rawBuild.log
// obviously, if you don't want the output in your console, do not println
println checklog2
Obviously instead of 'println checklog2' you can search it for whatever stuff you want. This is an exercise left for the reader ;-)
(Again, there are probably 100 better ways to do this, but this worked for me)
My environment: using pipelines exclusively. Master host must be running the pipeline script, but every once in a while needs to run something on another host, but remain on the master host, so sub jobs seem to be the way to go for me so far.