I have a properties file where certain string shoudl be replaced with Jenkins parameter. I ahve tried using the variable directly in the Properties file which did not work.
properties file
DOCKER_TAG_SUFFIX=-REPLACE_RELEASE_VERSION
PROPERTY_FILE_PATH=someproperty
Jenkinsfile snippet
def jboss_parameters = readProperties file: jboss_propfile
jboss_parameters .replaceAll("RELEASE_VERSION",params.RELEASE_VERSION) # try1
jboss_parameters = readFile(jboss_propfile).replaceAll("REPLACE_RELEASE_VERSION",params.RELEASE_VERSION) # try2
# try 3
jboss_parameters.each{k,v ->
if (v == "REPLACE_RELEASE_VERSION" )
jboss_parameters.setProperty($k,params.RELEASE_VERSION)
}
# try 4
def jboss_source_file = new File(jboss_propfile)
def jboss_parameters = jboss_source_file.text.replace("REPLACE_RELEASE_VERSION",params.RELEASE_VERSION)
I am not able to find another way that works for me.
println jboss_parameters output
{DOCKER_TAG_SUFFIX=-REPLACE_RELEASE_VERSION, PROPERTY_FILE_PATH=someproperty}
The readProperties step returns a dictionary (map), not a string, that is crated from the properties file.
Your first attempt (# try1) fails because maps in groovy do not have a replaceAll function like strings have and therefore you will get an error.
Your third attempt (# try3) is failing because you are comparing the map values to REPLACE_RELEASE_VERSION without the - character and therefore the comparison always fails and no values are changed.
I tested the second attempt (# try 2) and it seems to be working, so i am not sure what is your issue, but it is easier to handle properties as a map instead of a string that is retuned from the readFile method.
So if you have only specific properties that need to be updated you can update them directly:
def jboss_parameters = readProperties file: jboss_propfile
jboss_parameters.DOCKER_TAG_SUFFIX = params.RELEASE_VERSION // update relevant property
Or if you have multiple properties that should be modified you can iterate and update each value using the collectEntries method. Something like:
def jboss_parameters = readProperties file: jboss_propfile
updated_parameters = jboss_parameters.collectEntries { key, value ->
[key, value.replaceAll("REPLACE_RELEASE_VERSION",params.RELEASE_VERSION)]
}
Related
So I have a file called "text1.txt" that has only one line -
version.build=846
I want to do something like this-
def svntag = ccsmp_v_ {version.build}
println $svntag
ccsmp_v_846
Is there any way to do this ?
You can read a file from the workspace using the methods from pipeline utility steps plugin.
For your case it would be best to use readProperties method, for example:
def properties = readProperties file: '<your properties file in the workspace>'
Then you can access the value with:
def svntag = "ccsmp_v_${properties['version.build']}"
How can I read all file names in a directory and display them as a dropdown in Jenkins GUI?
My goal is actually creating two depending dropdowns where a user chooses a file in the first dropdown and regarding the choice, in the second dropdown, the first selected file content will be shown to the user as a parameter.
I've tried the following but without success.
In the Active Choice Parameter - Groovy Script:
import groovy.io.FileType
def list = []
def dir = new File("/some/path/to/variable/TEST/*")
dir.eachFileRecurse (FileType.FILES) { file ->
list << file
}
return list
Here Active Choice Parameter Name is SWITCH
and
In the Active Choices Reactive Parameter
import groovy.json.JsonSlurper
def list = []
File textfile= new File("/some/path/to/variable/${SWITCH}")
JsonSlurper slurper = new JsonSlurper()
def parsedJson = slurper.parse(textfile)
parsedJson.each{ list.add(it.port_name + " " + it.description)}
return list
PS: Files are JSON formatted.
I've solved the problem so if anyone needs:
import groovy.io.FileType
def list = []
def dir = new File("/some/path/to/variable/TEST/")
dir.eachFileRecurse (FileType.FILES) { file ->
list.add(file.getName())
}
return list
I think you miss the option Referenced parameters as in the screenshot:
The description of this filed is here:
This option, takes a list of job parameters that trigger an
auto-refresh of the Reactive Parameter when any of the 'Referenced
parameters' change
Update:
For me works with your code, except one small change:
import groovy.json.JsonSlurper
def list = []
File textfile= new File("${SWITCH}")
JsonSlurper slurper = new JsonSlurper()
def parsedJson = slurper.parse(textfile)
parsedJson.each {
list.add "$it.port_name $it.description".toString()
}
return list
I added toString() for each list element to convert the items of GString type to String. I assume this was your problem. Without toString(), Jenkins displays [Object object] because it does not know how to convert it.
I am trying to save the value fetched from a properties file in my jenkins pipeline but it is not working
script {
String content = readFile("gradle.properties")
Properties properties = new Properties()
properties.load(new StringReader(content))
backupVersion = ${properties.backupUrl} // this is not working
echo backupVersion
echo "property 'version' has value '${properties.backupUrl}'"// this is working
}
I have defined backupVersion globally
You don't use dollar syntax if you directly refer to variables. Dollar syntax is only for string interpolation.
Simply write:
backupVersion = properties.backupUrl
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
In relation to Jenkins DSL, what is the difference between:
def cwd = pwd()
and
cwd = pwd()
?
It's a difference of scope. When you assign a value to a variable without a "def" or other type, in a Groovy script, it's added to the "binding", the global variables for the script. That means it can be accessed from all functions within the script. It's a lot like if you had the variable defined at the top of the script.
You could wind up with unexpected behavior if multiple threads are acting on the script.
def a = {
x = 1
println x
}
def b = {
x = 2
println x
}
new Thread(a).start()
new Thread(b).start()
... could produce two ones, two twos, or a mix.
In contrast, using "def" makes a local variable:
def a = {
def x = 1
println x
}
def b = {
def x = 2
println x
}
new Thread(a).start()
new Thread(b).start()
... will always print a 1 and a 2, in arbitrary order.
It's a good question, but it's more a Groovy question.
From what I understand, defining a variable without def keyword will work from a script, but not if you were in a class method. Example from this blog post :
class MyTest {
def testMethod() {
y = 3
println y
}
}
t = new MyTest()
t.testMethod()
Variable t will be defined without problem but y definition will throw an exception.
What it means is that in our context (Jenkins pipeline) you could always define your variable without the def keyword because you are always in a script context and your variables will be bound to the script. However, I think it is good practice to use def keyword because it shows you know when you instantiate your variables, and it also can avoid some problems of duplicate variables definitions (if you define them with the def keyword at least compilation will fail if you defined the same variable twice).
Finally, from Groovy documentation :
When using def in Groovy, the actual type holder is Object (so you can
assign any object to variables defined with def, and return any kind
of object if a method is declared returning def).
So you might want to be specific and specify the type of variable you are defining. In your case you could define cwd as :
String cwd = pwd()
It would forbid you to do things like :
def cwd = pwd()
cwd = 1000 // Valid code
String cwd2 = pwd()
cwd2 = 1000 // Will fail compilation