Skip to content

Instantly share code, notes, and snippets.

@ben-mcclain
Last active January 6, 2022 22:28
Show Gist options
  • Select an option

  • Save ben-mcclain/6ffb28acd1e9ade0071fe934c948f873 to your computer and use it in GitHub Desktop.

Select an option

Save ben-mcclain/6ffb28acd1e9ade0071fe934c948f873 to your computer and use it in GitHub Desktop.
The Jenkins job DSL is different than a job's declarative actions

The Jenkins job DSL is different than a job's declarative actions

Recently, I was trying to add a new job to our Jenkins using Jenkins Configuration as Code. When refreshing the CASC, I was greeted with this beautiful error:

javaposse.jobdsl.dsl.helpers.BuildParametersContext.choice() is applicable for argument types: (java.util.LinkedHashMap)

While not too helpful, it does indicate this has to do with a choice type parameter.

Troubleshooting

What I did wrong

This is a redacted and simplified example of how the job was originally defined:

pipelineJob("my-job") {
  parameters {
    booleanParam("IS_INCREMENTAL", true, "Should this be an incremental run or full?")
    choice(name: 'ENV', choices: ['dev', 'stage', 'prod'], description: 'Which environment should we be using')
  }
  triggers {
    parameterizedCron('''
        0 1 * * * %IS_INCREMENTAL=true;ENV=dev
        0 1 * * * %IS_INCREMENTAL=true;ENV=stage
    ''')
  }
  definition {
    cpsScm {
      scm {
        git {
          remote {
            github("org/repo", "https")
            credentials("secret")
          }
        branch("main")
        }
      }
      scriptPath("Jenkinsfile")
      lightweight()
    }
  }
}

The choice parameter was recently added, and appears to be correct, based on the Jenkins' pipeline syntax.
Here's the documentation on parameters:

pipeline {
    agent any
    parameters {
        string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')

        text(name: 'BIOGRAPHY', defaultValue: '', description: 'Enter some information about the person')

        booleanParam(name: 'TOGGLE', defaultValue: true, description: 'Toggle this value')

        choice(name: 'CHOICE', choices: ['One', 'Two', 'Three'], description: 'Pick something')

        password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'Enter a password')
    }
    stages {
        stage('Example') {
            steps {
                echo "Hello ${params.PERSON}"

                echo "Biography: ${params.BIOGRAPHY}"

                echo "Toggle: ${params.TOGGLE}"

                echo "Choice: ${params.CHOICE}"

                echo "Password: ${params.PASSWORD}"
            }
        }
    }
}

It looks good, right? Then why the error...

There's a Job DSL and it's different than how the Jenkinsfile is written?

Yes.

They are so similar that I didn't notice it at first. Let's look at the Job DSL documentation, which can be found on your own Jenkins via https://myjenkins.hodor/plugin/job-dsl/api-viewer/index.html. Now, let's go exploring. Navigate into pipelineJob | parameters. We can see two options that seem the same: choice and choiceParam. This is now only slightly less confusing... If we look at both we can see the choiceParam has an example and the other one doesn't, so let's use that. It also matches the booleanParam syntax that we have above that has been working fine.

pipelineJob("my-job") {
  parameters {
    booleanParam("IS_INCREMENTAL", true, "Should this be an incremental run or full?")
    choiceParam('ENV', ['dev', 'stage', 'prod'], 'Which environment should we be using')
  }
  triggers {
    parameterizedCron('''
        0 1 * * * %IS_INCREMENTAL=true;ENV=dev
        0 1 * * * %IS_INCREMENTAL=true;ENV=stage
    ''')
  }
  definition {
    cpsScm {
      scm {
        git {
          remote {
            github("org/repo", "https")
            credentials("secret")
          }
        branch("main")
        }
      }
      scriptPath("Jenkinsfile")
      lightweight()
    }
  }
}

Parameterized Scheduler Plugin Job DSL

After refreshing CASC, I got another error relating to our use of the Parameterized Scheduler plugin along the lines of: No signature of method: javaposse.jobdsl.dsl.helpers.triggers.TriggerContext.parameterizedTimerTrigger() is applicable
I could not easily figure this out, so I went to google which helped me find this StackOverflow page which gave me the answer. I needed to change this section to:

          triggers {
            parameterizedTimerTrigger{
              parameterizedSpecification('''
                0 8 * * * %IS_INCREMENTAL=true;ENV=dev
                0 8 * * * %IS_INCREMENTAL=true;ENV=prod
              ''')
            }
          }

To be honest, I'm not sure where the stack overflow user kivagant found how to do this, but if you're out there somewhere, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment