Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I do string to integer conversion in a Jenkinsfile?

I have the following in my Jenkinsfile:

pipeline {
    agent none
    environment {
        timeout_mins = 1
    }
    options {
        timeout(time: "${env.timeout_mins}", unit: 'MINUTES')
    }
    stages {
        stage("test print") {
            steps {
                echo "timeout_mins: ${env.timeout_mins}"
                sh "sleep 120"
            }
        }
    }
}

I'd like to re-use environment params such as timeout_mins in multiple places, but need to convert it to integer in certain places for certain plugins. The error I get with the above example is as follows:

Processing environment for org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty
java.lang.IllegalArgumentException: Could not instantiate {time=null, unit=MINUTES} for TimeoutStep(time: int, unit?: TimeUnit[NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS]): java.lang.ClassCastException: org.jenkinsci.plugins.workflow.steps.TimeoutStep.time expects int but received class java.lang.String
    at org.jenkinsci.plugins.structs.describable.DescribableModel.instantiate(DescribableModel.java:264)
    at org.jenkinsci.plugins.workflow.steps.StepDescriptor.newInstance(StepDescriptor.java:194)
    at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:181)
    at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:126)
    at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:108)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:48)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
    at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:18)
    at 

Does any one have a way to convert from String to int in Jenkinsfile?

I tried time: env.timeout_mins, but that yields a null.

time: ${env.timeout_mins}, yields: WorkflowScript: 7: Method call arguments @ line 7, column 23. timeout(time: ${env.timeout_mins}, unit: 'MINUTES')

time: ${env.timeout_mins}.toInteger(), same as above

time: ${env.timeout_mins.toInteger()}, same as above

Any other things I can try?

like image 656
Ma3oxuct Avatar asked Apr 26 '17 00:04

Ma3oxuct


3 Answers

it's not the conversion that's failing, it's just that you can't reference environment variables in the options block.

this also fails (nullpointer exception):

pipeline {
    agent none
    environment {
        timeout_mins = 'MINUTES'
    }
    options {
        timeout(time: 1, unit: env.timeout_mins)
    }
    stages {
        stage("test print") {
            steps {
                echo "timeout_mins: ${env.timeout_mins}"
                sh "sleep 120"
            }
        }
    }
}

this works:

def timeout_in_minutes = 1

pipeline {
    agent none
    options {
        timeout(time: timeout_in_minutes, unit: 'MINUTES')
    }
    stages {
        stage("test print") {
            steps {
                echo "timeout_in_minutes: ${env.timeout_in_minutes}"
                sh "sleep 120"
            }
        }
    }
}
like image 121
burnettk Avatar answered Oct 17 '22 14:10

burnettk


As @burnettk says it’s a limitation with the options block. It's not the most elegant but you can use timeout as a step e.g.

pipeline {
    agent none
    environment {
        timeout_mins = 1
    }
    stages {
        stage("test print") {
            steps {
                timeout(time: env.timeout_mins.toInteger(), unit: 'MINUTES') {
                    echo "timeout_mins: ${env.timeout_mins}"
                    sh "sleep 120"
                }
            }
        }
    }
}
like image 2
gearn Avatar answered Oct 17 '22 12:10

gearn


For those trying to use a more elegant solution, you could store a parameter, convert it to an integer and use it as an options setting. This works fine for me.

def TIME_OUT = params.TEST_DURATION.toInteger() + 900

pipeline {
    options {
        //get duration in seconds
        timeout(time: TIME_OUT, unit: 'SECONDS') 
    }  
like image 1
Pat Avatar answered Oct 17 '22 12:10

Pat