Jenkins: groovy DSL: using the ternary operator to distinguish between FreeStyleJob and MatrixJob

10,767

I managed to solve it this way:

def jobInstance = !config.toolchainsBuild ? job("job1") : matrixJob("job2")

jobInstance.with {
    // ... job definition follows
}

I.e., by using the with method. This way, the closure is only written once.

Share:
10,767
thiagowfx
Author by

thiagowfx

Updated on June 05, 2022

Comments

  • thiagowfx
    thiagowfx almost 2 years

    I am trying to write a groovy-dsl script for Jenkins to generate two jobs:

    • The first job is a FreestyleJob
    • The second one is a MatrixJob

    Their definitions are almost the same; there are only minor differences between them. Therefore, I want to reuse most of the job code and I came to the following refactoring scenario (please focus in the fifth line, in the ternary operator):

    [
        ['toolchainsBuild': false],
        ['toolchainsBuild': true],
    ].each { Map config ->
        config.toolchainsBuild ? job("job1") : matrixJob("job2") {
            // job definition follows...for example:
            out.println("debug")
            steps {
                cmake {
                    buildToolStep {}
                }
            }
            // if (config.toolchainsBuild) {
            //     ... // different actions, depending on the job type
            // }
        }
    }
    

    However, this does not work. Proof: debug is printed just once in the logfile (it should appear twice, as I want two different jobs to be defined).

    I also tried to wrap the ternary operator and its operands in parentheses, as in:

    (config.toolchainsBuild ? job("job1") : matrixJob("job2")) {
    // ...
    

    However, this causes a syntax error:

    Processing provided DSL script
    ERROR: (script, line 20) No signature of method: javaposse.jobdsl.dsl.jobs.MatrixJob.call() is applicable for argument types: (script$_run_closure1$_closure2) values: [script$_run_closure1$_closure2@2cb2656f]
    Possible solutions: wait(), label(), any(), wait(long), label(java.lang.String), each(groovy.lang.Closure)
    Started calculate disk usage of build
    Finished Calculation of disk usage of build in 0 seconds
    Started calculate disk usage of workspace
    Finished Calculation of disk usage of workspace in 0 seconds
    Notifying upstream projects of job completion
    Finished: FAILURE
    

    How can I rewrite the above expression to produce two different jobs, depending on the value of the boolean?

    I believe the problem is related to the usage of the ternary operator with closures, maybe it is not intended to be used this way?

  • thiagowfx
    thiagowfx almost 7 years
    Another alternative would be to assign the closure to a variable, and then try to use the aforementioned variable to initialize the jobs. It would probably be more elegant than my solution, however I could not find a way to properly do it.