My question is very related to How to access list of Jenkins job parameters from within a JobDSL script?
With the diference: How can I access one specific parameter within the DSL script?
I tried to figure it out from the answers in the mentioned question but couldn't figure it out.
Let's say the parameter is named REPOSITORY_NAME.
I tried to use the code from the accepted answer and do something like
import hudson.model.*
Build build = Executor.currentExecutor().currentExecutable
ParametersAction parametersAction = build.getAction(ParametersAction)
def newname = parametersAction.parameters['REPOSITORY_NAME'].ParameterValue
println newname
but I only got
ERROR: (script, line 5) Exception evaluating property 'REPOSITORY_NAME' for java.util.Collections$UnmodifiableRandomAccessList, Reason: groovy.lang.MissingPropertyException: No such property: REPOSITORY_NAME for class: hudson.model.StringParameterValue
I also tried
def newname = parametersAction.parameters.getParameter('REPOSITORY_NAME').ParameterValue
instead but it gave me
ERROR: (script, line 5) No signature of method: java.util.Collections$UnmodifiableRandomAccessList.getParameter() is applicable for argument types: (java.lang.String) values: [REPOSITORY_NAME]
What do I have to change to make this work?
Okey just figured it out now using the second answer on the mentioned question and if-else like
def reponame = ''
binding.variables.each {
println "${it.key} = ${it.value}"
if(it.key == 'REPOSITORY_NAME'){
reponame = it.value
}
}
probably not the most eficient way but it works.
Related
While creating a Jenkins server, I use jobDSL to create jobs via pipeline.
Basically my created job ressembles this:
pipeline{
parameters{
string(name: "SAMPLE_PARAMETER")
}
stages{
stage("Does not matter here"){
//Does some work
}
}
}
When jobDSL tries to create a job out of this, I get an error saying that javaposse.jobdsl.dsl.helpers.BuildParametersContext.stringParam() can only work with (java.lang.string), (java.lang.string, java.lang.string) or (java.lang.string, java.lang.string, java.lang.string) and not with java.util.ArrayList
Can I force the type of "SAMPLE_PARAMETER", and if so how?
If this is not possible, how can I work around this?
You are already passing type of variable. But if you still want to pass datatype,
you can simply use it like this.
string SAMPLE_PARAMETER1 = params.SAMPLE_PARAMETER
or
def SAMPLE_PARAMETER1 = params.SAMPLE_PARAMETER
SAMPLE_PARAMETER1 = SAMPLE_PARAMETER1.toString()
As suggested by Matt Schuchard in the comment he posted, I was missing the agent section, adding
agent any
fixed my issue. I have no clue how it's related but it fixed it
Noob in Shared library,
I am puzzled with Jenkins document section 'Loading Libraries dynamically'.
Followed the Stackoverflow_answer, but I have some different needs, just wanted to call a function from library to pipeline with an argument.
Note: Jenkins library configuration is correct and library access is already checked with another example with call method
vars/foo.groovy contains function
//{Root}/vars/foo.groovy
def Foo_Func(Body){
Body= Body + "This is a Message from Shared Lib."
return Body
}
Body Variable is already defined into main Pipeline 'bar.jenkinsfile'
My real problem is how to call the function from foo.groovy without using call method,
I have tried following -
//somefolder_in_scm/bar.jenkinsfile
#Library('jenkins-shared-libs') _
def Body_Main=""
deg SUBJECT="Title 1"
def NativeReceivers = "abc#xyz.com"
pipeline{
node any
stage{
script {
/*Some script*/
}
}
post {
always {
script {
foo.Foo_Func(Body_Main)
// send email
emailext attachLog: true,
mimeType: 'text/html',
subject: SUBJECT,
body: Body_Main,
to: NativeReceivers
}
}
}
}
Since I have used _, I expect that no import needed.
Error which is occurred after triggering pipeline,
groovy.lang.MissingMethodException: No signature of method: java.lang.Class.Foo_Func() is applicable for argument types:
In the error, why function Foo_Func is treated as a class? It might possible that the argument need to be given in different way.
Any help is appreciated.
Have you tried declaring a Field ?
#groovy.transform.Field
def myVar = "something"
script.myScript.myVar
Assuming your file is myScript.groovy.
I am writing an shared lib too.
I think the problem is in the:
def Foo_Func(Body)
what works for me is:
def Foo_Func(Map Body)
so if you try:
def Foo_Func(String Body)
it should work. I think it can't find the function with the right signature.
I am retrieving an XML file from a remote host and parsing it using XmlParser. The content of the file is as follows:
<?xml version="1.0" encoding="utf-8"?><Metrics> <Safety> <score>81.00</score> <Percentrules>98.00</Percentrules> </Safety> </Metrics>
I am able to retrieve the score value in the following way when I execute the script outside the Groovy sandbox.
def report = readFile(file: 'Qualitycheck.xml')
def metrics = new XmlParser().parseText(report)
println metrics
double score = Double.parseDouble(metrics.Safety.score[0].value()[0])
However, when I execute the script using SCM I get the following:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field groovy.util.Node
The issue persist even though I have installed the Permissive-Script-Security-Plugin and enabled the plugin using the -Dpermissive-script-security.enabled=no_securityJVM option. Is there something different about this method? No other method is causing issues. Why?
Edit
I decided to use XmlSlurper(), and retrieved the value 81.00. However the result was type groovy.util.slurpersupport.NodeChildren
def metrics2 = new XmlSlurper().parseText(report)
def score = metrics2.Safety.score
print score
print score.getClass()
=> 81.0098.00
=> groovy.util.slurpersupport.NodeChildren
How do I use XmlSlurper to extract the value 81.00 and cast it as double? Will that be a good alternative?
There seems to be some issues with the script sandbox with Node and NodeList field access. You can work around this like the following, its not nice but works at least.
node() {
def xml = readFile "${env.WORKSPACE}/Qualitycheck.xml"
def rootNode = new XmlParser().parseText(xml)
print Double.parseDouble(rootNode.value()[0].value()[0].value()[0])
// Next line if position isnt fixed, can return an array
// if theres more than 1 with structure "Safety.score", [0] at the end takes the first.
print Double.parseDouble(rootNode.find{it.name() == "Safety"}.value().find{it.name() == "score"}.value()[0])
}
You also need to approve following signatures in the In-process Script Approval section in Manage Jenkins menu.
method groovy.util.Node name
method groovy.util.Node value
method groovy.util.XmlParser parseText java.lang.String
new groovy.util.XmlParser
staticMethod java.lang.Double parseDouble java.lang.String
staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods find java.lang.Object groovy.lang.Closure
I have a jenkins build that needs to get the filenames for all files checked in within a changeset.
I have installed groovy on the slave computer and configured Jenkins to use it. I am running the below script that should return the names (or so I assume as this may be wrong as well) and print to the console screen however I am getting this error:
groovy.lang.MissingPropertyException: No such property: paths for class: hudson.plugins.tfs.model.ChangeSet
Here is the Groovy System Script:
import hudson.plugins.tfs.model.ChangeSet
// work with current build
def build = Thread.currentThread()?.executable
// get ChangesSets with all changed items
def changeSet= build.getChangeSet()
def items = changeSet.getItems()
def affectedFiles = items.collect { it.paths }
// get file names
def fileNames = affectedFiles.flatten().findResults
fileNames.each {
println "Item: $it" // `it` is an implicit parameter corresponding to the current element
}
I am very new to Groovy and Jenkins so if its syntax issue or if I'm missing a step please let me know.
I don't know the version of jenkins you are using but according to the sourcecode of ChangeSet that you can find here I suggest you to replace line 9 with:
def affectedFiles = items.collect { it.getAffectedPaths() }
// or with the equivalent more groovy-idiomatic version
def affectedFiles = items.collect { it.affectedPaths }
Feel free to comment the answer if there will be more issues.
what is wrong with below code, comparing 2 strings in groovy
I am trying do the comparison between the 2 parameters in a single line to make it look tidier
if (params.dirname == ((params.path =~ ~/${params.dirname}/).with { matches() ? it[0] : null })) {
print success
}
Throwing Exception -
java.lang.NoSuchMethodError: No such DSL method 'matches' found among steps
There is no need to over-complicate your use case. According to:
params.dirname = hde, params.path = /usr/tmp/jenkins/hde/filename.txt or /usr/hde/jenkins/ing/filename.txt or any random path which has hde in it
you are trying to find if given string a contains substring b. It can be done using Java's method String.contains(String substring). Alternatively you can use regular expression for that, but String.contains() just looks a few times simpler to understand what is your intention. Consider following Groovy script:
def params = [
dirname: 'hde',
path: '/usr/tmp/jenkins/hde/filename.txt'
]
// Using String.contains()
if (params.path.contains(params.dirname)) {
println "Path '${params.path}' contains '${params.dirname}'"
}
// Using regular expression
if (params.path ==~ /(.*)${params.dirname}(.*)/) {
println "Path '${params.path}' contains '${params.dirname}'"
}
When you run it both if statements evaluates to true:
Path '/usr/tmp/jenkins/hde/filename.txt' contains 'hde'
Path '/usr/tmp/jenkins/hde/filename.txt' contains 'hde'