Mark Allison
Mark Allison

Reputation: 7228

How to run downstream job conditionally based on a parameter in Jenkins pipeline?

Following on from my question How to trigger parameterized build on successful build in Jenkins?

I would like the invoke a downstream project but only if a boolean parameter is set to true. Is this possible? My pipeline looks like this:

node {
    try {
        echo "ConfigFilePath: ${ConfigFilePath}"
        echo "Delete VM on Successful Build: ${DeleteOnSuccess}"

        stage('checkout') {
            deleteDir()
            git 'http://my.git.lab/repo.git'
        }   

        stage('deploy') {
                bat 'powershell -nologo -file BuildMyVM.ps1 -ConfigFilePath "%ConfigFilePath%" -Verbose'                
            }
        }
        stage('test') {
            // functional tests go here
        }    
    } 
    catch (e) {
    // exception code

  } finally {
    // finally code

  }
} //node

stage('delete') {
    if(DeleteOnSuccess)
    {
        bat 'SET /p VM_NAME=<DeleteVM.txt'
        echo "Deleting VM_NAME: %VM_NAME%"
        def job = build job: 'remove-vm', parameters: [[$class: 'StringParameterValue', name: 'VM_NAME', value: '${VM_NAME}']]
    }
}   

I get this error on the delete stage

Required context class hudson.FilePath is missing. Perhaps you forgot to surround the code with a step that provides this, such as: node

If I wrap the above in a node, then the parameter values are lost. If I put the delete stage in the main node, then I take up two executors, which I'm trying to avoid because it will result in some deadlock conditions.

Upvotes: 1

Views: 2828

Answers (1)

Rik
Rik

Reputation: 3887

The problem is that the running of a script actually needs a node to run on, so in your case the cause of the error is that you try to run a bat command outside of a node context

node {
...
}
stage('delete') {
    if(DeleteOnSuccess)
    {
        bat 'SET /p VM_NAME=<DeleteVM.txt' // <- this is actually causing the error
        echo "Deleting VM_NAME: %VM_NAME%"
        def job = build job: 'remove-vm', parameters: [[$class:    'StringParameterValue', name: 'VM_NAME', value: '${VM_NAME}']]
    }
}   

You can fix this by wrapping this part also inside a node by either putting it inside the first node or add a new one, depending on what you want

Besides that, if the DeleteOnSuccess variable is a build parameter, it will be a string. I am not sure, but I think this is because it is injected as an environment variable, which are also strings (even if it is of type BooleanParameter. I guess that is only a UI thing so it will show up as checkbox). You can check that by echoing DeleteOnSuccess.class. This will tell you its class

 if(DeleteOnSuccess) { ... }

will always run the conditional block. You can fix this by either converting it to a bool using the toBoolean() extension method, or checking it against the the string true: DeleteOnSuccess == "true", like you did. The extension method has the advantage that it will also allow values "1" and "True" as true

Upvotes: 2

Related Questions