jenkins. pipeline

How to Fix Jenkins “No such DSL method ‘node’ found among steps”

Had this error today,

Also:   org.jenkinsci.plugins.workflow.actions.ErrorAction$ErrorId: 417038a0-74ea-4878-a8b3-6a832a793150
java.lang.NoSuchMethodError: No such DSL method 'node' found among steps [archive, bat, build, catchError, checkout, container,
 containerLog, deleteDir, dir, echo, envVarsForTool, error, fileExists, getContext, git, input, isUnix, library, libraryResource, load,
 mail, milestone, node, parallel, podTemplate, powershell, properties, pwd, pwsh, readFile, readTrusted, resolveScm, retry, script, sh,
 sleep, stage, stash, step, timeout, tool, unarchive, unstable, unstash, validateDeclarativePipeline, waitForBuild, waitUntil, warnError,
 withContext, withCredentials, withEnv, wrap, writeFile, ws] or symbols [GitUsernamePassword, agent, all, allBranchesSame, allOf, always,
 any, anyOf, apiToken, apiTokenProperty, architecture, archiveArtifacts, artifactManager, assembla, authorInChangelog, batchFile,
 bitbucket, bitbucketServer, booleanParam, branch, browser, buildButton, buildDiscarder, buildDiscarders, buildRetention,
 buildSingleRevisionOnly, buildingTag, builtInNode, caseInsensitive, caseSensitive, certificate, cgit, changeRequest, changelog,
 changelogBase, changelogToBranch, changeset, checkoutOption, checkoutToSubdirectory, choice, choiceParam, cleanAfterCheckout,
 cleanBeforeCheckout, clock, cloneOption, command, computerRetentionCheckInterval, configMapVolume, consoleUrlProvider, containerEnvVar,
 containerLivenessProbe, containerTemplate, cps, credentials, cron, crumb, default, defaultDisplayUrlProvider, defaultFolderConfiguration, 
defaultView, demand, disableConcurrentBuilds, disableRestartFromStage, disableResume, discoverOtherRefs, discoverOtherRefsTrait, diskSpace, diskSpaceMonitor, downstream, dumb, durabilityHint, dynamicPVC, emptyDirVolume, emptyDirWorkspaceVolume, envVar, envVars, envVarsFilter, 
environment, equals, experimentalFlags, expression, file, fileParam, filePath, fingerprint, fingerprints, firstBuildChangelog, fisheye, 
frameOptions, freeStyle, freeStyleJob, fromScm, fromSource, genericEphemeralVolume, git, gitBranchDiscovery, gitHooks, gitLab, gitList, 
gitSCM, gitTagDiscovery, gitTool, gitUsernamePassword, gitWeb, gitblit, github, gitiles, gogs, headRegexFilter, headWildcardFilter, 
hostPathVolume, hostPathWorkspaceVolume, hyperlink, hyperlinkToModels, ignoreOnPush, inbound, installSource, isRestartedRun, jdk, jgit,
 jgitapache, jnlp, jobBuildDiscarder, jobName, kiln, kubeconfig, kubernetes, kubernetesAgent, label, lastDuration, lastFailure, 
lastGrantedAuthorities, lastStable, lastSuccess, legacy, legacySCM, lfs, list, local, localBranch, localBranchTrait, location, logRotator,
 loggedInUsersCanDoAnything, mailer, masterBuild, maven, maven3Mojos, mavenErrors, mavenGlobalConfig, mavenMojos, mavenWarnings, merge, 
modernSCM, multiBranchProjectDisplayNaming, multibranch, myView, namedBranchesDifferent, never, nfsVolume, nfsWorkspaceVolume, node, 
nodeProperties, none, nonresumable, not, onFailure, organizationFolder, override, overrideIndexTriggers, paneStatus, 
parallelsAlwaysFailFast, parameters, password, pattern, perBuildTag, permanent, persistentVolumeClaim, 
persistentVolumeClaimWorkspaceVolume, phabricator, pipeline, pipelineTriggers, plainText, plugin, podAnnotation, podEnvVar, podLabel, 
pollSCM, portMapping, preserveStashes, prism, projectNamingStrategy, proxy, pruneStaleBranch, pruneStaleTag, pruneTags, 
queueItemAuthenticator, quietPeriod, rateLimit, rateLimitBuilds, redmine, refSpecs, remoteName, resourceRoot, responseTime, 
retainOnlyVariables, rhodeCode, run, runParam, schedule, scmGit, scmRetryCount, scriptApproval, scriptApprovalLink, search, secretEnvVar, 
secretVolume, security, shell, simpleBuildDiscarder, skipDefaultCheckout, skipStagesAfterUnstable, slave, sourceRegexFilter, 
sourceWildcardFilter, sparseCheckout, sparseCheckoutPaths, sshUserPrivateKey, standard, status, string, stringParam, submodule, 
submoduleOption, suppressAutomaticTriggering, suppressFolderAutomaticTriggering, swapSpace, tag, teamFoundation, text, textParam, timezone, 
tmpSpace, toolLocation, triggeredBy, unsecured, untrusted, upstream, userIdentity, userSeed, usernameColonPassword, usernamePassword, 
viewgit, viewsTabBar, weather, zip] or globals [currentBuild, env, params, pipeline, scm]
	at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:219)
	at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:124)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1225)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:41)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
	at PluginClassLoader for script-security//org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:180)
	at PluginClassLoader for script-security//org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
	at PluginClassLoader for script-security//org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:163)

when building Jenkins Pipeline using Script from SCM. The weird thing is the same script is working perfectly well when being executed directly from Jenkins, without the SCM / Git part.

The rootcause is actually simple, we are storing the Jenkins pipeline in Git using UTF8 With BOM with a specific Windows encoding. Saving it as a UTF8 directy and push it to Git can solve this problem.

ps.
opening the log in notepad++, after choosing the option to show all character, will give this result.

As we can see from above image, there is a “hidden” character with the name of “ZWNBSP” that is invisible to naked eyes. However it makes Jenkins failed to parse the corresponding pipeline.

Deploying A Spring Boot Application to Openshift, with Java 11 S2I and Jenkins Pipeline

Openshift provide a base Java s2i image where we can use as a base image to run our java applicaiton. But too bad, the default Java base image is still using java 8. On this example, im trying to do a simple deployment to Openshift but using Java 11 as its base image, instead of Java 8.

First we need to import a Java 11 s2i image from Red Hat Registry, it will become our base image to run our executable java app.

oc import-image my-project/openjdk-11-rhel7 --from=registry.redhat.io/openjdk/openjdk-11-rhel7 --confirm

Next is creating a very simple pipeline script to build, and deploy our app using Jenkins Pipeline.

node('maven') {
	stage('Clone') {
		sh "git config --global http.sslVerify false"
		sh "git clone https://github.com/edwin/hello-world.git"
	}
	stage('Build') {
		sh "mvn -v"
		sh "mvn clean package -f hello-world/pom.xml"
		
		def jarFile = sh(returnStdout: true, script: 'find hello-world/target -maxdepth 1 -regextype posix-extended -regex ".+\\.(jar|war)\$" | head -n 1').trim()
		sh "cp ${jarFile} app.jar"
	}
	stage('Deploy') {
		sh "oc new-build --name hello-world --binary -n my-project --image-stream=my-project/openjdk-11-rhel7  || true"
		sh "oc start-build hello-world --from-file=app.jar -n my-project --follow --wait"
		sh "oc new-app hello-world || true"
		sh "oc expose svc/hello-world || true"
	}
}