-
Bug
-
Resolution: Fixed
-
Major
-
Jenkins:
- Core 2.76
- Ubuntu 15.04
- Pipeline plugins:
- pipeline-graph-analysis 1.5
- pipeline-rest-api 2.8 (2.9)
- pipeline-model-definition 1.2-beta-4
- pipeline-model-api 1.2-beta-4
- pipeline-stage-view 2.8 (2.9)
- blueocean-pipeline-editor 1.2.0
- pipeline-input-step 2.8
- blueocean-github-pipeline 1.2.0
- pipeline-stage-tags-metadata 1.2-beta-4
- pipeline-model-declarative-agent 1.1.1
- pipeline-model-extensions 1.2-beta-4
- blueocean-pipeline-api-impl 1.2.0
- blueocean-pipeline-scm-api 1.2.0
- pipeline-stage-step 2.2
- pipeline-build-step 2.5.1
- blueocean-git-pipeline 1.2.0
- blueocean-bitbucket-pipeline 1.2.0
- pipeline-milestone-step 1.3.1
- pipeline-github-lib 1.0
Agent:
- OS: Amazon Linux AMI VERSION="2017.03"
- Java: openjdk version "1.8.0_141"
Client:
- Fedora Workstation 26
- Google Chrome 60.0.3112.113 (Official Build) (64-bit)Jenkins: - Core 2.76 - Ubuntu 15.04 - Pipeline plugins: - pipeline-graph-analysis 1.5 - pipeline-rest-api 2.8 (2.9) - pipeline-model-definition 1.2-beta-4 - pipeline-model-api 1.2-beta-4 - pipeline-stage-view 2.8 (2.9) - blueocean-pipeline-editor 1.2.0 - pipeline-input-step 2.8 - blueocean-github-pipeline 1.2.0 - pipeline-stage-tags-metadata 1.2-beta-4 - pipeline-model-declarative-agent 1.1.1 - pipeline-model-extensions 1.2-beta-4 - blueocean-pipeline-api-impl 1.2.0 - blueocean-pipeline-scm-api 1.2.0 - pipeline-stage-step 2.2 - pipeline-build-step 2.5.1 - blueocean-git-pipeline 1.2.0 - blueocean-bitbucket-pipeline 1.2.0 - pipeline-milestone-step 1.3.1 - pipeline-github-lib 1.0 Agent: - OS: Amazon Linux AMI VERSION="2017.03" - Java: openjdk version "1.8.0_141" Client: - Fedora Workstation 26 - Google Chrome 60.0.3112.113 (Official Build) (64-bit)
-
-
Declarative - 1.2
Summary:
Given a Declarative Pipeline Jenkinsfile with an environment block, if that block sets a variable without using double quotes around its value, the Pipeline will fail. This is probably just fine - however, the post/success block will run, and that seems incorrect. Also, this Pipeline will pass the CLI linter with no failures.
Severity Justification:
Bugged Jenkinsfiles get reported as being fine, through the linter, and via the post/success condition, even though in the end, they fail.
Prerequisites:
1. A remote repository (mine was on a GitHub Enterprise server), which needs nothing inside it but a Jenkinsfile.
Steps to recreate:
1. Create a Jenkinsfile with an environment
block, set a variable as follows. Note that there are no double quotes around the value. The entire Jenkinsfile that I used is attached, so it can be cut/pasted in.
environment { NEW_THING = ${env.BRANCH_NAME} }
This pipeline should also have a post
{ ... } section. Mine looks like this, so that I can easily see what gets run. This is important, because part of the issue is that the success section gets run, even though the Pipeline will fail.post { always { echo "ALWAYS. Runs all the time." } success { echo "SUCCESS. Whatever we did, it worked. Yay!" } failure { echo "FAILURE. Womp womp." } }
2. Use the Jenkins CLI to validate this pipeline, as follows, while sitting on the branch where this Jenkinsfile is. Note that it is successfully validated:
✔ ~/Documents/CloudBees/Work/Declarative/declarative-parser-rewrite [success-runs-despite-failure|…2] 11:43 $ java -jar ~/bin/jenkins-cli.jar -auth admin:admin -s http://172.30.0.13:8080/ declarative-linter < Jenkinsfile Jenkinsfile successfully validated.
3. Push this change, and build this branch again from Jenkins. The build will fail. Sample log snippet below:
First time build. Skipping changelog. [Pipeline] } [Pipeline] // stage [Pipeline] withEnv [Pipeline] { [Pipeline] } [Pipeline] // withEnv [Pipeline] } [Pipeline] // node [Pipeline] stage [Pipeline] { (Declarative: Post Actions) [Pipeline] echo ALWAYS. Runs all the time. [Pipeline] echo SUCCESS. Whatever we did, it worked. Yay! [Pipeline] } [Pipeline] // stage [Pipeline] End of Pipeline GitHub has been notified of this commit’s build result java.lang.NoSuchMethodError: No such DSL method '$' found among steps [archive, bat, build, catchError, checkout, deleteDir, dir, dockerFingerprintFrom, dockerFingerprintRun, dockerNode, echo, emailext, emailextrecipients, envVarsForTool, error, fileExists, getContext, git, input, isUnix, jiraComment, jiraIssueSelector, jiraSearch, library, libraryResource, load, mail, milestone, node, parallel, powershell, properties, publishHTML, pwd, readFile, readTrusted, resolveScm, retry, script, sh, sleep, stage, stash, step, svn, timeout, timestamps, tm, tool, unarchive, unstash, validateDeclarativePipeline, waitUntil, withContext, withCredentials, withDockerContainer, withDockerRegistry, withDockerServer, withEnv, wrap, writeFile, ws] or symbols [all, allOf, always, ant, antFromApache, antOutcome, antTarget, any, anyOf, apiToken, architecture, archiveArtifacts, artifactManager, batchFile, bitbucket, booleanParam, branch, buildButton, buildDiscarder, caseInsensitive, caseSensitive, certificate, changelog, changeset, choice, choiceParam, cleanWs, clock, cloud, command, credentials, cron, crumb, defaultView, demand, disableConcurrentBuilds, docker, dockerCert, dockerfile, downloadSettings, downstream, dumb, envVars, environment, expression, file, fileParam, filePath, fingerprint, frameOptions, freeStyle, freeStyleJob, fromScm, fromSource, git, github, githubPush, gradle, headRegexFilter, headWildcardFilter, hyperlink, hyperlinkToModels, installSource, jdk, jdkInstaller, jgit, jgitapache, jnlp, jobName, junit, label, lastDuration, lastFailure, lastGrantedAuthorities, lastStable, lastSuccess, legacy, legacySCM, list, local, location, logRotator, loggedInUsersCanDoAnything, masterBuild, maven, maven3Mojos, mavenErrors, mavenMojos, mavenWarnings, modernSCM, myView, node, nodeProperties, nonStoredPasswordParam, none, not, overrideIndexTriggers, paneStatus, parameters, password, pattern, pipeline-model, pipelineTriggers, plainText, plugin, pollSCM, projectNamingStrategy, proxy, queueItemAuthenticator, quietPeriod, remotingCLI, run, runParam, schedule, scmRetryCount, search, security, shell, skipDefaultCheckout, skipStagesAfterUnstable, slave, sourceRegexFilter, sourceWildcardFilter, sshUserPrivateKey, stackTrace, standard, status, string, stringParam, swapSpace, text, textParam, tmpSpace, toolLocation, unsecured, upstream, usernameColonPassword, usernamePassword, viewsTabBar, weather, withAnt, zfs, zip] or globals [currentBuild, docker, env, params, pipeline, scm] at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:173) at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:108) at sun.reflect.GeneratedMethodAccessor553.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42) 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:155) at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:123) at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:153) at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:157) at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:127) at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:127) at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17) at WorkflowScript.run(WorkflowScript) at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withEnvBlock(jar:file:/var/lib/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:283) at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.callClosureForMapEntry(CpsDefaultGroovyMethods:5226) at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.collect(CpsDefaultGroovyMethods:3446) at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.collect(CpsDefaultGroovyMethods:3463) at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withEnvBlock(jar:file:/var/lib/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:282) at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.call(jar:file:/var/lib/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:68) at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withCredentialsBlock(jar:file:/var/lib/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:330) at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withCredentialsBlock(jar:file:/var/lib/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:329) at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.call(jar:file:/var/lib/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:67) at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.inDeclarativeAgent(jar:file:/var/lib/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:415) at org.jenkinsci.plugins.pipeline.modeldefinition.agent.CheckoutScript.checkoutAndRun(jar:file:/var/lib/jenkins/plugins/pipeline-model-extensions/WEB-INF/lib/pipeline-model-extensions.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/agent/CheckoutScript.groovy:60) 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.GeneratedMethodAccessor362.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.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:76) 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.GeneratedMethodAccessor367.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:83) at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:173) at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:162) 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:162) at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:19) at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:35) at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:32) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108) at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:32) at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:174) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:330) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.java:82) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:242) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:230) 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: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
4. Shown below is Stage View for this job, showing that it failed, but also showing that the post { success { ... }
} block gets run:
- links to