How to add build parameters to jenkins multibranch pipeline? - jenkins

I would like to add additional build parameters to my jenkins mutibranch pipeline job.
Relevant versions:
org.jenkins-ci.plugins:script-security:1.19
org.kohsuke:groovy-sandbox:1.10
org.jenkins-ci.main:jenkins-war:2.0
org.jenkins-ci.plugins.workflow:workflow-aggregator:2.0
My Jenkins file:
As you can see the first four lines are supposed to add the build parameter option.
import hudson.model.*
def build = Thread.currentThread().executable;
build.addAction(new ParametersAction(new StringParameterValue("SVN_UPSTREAM", build.getEnvVars()['SVN_REVISION'])));
println "SVN_UPSTREAM:" + build.getEnvVars()['SVN_UPSTREAM'];
node('dockerSlave') {
stage 'Checkout'
checkout scm
def mvnHome = tool 'M3'
stage 'VersionSet'
def v = version()
if (v) {
echo "Building version ${v}"
}
sh "${mvnHome}/bin/mvn versions:set -DnewVersion=${env.BUILD_NUMBER}"
stage 'Build'
sshagent(['601b6ce9-37f7-439a-ac0b-8e368947d98d']) {
sh 'echo SSH_AUTH_SOCK=$SSH_AUTH_SOCK'
sh "${mvnHome}/bin/mvn -B -Dmaven.test.failure.ignore clean deploy scm:tag"
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml'])
}
}
def version() {
def matcher = readFile('pom.xml') =~ '<version>(.+)</version>'
matcher ? matcher[0][1] : null
}
Unfortunately i get the following error:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException:
Scripts not permitted to use staticMethod java.lang.Thread
currentThread at
Is there a way to add the static method to a whitelist or add a build parameter via a different way?
[Pipeline] End of Pipeline
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod java.lang.Thread currentThread
at org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.StaticWhitelist.rejectStaticMethod(StaticWhitelist.java:174)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onStaticCall(SandboxInterceptor.java:142)
at org.kohsuke.groovy.sandbox.impl.Checker$2.call(Checker.java:180)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedStaticCall(Checker.java:177)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:91)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:15)
at WorkflowScript.run(WorkflowScript:2)
at ___cps.transform___(Native Method)
at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:55)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:106)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixName(FunctionCallBlock.java:74)
at sun.reflect.GeneratedMethodAccessor210.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
at com.cloudbees.groovy.cps.Next.step(Next.java:58)
at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:154)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:19)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:33)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:30)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:30)
at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:164)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:277)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$000(CpsThreadGroup.java:77)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:186)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:184)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:47)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Finished: FAILURE
Update:
Seems like disabling the sandbox mode is not possible at the moment.
https://cloudbees.zendesk.com/hc/en-us/articles/207406207-Avoid-script-approvals-with-a-Jenkins-Pipeline-Groovy-script

You should use properties step. Also take a look here at Stackoverflow: How do I use jenkins pipeline properties step?. That is my question where I've learned that you need to explicitly add parentheses even though snippet generator doesn't do that.
Example:
properties([[$class: 'ParametersDefinitionProperty', parameterDefinitions: [[$class: 'StringParameterDefinition', name: 'myparam', defaultValue: 'default value']]]])
echo "received ${binding.hasVariable('myparam') ? myparam : 'undefined'}"

Related

How to clone a github repository using Jenkins pipeline script?

I am relatively new to the CI/CD concept.
I am trying to clone a Github repository using declarative pipeline in Jenkins (without SCM).
If i do it without any credentials then I can see in the console output that Jenkins is already trying to clone that repo but it takes extremely long . I can already see that in the Jenkins workspace I have a folder with the name of my github repo but it only has a .git folder inside it and it takes forever but never pulls the repo. After searching on the internet I found out that the permissions of accessing the repository were missing.
Then i added the credentials of my Github repo in Jenkins. I have the following script.
pipeline {
agent any
stages {
stage('clone repo') {
steps {
withCredentials(usernamePassword(credentialsId :jenkins-user-github ,passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME' )){
// Get some code from a GitHub repository
bat("""
git config --global credential.username {GIT_USERNAME}
git config --global credential.helper "!echo password={GIT_PASSWORD}; echo"
git clone https://github.com/aakashsehgal/FMU.git
echo "pulled the code"
""")
}
}
}
}
}
But i get the following error:
Started by user Aakash Sehgal
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in C:\Program Files (x86)\Jenkins\workspace\GitHub
[Pipeline] {
[Pipeline] stage
[Pipeline] { (clone repo)
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
groovy.lang.MissingPropertyException: No such property: jenkins for class: groovy.lang.Binding
at groovy.lang.Binding.getVariable(Binding.java:63)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:270)
at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:291)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:295)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:271)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:271)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:29)
at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
at WorkflowScript.run(WorkflowScript:6)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.delegateAndExecute(ModelInterpreter.groovy:139)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.executeSingleStage(ModelInterpreter.groovy:663)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.catchRequiredContextForNode(ModelInterpreter.groovy:397)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.catchRequiredContextForNode(ModelInterpreter.groovy:395)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.executeSingleStage(ModelInterpreter.groovy:662)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.evaluateStage(ModelInterpreter.groovy:290)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.toolsBlock(ModelInterpreter.groovy:546)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.toolsBlock(ModelInterpreter.groovy:545)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.evaluateStage(ModelInterpreter.groovy:278)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withEnvBlock(ModelInterpreter.groovy:445)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withEnvBlock(ModelInterpreter.groovy:444)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.evaluateStage(ModelInterpreter.groovy:277)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withCredentialsBlock(ModelInterpreter.groovy:483)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withCredentialsBlock(ModelInterpreter.groovy:482)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.evaluateStage(ModelInterpreter.groovy:276)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.inDeclarativeAgent(ModelInterpreter.groovy:588)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.inDeclarativeAgent(ModelInterpreter.groovy:587)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.evaluateStage(ModelInterpreter.groovy:274)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.stageInput(ModelInterpreter.groovy:358)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.stageInput(ModelInterpreter.groovy:357)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.evaluateStage(ModelInterpreter.groovy:263)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.inWrappers(ModelInterpreter.groovy:615)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.inWrappers(ModelInterpreter.groovy:614)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.evaluateStage(ModelInterpreter.groovy:261)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withEnvBlock(ModelInterpreter.groovy:445)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withEnvBlock(ModelInterpreter.groovy:444)
at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.evaluateStage(ModelInterpreter.groovy:256)
at ___cps.transform___(Native Method)
at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:74)
at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:66)
at sun.reflect.GeneratedMethodAccessor321.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
at com.cloudbees.groovy.cps.Next.step(Next.java:83)
at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:129)
at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:268)
at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:51)
at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:185)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:400)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$400(CpsThreadGroup.java:96)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:312)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:276)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:67)
at java.util.concurrent.FutureTask.run(Unknown Source)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:131)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Finished: FAILURE
Any idea what am i missing here ?
When utilising the username and password inside the stage, you have a syntax problem. Instead of only {GIT_USERNAME}, you ought to have used ${GIT_USERNAME}.
Having said that, you need to explicitly mention to which branch you need to check out. I assume you'd want to checkout to master branch by default. So use the below:
pipeline {
agent any
stages {
stage('Checkout') {
steps {
script {
// The below will clone your repo and will be checked out to master branch by default.
git credentialsId: 'jenkins-user-github', url: 'https://github.com/aakashsehgal/FMU.git'
// Do a ls -lart to view all the files are cloned. It will be clonned. This is just for you to be sure about it.
sh "ls -lart ./*"
// List all branches in your repo.
sh "git branch -a"
// Checkout to a specific branch in your repo.
sh "git checkout branchname"
}
}
}
}
}
If you want to checkout to a specific branch by default then use the below in your pipeline stage. With the below part, you won't need to run git checkout command separately.
pipeline {
agent any
stages {
stage('Checkout') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/branchname']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'jenkins-user-github', url: 'https://github.com/aakashsehgal/FMU.git']]])
sh "ls -lart ./*"
}
}
}
}

Dynamic Parallel stages in Jenkins Pipeline outside 'script' block

I am trying to construct parallel stages dynamically, as demonstrated here and here. Specifically, I am trying to do this in a function defined outside the scope of the pipeline, e.g.:
pipeline{
stages{
stage('CI'){
steps{
doDynamicParallelSteps()
}
}
}
}
def doDynamicParallelSteps(){
tests = [:]
for (f in findFiles(glob: '**/html/*.html')) {
tests["${f}"] = {
node {
stage("${f}") {
echo '${f}'
}
}
}
}
parallel tests
}
The problem is, it seems this only works when the dynamic parallel generation code is inside a script{} block within the steps{} block of the pipeline (as seen in the first source).
When running something similar to the code snippet above, I see this error in jenkins:
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.lang.String.call() is applicable for argument types: (java.lang.String, org.jenkinsci.plugins.workflow.cps.CpsClosure2) values: [teststage, org.jenkinsci.plugins.workflow.cps.CpsClosure2#2e1b48b4]
Possible solutions: wait(), any(), trim(), size(), next(), size()
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:153)
at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:155)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:159)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
at WorkflowScript.parallelHandler(WorkflowScript:1383)
at ___cps.transform___(Native Method)
at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:82)
at sun.reflect.GeneratedMethodAccessor110.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
at com.cloudbees.groovy.cps.impl.ClosureBlock.eval(ClosureBlock.java:46)
at com.cloudbees.groovy.cps.Next.step(Next.java:83)
at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:122)
at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:261)
at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$101(SandboxContinuable.java:34)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.lambda$run0$0(SandboxContinuable.java:59)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:58)
at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:182)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:332)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$200(CpsThreadGroup.java:83)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:244)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:232)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:131)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Finished: FAILURE
Is there any way to have it defined as a function in the way I showed in the initial code snippet, or am I stuck with having a ton of script{} blocks in my pipeline definition?
The declarative pipeline does not allow you to put Groovy code inside steps {} block - it expects a valid Jenkins pipeline step in this place. This is why script {} block got introduced that can be put inside the steps {} block to execute some Groovy code.
If you need flexibility and non-opinionated syntax then you might use scripted pipeline instead. Here you can mix Groovy code with existing pipeline steps with almost no limitations.
Jenkins documentation explains shortly the difference between both approaches and why they exist:
When Jenkins Pipeline was first created, Groovy was selected as the foundation. Jenkins has long shipped with an embedded Groovy engine to provide advanced scripting capabilities for admins and users alike. Additionally, the implementors of Jenkins Pipeline found Groovy to be a solid foundation upon which to build what is now referred to as the "Scripted Pipeline" DSL. [2].
As it is a fully featured programming environment, Scripted Pipeline offers a tremendous amount of flexibility and extensibility to Jenkins users. The Groovy learning-curve isn’t typically desirable for all members of a given team, so Declarative Pipeline was created to offer a simpler and more opinionated syntax for authoring Jenkins Pipeline.
Both are fundamentally the same Pipeline sub-system underneath. They are both durable implementations of "Pipeline as code." They are both able to use steps built into Pipeline or provided by plugins. Both are able to utilize Shared Libraries
Your example in scripted pipeline may look like this:
node {
stage('CI') {
doDynamicParallelSteps()
}
}
def doDynamicParallelSteps(){
tests = [:]
for (f in findFiles(glob: '**/html/*.html')) {
tests["${f}"] = {
node {
stage("${f}") {
echo '${f}'
}
}
}
}
parallel tests
}
And declarative pipeline with script {} block in steps would look like this:
pipeline{
agent any
stages{
stage('CI'){
steps{
script {
doDynamicParallelSteps()
}
}
}
}
}
def doDynamicParallelSteps(){
tests = [:]
for (f in findFiles(glob: '**/html/*.html')) {
tests["${f}"] = {
node {
stage("${f}") {
echo '${f}'
}
}
}
}
parallel tests
}

Jenkins pipeline sh returnstdout not working

I am attempting to use the returnStdout feature of the Jenkins pipeline sh command. defined here https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#code-sh-code-shell-script
Pulling from previous question and answers: Is it possible to capture the stdout from the sh DSL command in the pipeline
My original code:
node{
def output = sh(returnStdout: true, script: 'pwd')
println "output = ${output}"
}
and its result. You can see that I am getting exit code instead of the result passed into my variable:
[Pipeline] node {
[Pipeline] sh
[Update_Stageing_DB] Running shell script
+ pwd
/mnt/storage/jenkins/workspace/Update_Stageing_DB
[Pipeline] echo
output = 0
[Pipeline] } //node
[Pipeline] Allocate node : End
[Pipeline] End of Pipeline
Finished: SUCCESS
Based on the examples I figured I might need to add the .trim() so my updated code looks like this:
node{
def output = sh(returnStdout: true, script: 'pwd').trim()
println "output = ${output}"
}
But this results in the entire job to fail:
[Pipeline] node {
[Pipeline] sh
[Update_Stageing_DB] Running shell script
+ pwd
/mnt/storage/jenkins/workspace/Update_Stageing_DB
[Pipeline] } //node
[Pipeline] Allocate node : End
[Pipeline] End of Pipeline
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.lang.Integer.trim() is applicable for argument types: () values: []
Possible solutions: wait(), grep(), wait(long), times(groovy.lang.Closure), div(java.lang.Character), print(java.io.PrintWriter)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58)
at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:49)
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:15)
at WorkflowScript.run(WorkflowScript:3)
at ___cps.transform___(Native Method)
at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:55)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:106)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixName(FunctionCallBlock.java:74)
at sun.reflect.GeneratedMethodAccessor771.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
at com.cloudbees.groovy.cps.Next.step(Next.java:58)
at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:154)
at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:164)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:277)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$000(CpsThreadGroup.java:77)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:186)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:184)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:47)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Finished: FAILURE
Im sure i'm missing something basic but for the life of me I cant see whats wrong with this simple code. Any help would be appreciated.
Jenkins ver. 2.32.2
No signature of method: java.lang.Integer.trim() is applicable
That error message means that the sh step is returning a numeric value.
For me, this only occurs if I use the returnStatus parameter rather than returnStdout in the sh step invocation.
Make sure that your plugins are up-to-date, and that you're using the correct parameter; you can use the "Replay" link in the sidebar on any build page to see exactly which Pipeline script(s) was loaded, if you're loading the Pipeline from a remote SCM, for example.
Also, in case you really only need to run pwd in the shell step, you can simplify a bit by using the pwd Pipeline step.

Jenkins Pipeline conditional stage succeeds but Jenkins shows build as failed

Jenkins version = 2.19
Jenkins Multibranch Pipeline plugin version = 2.92
I have a Jenkinsfile with a few conditional stages based on the branch.
Here is a modified for the sake of brevity version of my Jenkinsfile:
node {
stage('Checkout') {
checkout scm
}
stage('Clean Verify') {
sh 'mvn clean verify'
}
if (env.BRANCH_NAME == "develop") {
stage('Docker') {
sh 'mvn docker:build -DpushImage'
}
}
}
I am using the multibranch pipeline plugin.
It successfully detects and builds all my branches.
The problem I have is that all builds report as failed even though if i hover each stage it reports 'Success'.
I have attached an image showing a feature branch where the two stages i wanted to run have run and completed with success but you can see the build has actually reported as failed.
I get the exact same outcome for develop branch as well - it executes the Docker stage successfully but the build reports failed.
My expectation is that each branch will report success as the stages that ran for that branch all passed.
EDIT 1
Here's the end of the build log (i'm hoping this is sufficient as i didn't want to pick out all the private info but let me know if required)
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 30.459 s
[INFO] Finished at: 2017-02-21T15:13:02+11:00
[INFO] Final Memory: 84M/769M
[INFO] ------------------------------------------------------------------------
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] sh
Required context class hudson.FilePath is missing
Perhaps you forgot to surround the code with a step that provides this, such as: node
[Pipeline] End of Pipeline
org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Required context class hudson.FilePath is missing
at org.jenkinsci.plugins.workflow.steps.StepDescriptor.checkContextAvailability(StepDescriptor.java:253)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:179)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:126)
at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:108)
at groovy.lang.GroovyObject$invokeMethod.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:151)
at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:21)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:115)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:103)
at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:149)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:146)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:16)
at WorkflowScript.run(WorkflowScript:93)
at ___cps.transform___(Native Method)
at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:82)
at sun.reflect.GeneratedMethodAccessor501.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
at com.cloudbees.groovy.cps.Next.step(Next.java:58)
at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:154)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:33)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:30)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:30)
at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:163)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:328)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.java:80)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:240)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:228)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:63)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Finished: FAILURE
So after looking more closely at the log file it helped me to track down the problem.
It's worth noting that clicking on the build stage to view the logs is what threw me - this is what I had been doing. When I actually went to the full console log output i saw the error about:
Required context class hudson.FilePath is missing
Perhaps you forgot to surround the code with a step that provides this, such as: node
Underneath the node {} section that I had I had a statement for deploys:
def branch = readFile('branch').trim()
if (branch == master) {
...
}
The problem was that the readFile statement was defined outside of a node.
The answer was to put the readFile statement within a node {} section.
I know this is old, but I ran into a similar issue with a declarative pipeline and landed here. As it turns out, I was trying to use a sh to set an environment variable within the pipeline block, but my main agent was none, i.e.:
pipeline {
agent none
environment {
VERSION = sh(returnStdout: true, script: 'git describe --tags')
}
}
That resulted in the same error Required context class hudson.FilePath is missing. Moving it to a stage with an agent worked as expected.
my solution for the error Required context class hudson.FilePath is missing
Perhaps you forgot to surround the code with a step that provides this, such as: node
is:
#!/usr/bin/env groovy
import hudson.model.*
node('master') {
sh("your shell script")
}
In my case, it suddenly stopped working, with the error:
Required context class hudson.FilePath is missing
Perhaps you forgot to surround the code with a step that provides this, such as: node
The reason was that the node was simply down. Had to restart it and relaunch its agent (it was slave).
The sh command is not closed with a quote in the end.
This error can happen if your branch gets deleted and will show the below error:
Caused by: org.codehaus.groovy.runtime.InvokerInvocationException:
org.jenkinsci.plugins.workflow.steps.MissingContextVariableException:
Required context class hudson.FilePath is missing 14:25:07 Perhaps
you forgot to surround the code with a step that provides this, such
as: node
and THEN at the end it will also say:
ERROR: Couldn't find any revision to build. Verify the repository and
branch configuration for this job.
In our case we had sometimes set a job to use a branch that was still in a PR and once the PR was merged the branch was auto-deleted (e.g. https://stackoverflow.com/a/57328204/292408).
Restore the branch in the job if this is your case and it should work again. If you are seeing this error inconsistently then this might be your issue.
I had this error:
Error when executing always post condition: org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Required context class hudson.FilePath is missing
Perhaps you forgot to surround the code with a step that provides this, such as: node
It was caused by ambiguous interpolation:
environment {
FILE = "some-$BRANCH.yml"
}
The correct expression in this case would be:
"some-${BRANCH}.yml"

Jenkins: Groovy No signature of method: static hudson.model.Job.getBuildDir()

I am using Jenkins 1.6.20 testing the Workflow Plugin which uses Groovy for creating the job as you would know.
I am trying to get information about the current job, for example the working directory of the job.
This is my code:
import hudson.EnvVars
import hudson.model.*
def build_number = Job.getBuildDir()
echo "$build_number"
It gives me the error:
groovy.lang.MissingMethodException: No signature of method: static hudson.model.Job.getBuildDir() is applicable for argument types: () values: []
Possible solutions: getBuildDir(), getBuilds(), getBuild(java.lang.String), getBuilds(hudson.model.Fingerprint$RangeSet), getRootDir()
at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1367)
at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1353)
at org.codehaus.groovy.runtime.callsite.StaticMetaClassSite.call(StaticMetaClassSite.java:50)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:15)
at WorkflowScript.run(WorkflowScript:4)
at ___cps.transform___(Native Method)
at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:69)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:106)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixName(FunctionCallBlock.java:74)
at sun.reflect.GeneratedMethodAccessor1418.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
Using this documentation:
http://javadoc.jenkins-ci.org/hudson/model/Job.html
I can read that the method getBuildDir is actually there and also the error suggest me to use getBuildDir making no sense for me.
If it is useful for someone I could get the workspace dir by:
node {
def pwdv = pwd()
echo "path ${pwdv}"
}

Resources