Use groovy-variable in Jenkins-Batchscript - jenkins

I have this pipeline-script:
script {
def resultFile = "logs/Resharper-Warnings.out.xml"
bat (script:
'''
set PlotFrameworkVersion=v4.5.1
set ReferencePath='C:/lib'
call ".../InspectCode.exe" "Path/To/My.sln" -a -o="${resultFile}"
'''
)
recordIssues(
qualityGates: [[threshold: 1, type: 'TOTAL', unstable: true]],
tools: [resharperInspectCode(pattern: "${resultFile}")]
)
}
As you can see I want to use the variable resultFile within both the recordIssues-step as well as the bat-step. When I execute it, I get the following log:
Inspection report was written to D:\Workspace\${resultFile}
so the variable isn´t expanded correctly. The recorsIssues-step however does parse the variable, as seen in the log:
Searching for all files in 'D:\Workspace' that match the pattern 'logs/Resharper-Warnings.out.xml'
So how do I use the variable correctly within my bat-step?

It´s just about concatenating strings in groovy, which we can achieve using +. I ended up with this which isn´t the neatest way but it gets its job done:
''' set PlotFrameworkVersion=v4.5.1
set ReferencePath='C:/lib'
call ".../InspectCode.exe" "Path/To/My.sln" ''' + "-a -o=${resultFile}"

Related

Is it possible to give multiple values as input in a string parameter in Jenkins job..?

Is it possible to give multiple values as input in a string parameter in the Jenkins job..?
If yes, what will be the syntax and how are we calling that in a for loop so the values take one after the other.?
This is for a declarative job in Jenkins.
Thank you for the help in advance
parameters {
string(name: "usernames", value: list.join (","), description: "enter the user names")
}
stages{
need the syntax for this --> //for user in usernames list
do
$echo ---> username
this username which print will be called in my curl command one after the other.
so please do help me with the right path
Generally it is only possible to pass one string.
That being said, since you are using strings you can encode whatever data you want in them.
Suppose you want to pass the pipeline a list of strings myList with values ['foo', 'bar', 'baz']. In the calling job you could simply do:
build ... parameters(string(name: "myString", value: myList.join(",")))
which passes 'foo, bar, baz' to the called job. There you could parse it out again:
params.myString.split(',') // results in ['foo', 'bar', 'baz']
To iterate over this, you could use a for-in loop or a list function like each or collect.
In order to iterate over all the elements you receive you can use the each method
stages {
stage("Iterate over parameters"){
script{
def userNames = params.userNamesString.split(',')
userNames.each { user ->
echo "$user"
}
}
}
}
Alternativly (instead of the userNames.each block you can just use a for-in statement:
for(userName in userNames){
echo "$userName"
}
For more informations on this please have a look at the links I included in my previous answer.

Changing variable deletes other variable in Jenkins groovy-script

I use a free style job in Jenkins that has 2 Parameters that the user can change at the start:
ReleaseBuild - boolean
PluginVersion - string
I use a system groovy script to read an change the variables
First I read the content of ReleaseBuild:
def isRelease = build.buildVariableResolver.resolve("ReleaseBuild").toString();
println "Is ReleaseBuild: " + isRelease
The output shows the correct value: Is ReleaseBuild: true
I need to replace the content of the second variable:
def verParameter = new StringParameterValue('PluginVersion', '1.0')
build.addOrReplaceAction(new ParametersAction(verParameter))
Now I check the content of ReleaseBuild variable again:
def isStillRelease = build.buildVariableResolver.resolve("ReleaseBuild").toString();
println "Is ReleaseBuild: " + isStillRelease
Now the variable seems to be gone. Output: Is ReleaseBuild: null
How can I change the content of PluginVersion without deleting ReleaseBuild variable?
I solved my problem meanwhile with a workaround:
When I want to update the value, I update all values (this is ok here, since I only have two)
def verParameter = new StringParameterValue('PluginVersion', ver)
def relParameter = new BooleanParameterValue('ReleaseBuild', isRelease)
build.addOrReplaceAction(new ParametersAction(verParameter, relParameter))
Still hoping to get a better solution but at least it works.

Jenkins dynamic pipeline parameters

I have a jenkins pipeline which gives the user a list of keys from Consul, the user should choose one option (using active choice parameter), I need the pipeline to dynamically generate the list of "sub keys" (depends on the user first choice, for example: key/path/${user_choice} ) and let the user to choose a sub key
my current code his:
def sout = new StringBuffer(), serr = new StringBuffer()
def proc = ['/bin/bash', '-c', 'consul kv get -keys --http-addr=X key/path/ | awk -F / \'{print $(NF-1)}\''].execute()
proc.consumeProcessOutput(sout, serr)
proc.waitFor()
return sout.tokenize()
It works fine till now, but "active choice reactive parameter" is not acting dynamically and refuse to relate to the user's first choice. I haven't found any other useful plugin
Any help?
thanks :)
From what I know you can't have an interactive command prompt in Jenkins. However, you can use the input step to get feedback and use it throughout the pipeline like so:
def keys = sh(script: 'consul kv get -keys --http-addr=X key/path/ | awk -F / \'{print $(NF-1)}\'', returnStdout: true).trim().tokenize('\n')
def choice = input message: 'Please choose a sub-key', parameters: [choice(choices: keys, description: '', name: 'Subkeys')]
println "You chose $choice"

How can I force Jenkins Blue Ocean to display print output instead of "Print Message"?

In the below screenshot some debug entries display the output text (with - Print Message at the end) while others simply display Print Message. To view these you have to expand the step to see the output.
All lines are using the format print "TEXT HERE". I've tried using print, println, and echo. All have the same output.
Why do these sometimes display the message, while others force it into a collapsed section? Is it possible to configure this to always show? The normal non-Blue Ocean Jenkins interface displays fine but there is a lot of verbosity.
This seems to be a known issue:
https://issues.jenkins-ci.org/browse/JENKINS-53649
It looks like that BlueOcean does not handle the Groovy GStrings correctly. This is what I've observed:
A simple:
echo "hello world"
will work as expected and will display correctly.
Whereas a templated string with variables, like:
echo "hello ${some_variable}"
will hide the message under a "Print Message" dropdown.
See also this answer.
It appears that if echo uses a variable with value from params or environment (i.e. "params.*"), then step label gets "Print message" name instead of actual value being echoed. It does not matter if the variable itself is a String or not. Even explicitly converting the params value to String does not help.
String param_str
String text_var_2
parameters {
string(name: 'str_param', defaultValue: 'no value')
}
param_str = params.str_param.toString()
echo "string text in double quotes is ${param_str}"
echo "simple quoted string is here"
echo 'simple quoted string is here'
echo 'Single quoted with str ' + param_str + ' is here'
echo param_str
text_var_2 = 'Single quoted str ' + param_str + ' combined'
echo "GString global text2 is ${text_var_2}"
echo 'String global text2 is' + text_var_2
BlueOcean shows simple quoted strings in step label, but everything else as "Print message".
BlueOcean output
Note that 'normal' variables (strings, integers) are not included into this example, but they are also shown in the label normally. So if you have a code like this
def text_str = 'Some string'
def int_var = 1+2
echo text_str + ' is here'
echo int_var
These will be shown on the label.
And indeed it appears to be a known Jenkins issue as stated in a previous answer.
This is a known BlueOcean bug. The console output in the "classic" view interpolates variables correctly.
One workaround is to use the label parameter of the sh step:
def message = 'Hello World'
sh(script: "echo $message", label: message)
I tried lots of things and seems the moment an environment variable is going to be displayed, it uses Print Message instead the text.
Another workaround would be to split the multiline string into an array and iterate over it :-
String[] splitData = MULTI_LINE_STRING.split("\n");
for (String eachSplit : splitData) {
print(eachSplit);
}

Environment variables manipulation

When using:
echo "${env.PRODUCT_NAME}"
it will echo:
MyProdName
When using:
echo "${env.MyProdName_Key}"
it will echo:
123456789
I would like to use something as follows:
echo "${env.${env.PRODUCT_NAME}_Key}"
Is this possible? How?
In Bash this is termed as variable in direction
Try using variables to make it further simplified
PRODUCT_NAME=$(echo "${env.PRODUCT_NAME}")
This would assign PRODUCT_NAME=MyProdName
Similarly
MyProdName=$(echo "${env.MyProdName_Key}")
This would assign MyProdName=123456789
Now when you print PRODUCT_NAME value you will get
echo ${PRODUCT_NAME}
MyProdName
And adding '!' variable indirection will give you the value of another variable values
echo ${!PRODUCT_NAME}
123456789
Maybe this will help you somehow:
def env = [
PRODUCT_NAME:'MyProdName',
MyProdName_Key: 123456789,
]
println "${env[env.PRODUCT_NAME+'_Key']}"
env is Map in the example provided but it works in the exactly same way.
Important note, regardless of how you're deriving variables:
There's no need to use string interpolation if the only value in a
string is a variable itself. This just clutters your code.
Instead of:
echo "${env.PRODUCT_NAME}"
you can do:
echo.PRODUCT_NAME.
Additionally you can grab nested object values dynamically using bracket notation
def obj = [a: '1']
echo obj[a] // outputs '1'
Using these put together, you can do:
def prodName = env.PRODUCT_NAME //will set var prodName to "MyProdName"
echo env[prodName + '_Key'] //gets nested field with key "MyProdName_Key"
(Note: this is similar to Opal's answer, hopefully my breakdown helps)

Resources