Return parameters/results from a job(triggered by pipeline) back to the same pipeline

后端 未结 6 1802
青春惊慌失措
青春惊慌失措 2020-12-09 09:18

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

相关标签:
6条回答
  • 2020-12-09 09:30

    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')))
    
    0 讨论(0)
  • 2020-12-09 09:31

    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.

    0 讨论(0)
  • 2020-12-09 09:32

    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.

    0 讨论(0)
  • 2020-12-09 09:41

    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

    0 讨论(0)
  • 2020-12-09 09:44

    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()}"
    
    0 讨论(0)
  • 2020-12-09 09:48

    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.

    0 讨论(0)
提交回复
热议问题