java.lang.NoSuchMethodError: No such DSL method 'triggerInstallation_OnDemand' found among steps - jenkins

I have defined one parameterized method in jenkinsfile and calling it inside scripted pipeline stage but getting error "java.lang.NoSuchMethodError: No such DSL method 'triggerInstallation_OnDemand' found among steps"
below is my code
node{
stage('trigger installation'){
releases.service.each { patch ->
triggerInstallation_OnDemand(param1, param2, param3, param4)
}
}
}
def triggerInstallation_OnDemand(param1, param2, param3, param4){
---------
---------
---------
logic
}
Note: triggerInstallation_OnDemand not returning any value

Related

Using env variables in a Jenkinsfile function?

I'm triggering one Jenkins job from the other, all via Jenkinsfiles.
stage("Trigger another job")
{
build([job:"Job2", wait:true, propagate:true, parameters: [string(name:'branch_my',value:"${env.ghprbActualCommit}")]])
}
Note that parameter branch_my is sent to Job2. However, the pipeline Job2 needs to work even when branch_my is NOT defined, for example when it is triggered manually.
Jenkinsfile for Job2 looks like:
pipeline
{
// ...
steps
{
customBranches()
// etc...
}
}
def customBranches()
{
if ( env.branch_my != null)
{
sh "switch_to ${env.branch_my}"
}
}
However, the customBranches() if statement never evaluates to true. When I do
sh "echo 'Env branch_my is: ${env.branch_my} '"
I get Env branch_my is: some_value , which is OK, and if statement should evaluate to true - but it does not.
I tried adding ${} like so: if ( ${env.branch_my} != null), but that failed completely: No such DSL method "$" found.
What's wrong with my customBranches()?
Problem isn't the Jenkinsfile syntax, but the Jenkins job configuration: it must be labeled as "parametrized" in the GUI and a string parameter branch_my needs to be defined:
Note, the parameters can be added via the Jenkinsfile itself:
parameters { string(name: 'branch_my', defaultValue: 'master', description: '') }
However, this just adds the parameter to the GUI, so you end up with the same thing.

No such field found: field java.lang.String sinput error when accessing cppcheck plugin classes

]I am a junior dev trying to lear about Jenkins, I have been learning on my own for a couple of months. Currently I have a pipeline (just for learning purposes) which runs static analysis on a folder, and then publish it, I have been able to send a report through email using jelly templates, from there I realized it is posbile to instantiate the classes of a plugin to use its methods so I went to the cppcheck javadoc and did some trial and error so I can get some values of my report and then do something else with them, so I had something like this in my pipeline:
pipeline {
agent any
stages {
stage('analysis') {
steps {
script{
bat'cppcheck "E:/My_project/Source/" --xml --xml-version=2 . 2> cppcheck.xml'
}
}
}
stage('Test'){
steps {
script {
publishCppcheck pattern:'cppcheck.xml'
for (action in currentBuild.rawBuild.getActions()) {
def name = action.getClass().getName()
if (name == 'org.jenkinsci.plugins.cppcheck.CppcheckBuildAction') {
def cppcheckaction = action
def totalErrors = cppcheckaction.getResult().report.getNumberTotal()
println totalErrors
def warnings = cppcheckaction.getResult().statistics.getNumberWarningSeverity()
println warnings
}
}
}
}
}
}
}
which output is:
[Pipeline] echo
102
[Pipeline] echo
4
My logic (wrongly) tells me that if I can access to the report and statistics classes like that and uses their methods getNumberTotal() and getNumberWarningSeverity() respectively, therefore I should be able to also access the DiffState class in the same way and use the valueOf() method to get an enum of the new errors. But adding this to my pipeline:
def nueva = cppcheckaction.getResult().diffState.valueOf(NEW)
println nueva
Gives me an error:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field org.jenkinsci.plugins.cppcheck.CppcheckBuildAction diffState
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.unclassifiedField(SandboxInterceptor.java:425)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:409)
...
I can see in the javadoc there is a diffState class with a valueOf() method, but I cannot access to it is therre any other way to get the new errors between the last build and the current one?
I see 2 issues that could be causing this:
CppcheckResult doesn't have a member variable diffState so you can't access it obviously
If you check the javadoc of CppcheckResult the class does have:
private CppcheckReport report;
public CppcheckStatistics getReport()
and
private CppcheckStatistics statistics;
public CppcheckStatistics getStatistics()
there is no member (and getter method) for diffState so maybe try to call:
/**
* Get differences between current and previous statistics.
*
* #return the differences
*/
public CppcheckStatistics getDiff(){
my suggestion: cppcheckaction.getResult().getDiff().valueOf(NEW). Furthermore CppcheckWorkspaceFile does have a method getDiffState().
Please have a look at the script approval of your Jenkins (see here).
The syntax error might appear because Jenkins (Groovy Sandbox) blocks the execution of an (for the Jenkins) "unknown" and potential dangerous method.
Jenkins settings - Script Approval - Approve your blocked method

Scripted pipeline: wrap stage

I would like to be able to wrap a 'stage' in Jenkins, so I can execute custom code at the start and end of a stage, so something like:
myStage('foo') {
}
I thought I could do this by using metaClass:
//Wrap stages to automatically trace
def originalMethod = this.metaClass.getMetaMethod("stage", null)
this.metaClass.myStage = { args ->
println "Beginning of stage"
println "Args: " + args
def result = originalMethod.invoke(delegate, args)
println "End of stage"
return result
}
But it appears the Groovy script itself is a Binding, which doesn't have a metaClass:
groovy.lang.MissingPropertyException: No such property: metaClass for class: groovy.lang.Binding
I'm still learning how Groovy and Jenkins Pipeline work, so perhaps I'm just missing something.
I am not familiar with the metaclass concept but I think that a simple solution to your problem is to define a wrapped stage as a function.
Here's an example of how you'd define such a function:
def wrappedStage(name, Closure closure) {
stage(name) {
echo "Beginning of stage"
def result = closure.call()
echo "End of stage"
return result
}
}
and this is how you would call it:
wrappedStage('myStage') {
echo 'hi'
}
The return value of wrappedStage would only make sense when the body of your stage actually returns something, for example:
If you call another job, eg:
wrappedStage('myStage') {
build job: 'myJob'
}
you will get back org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper which you can use to access info of the job you run, like result, variables etc
If you print something to the console, eg:
wrappedStage('myStage') {
echo 'hi'
}
you will get back null.
Note that in my example I am not printing args because the way I understand stage, it only takes 2 arguments; the stage name and the closure it should run. The name of the stage will already be printed in the log, and I don't know how much value you'd get from printing the code you're about to execute but if that's something you want to do, take a look at this.
If you have a more specific case in mind for what you'd want to wrap, you can add more params to the wrapper and print all the information you want through those extra parameters.

Jenkins Job DSL: Using parameters in groovyScript in job step

For my build job "generated-job-1" I need several parameters, which are passed in when the build (of the generated-job-1) is triggered via URL.
Here my Job Definition with parameters inside the SeedJob DSL:
job('generated-job-1'){
label ('master')
parameters{
stringParam('DEPLOY_URI', 'https://192.168.200.176/hyperManager', 'Provide the URL where DeploymentManager can be accessed.')
stringParam('REG_ID', '12', 'The id of the owner (Registration) of this deployment.')
}
steps {
groovyCommand(readFileFromWorkspace('stepscript.groovy')){
prop('name', 'value')
prop('DEPLOY_URI', $DEPLOY_URI)
}
}
}
I tried to use DEPLOY_URI, $DEPLOY_URI and ${DEPLOY_URI} and it the build fails with different error messages like
No such property: DEPLOY_URI for class: javaposse.jobdsl.dsl.helpers.step.GroovyContext
or
ERROR: (script, line 12) No such property: $DEPLOY_URI for class: javaposse.jobdsl.dsl.helpers.step.GroovyContext
or
ERROR: (script, line 12) No signature of method: javaposse.jobdsl.dsl.helpers.step.GroovyContext.$() is applicable for argument types: (script$_run_closure1$_closure3$_closure4$_closure5) values: [script$_run_closure1$_closure3$_closure4$_closure5#1a11cf0]
How can I define and pass those parameters to my step-script.groovy?
How could I use those parameters in other steps, such as shell or batchFile?
How do I access those parameters in my step-script.groovy, to work with the given data?
I searched for a while now and tried hard to get it working... No success.
Help really appreciated, as I am new to Job DSL and to Groovy.
Thanks in advance,
Anne
You need to put the variable name in quotes so that it gets evaluated when the generated job is executed, not when the DSL script runs.
job('generated-job-1') {
parameters {
stringParam('DEPLOY_URI', '...', '...')
}
steps {
groovyCommand(readFileFromWorkspace('stepscript.groovy')) {
prop('DEPLOY_URI', '$DEPLOY_URI')
}
}
}

How to print each element of Multi-line String Parameter?

I've Pipeline job in Jenkins (v2.7.1) where I'd like to print each element of Multi-line String parameter (Params) with 3 strings in each line: Foo, Bar, Baz as an input.
So I've tried the following syntax (using split and each):
Params.split("\\r?\\n").each { param ->
println "Param: ${param}"
}
but it fails with:
java.lang.UnsupportedOperationException: Calling public static java.lang.Object
org.codehaus.groovy.runtime.DefaultGroovyMethods.each(java.lang.Object,groovy.lang.Closure) on a CPS-transformed closure is not yet supported (JENKINS-26481); encapsulate in a #NonCPS method, or use Java-style loops
at org.jenkinsci.plugins.workflow.cps.GroovyClassLoaderWhitelist.checkJenkins26481(GroovyClassLoaderWhitelist.java:90)
which suggest to encapsulate in a #NonCPS method, or use Java-style loops.
So I've tried to encapsulate in a #NonCPS method like:
#NonCPS
def printParams() {
Params.split("\\r?\\n").each { param ->
println "Param: ${param}"
}
}
printParams()
but it fails with:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods println groovy.lang.Closure java.lang.Object
Without the function (as per first example), adding #NonCPS at the beginning it complains about unexpected token.
I also tried Java-style syntax as suggested by using for operator (similar as here):
String[] params = Params.split("\\r?\\n")
for (String param: params) {
println "Param: ${param}"
}
which seems to work in plain Groovy, but it fails in Jenkins with:
java.io.NotSerializableException: java.util.AbstractList$Itr
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
Which syntax I should use to make it work?
The code works fine when disabling a Use Groovy Sandbox option and adding #NonCPS helper method. Alternatively, as suggested by #agg3l, proceed to Jenkins management to permit this method access.
So the working code is (same as the 2nd example):
#NonCPS
def printParams() {
Params.split("\\r?\\n").each { param ->
println "Param: ${param}"
}
}
printParams()
I know it's an old post but this is my way to do it, hopefully help anyone else
params.readLines().each {
println it
if (it) {
// if you want to avoid make operation with empty lines
}
}

Resources