i would like to use a variable as a message inside an input step inside a scripted pipeline.
stage("Manual Approval"){
sh """
ls -la
versionNumber=`grep -wE -A 2 '"package": "example0"'`
ancestorVersion=`grep -wE -A 2 '"package": "example"'`
"""
timeout(time: 120, unit: 'MINUTES') {
input message: "Do you want to build ver. ${versionNumber} having ver. ${ancestorVersion} as an ancestor?", submitter: 'user1'
}
}
In the latest version of the pipeline sh step allows save the output in a variable, following:
script {
INFO_SYSTEM = sh (
script: 'uname -a',
returnStdout: true
).trim()
echo "Value: ${INFO_SYSTEM}"
}
Output:
Running on Jenkins in /var/jenkins_home/workspace/testing
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Testing)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ uname -a
[Pipeline] echo
Value: Linux d7d184735414 4.14.225-121.357.amzn1.x86_64 #1 SMP Mon Mar 15 23:52:05 UTC 2021 x86_64 GNU/Linux
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
So, maybe you can change the approach for do this task getting each variable in executing in a single command and retrieve the output, like this:
stage("Manual Approval"){
VERSION_NUMBER = sh (
script: 'grep -wE -A 2 '"package": "example0"'',
returnStdout: true
).trim()
ANCESTOR_VERSION = sh (
script: 'grep -wE -A 2 '"package": "example"'',
returnStdout: true
).trim()
timeout(time: 120, unit: 'MINUTES') {
input message: "Do you want to build ver. ${VERSION_NUMBER} having ver. ${ANCESTOR_VERSION} as an ancestor?", submitter: 'user1'
}
}
Related
While executing the sh command in jenkins pipeline project, we are getting an an error like below and sh command is not working.
Error message:
[Pipeline] sh
Warning: JENKINS-41339 probably bogus PATH=/bin/sh:/usr/atria/bin:/usr/atria/bin:$PATH; perhaps you meant to use ‘PATH+EXTRA=/something/bin’?
process apparently never started in /var/lib/jenkins/workspace/QSearch_pipelineTest#tmp/durable-6d5deef7
(running Jenkins temporarily with -Dorg.jenkinsci.plugins.durabletask.BourneShellScript.LAUNCH_DIAGNOSTICS=true might make the problem clearer)
[Pipeline] }
Below is the jenkins pipeline script code:
pipeline {
agent any
environment {
DATE = "December 17th"
}
stages {
stage("Env Variables") {
environment {
NAME = "Alex"
}
steps {
echo "Today is ${env.DATE}"
echo "My name ${env.NAME}"
echo "My path is ${env.PATH}"
script {
env.WEBSITE = "phoenixNAP KB"
env.PATH = "/bin/sh:$PATH"
}
echo "This is an example for ${env.WEBSITE}"
echo "My path ${env.PATH}"
**sh 'env'**
withEnv(["TEST_VARIABLE=TEST_VALUE"]) {
echo "The value of TEST_VARIABLE is ${env.TEST_VARIABLE}"
}
}
}
}
Below is the output of jenkins build job:
...
[Pipeline] echo
My path /bin/sh:/usr/atria/bin:/usr/atria/bin:$PATH
**[Pipeline] sh
Warning: JENKINS-41339 probably bogus PATH=/bin/sh:/usr/atria/bin:/usr/atria/bin:$PATH; perhaps you meant to use ‘PATH+EXTRA=/something/bin’?
process apparently never started in /var/lib/jenkins/workspace/QSearch_pipelineTest#tmp/durable-6d5deef7
(running Jenkins temporarily with -Dorg.jenkinsci.plugins.durabletask.BourneShellScript.LAUNCH_DIAGNOSTICS=true might make the problem clearer)**
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
**ERROR: script returned exit code -2**
Finished: FAILURE
I have this stage in my Jenkins pipeline that runs a command and stores the output in a variable. I'm trying to get the id number from the stored string but getting the error bad ${} modifier. Should have printed 00062100. It works correctly in the console.
stage('test') {
agent {node 'test'}
steps{
sh "string=$(onetstat -a -P 1111)"
sh "echo ${string:6:8}"
}
}
output from the command("BUILD 00062100 Listen")
**Update:**
stage('server2') {
agent {node 'test'}
steps{
sh '''
var="$(onetstat -a -P 1111)"
echo ${var:6:8}
'''
}
}
**log of the run**
[Pipeline] sh
+ + onetstat -a -P 1111
+ 1<TMP> /tmp/shGgcEdAGgA
var=
BUILDER8 00069B50 Listen
Local Socket: 127.0.0.1..1111
Foreign Socket: 0.0.0.0..0
/Build#tmp/durable-a93a2921/script.sh 3: FSUM7728 bad ${} modifier
There are two misunderstandings in your example. When you use double quotes in the Jenkinsfile, you construct a Groovy String that substitutes variables (defined using $ sign) with associated values (or expressions.)
Another misunderstanding is creating a bash variable in one sh step and accessing it in another sh step. It won't work that way. Each sh step runs in its own shell process, and any local variable created in one shell cannot be accessed in another.
You can solve both issues. Firstly, you need to replace double quotes with single quotes in sh step. Secondly, you need to define shell script in a single sh step. You can use Groovy multiline string for that (triple quotes.) Consider the following example:
pipeline {
agent any
stages {
stage("Test") {
steps {
// Below code prints nothing
sh 'something="BUILD 00062100 Listen"'
sh 'echo ${something:6:8}'
// Below code prints 00062100
sh '''
something="BUILD 00062100 Listen"
echo ${something:6:8}
'''
}
}
}
}
Output:
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] sh
+ something='BUILD 00062100 Listen'
[Pipeline] sh
+ echo
[Pipeline] sh
+ something='BUILD 00062100 Listen'
+ echo 00062100
00062100
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
Used this solution to get the id from the command output
var=$(onetstat -a -P 1111)
var=$(echo $var | cut -b 6-10)
I try to print two variables in Jenkins shell (one of which is global one) . When I print them independently on shell for each it works, however when I try both variables on single line it fails. See the output, seems like a crop after the first variable .
I've tried to print two local variables, and it seems working. However I need the global one
#!/usr/bin/env groovy
def START
node ('master') {
// options{
// timestamps()
// }
stage("one") {
script{
START = sh(script: 'date --utc +%FT%T', returnStdout: true)
}
stage("two") {
def END = sh(script: 'date --utc +%FT%T', returnStdout: true)
sh "echo start $START"
sh "echo end $END"
sh "echo $START and $END"
}
}
}
+ date --utc +%FT%T
[Pipeline] sh
+ echo start 2019-08-01T14:48:08
start 2019-08-01T14:48:08
[Pipeline] sh
+ echo end 2019-08-01T14:48:09
end 2019-08-01T14:48:09
[Pipeline] sh
+ echo 2019-08-01T14:48:08
2019-08-01T14:48:08
+ and 2019-08-01T14:48:09
/var/jenkins_home#tmp/durable-979e1b9e/script.sh: 2: /var/jenkins_home#tmp/durable-979e1b9e/script.sh: and: not found
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 127
Finished: FAILURE
sh is a dedicated command of jenkins-groovy. The first two work because $START/$END are the final string and doesn't try to replace something else.
sh "echo ${START} and ${END}" writing the variables like this will limit the GString and convert only the correct part and wont try to convert the "and" also.
For more have a look at this examples http://grails.asia/groovy-gstring-examples
I need a solution for the following to work - search for value variable BRANCHVERSION in ver_list, compare them and use an appropriate.
BRANCHVERSION has the format like this "6.200.01"
ver_list looks like this
[Pipeline] echo
[6.000.02, 6.000.10, 6.000.12, 6.000.15, 6.000.20, 6.000.25, 6.000.30, 6.100.00, 6.100.01, 6.100.10, 6.100.20, 6.100.25, 6.100.30, 6.200.00, 6.300.00]
if BRANCHVERSION is not equal to any values in ver_list, then the next closest value from the list ordered by descending must be picked up ( if BRANCHVERSION = 6.200.01, then 6.200.00 must be picked up)
if BRANCHVERSION is equal to any values in ver_list, then that value is picked up.
My pipeline described below:
if (ENVIRONMENT == "") {
error("You should choose at least one environment")
}
node {
deleteDir()
checkout([$class: 'SubversionSCM', locations: [[credentialsId: 'XXXXXXX',local: './env_prop_files', remote:'http://FQDN/repos/src/cm/env_prop_files']]])
checkout([$class: 'SubversionSCM', locations: [[credentialsId: 'XXXXXXX',local: './SoapUITestSuites', remote:'http://FQDN/repos/src/tools/SoapUI/branches/']]])
def FILES_LIST = sh (script: "ls './SoapUITestSuites'", returnStdout:true).trim()
def GS_LIST = sh (script: "ls 'path_to_file'", returnStdout: true).trim()
echo "GS_Version : ${GS_LIST}"
echo "FILES_LIST : ${FILES_LIST}"
//PARSING TestSuite Version
def ver_list = []
for(String ele : FILES_LIST.split("\\r?\\n")){
ver = ele.split("_")
println ">>>${ver[1]}<<<"
ver_list.add(ver[1])
}
println(ver_list)
def VERSION = ver_list
//PARSING GS Version
def gs_list = []
for(String elegs : GS_LIST.split("\\r?\\n")){
println ">>>${elegs}<<<"
gs_list.add(elegs)
}
println(gs_list)
properties = readProperties file:"./env_prop_files/${ENVIRONMENT}.properties"
BRANCHVERSION = properties.SVN_LOCATION_VERSION
}
OUTPUT
No changes for http://FQDN/repos/src/tools/SoapUI/branches since the previous
build
[Pipeline] sh
[ClientRunSoapUITest] Running shell script
+ ls ./SoapUITestSuites
[Pipeline] sh
[ClientRunSoapUITest] Running shell script
+ ls /pkg/flexprod/oracle/flexprodfiles/archive/goldstand
[Pipeline] echo
GS_Version : 5.900.00
6.000.00
6.000.01
6.000.02
6.000.20
6.000.30
6.100.00
6.100.01
6.200.00
[Pipeline] echo
FILES_LIST : rel_6.000.02
rel_6.000.10
rel_6.000.12
rel_6.000.15
rel_6.000.20
rel_6.000.25
rel_6.000.30
rel_6.100.00
rel_6.100.01
rel_6.100.10
rel_6.100.20
rel_6.100.25
rel_6.100.30
rel_6.200.00
rel_6.200.01
rel_6.300.00
[Pipeline] echo
>>>6.000.02<<<
[Pipeline] echo
>>>6.000.10<<<
[Pipeline] echo
>>>6.000.12<<<
[Pipeline] echo
>>>6.000.15<<<
[Pipeline] echo
>>>6.000.20<<<
[Pipeline] echo
>>>6.000.25<<<
[Pipeline] echo
>>>6.000.30<<<
[Pipeline] echo
>>>6.100.00<<<
[Pipeline] echo
>>>6.100.01<<<
[Pipeline] echo
>>>6.100.10<<<
[Pipeline] echo
>>>6.100.20<<<
[Pipeline] echo
>>>6.100.25<<<
[Pipeline] echo
>>>6.100.30<<<
[Pipeline] echo
>>>6.200.00<<<
[Pipeline] echo
>>>6.200.01<<<
[Pipeline] echo
>>>6.300.00<<<
[Pipeline] echo
[6.000.02, 6.000.10, 6.000.12, 6.000.15, 6.000.20, 6.000.25, 6.000.30, 6.100.00, 6.100.01, 6.100.10, 6.100.20, 6.100.25, 6.100.30, 6.200.00, 6.200.01, 6.300.00]
[Pipeline] echo
>>>5.900.00<<<
[Pipeline] echo
>>>6.000.00<<<
[Pipeline] echo
>>>6.000.01<<<
[Pipeline] echo
>>>6.000.02<<<
[Pipeline] echo
>>>6.000.20<<<
[Pipeline] echo
>>>6.000.30<<<
[Pipeline] echo
>>>6.100.00<<<
[Pipeline] echo
>>>6.100.01<<<
[Pipeline] echo
>>>6.200.00<<<
[Pipeline] echo
[5.900.00, 6.000.00, 6.000.01, 6.000.02, 6.000.20, 6.000.30, 6.100.00, 6.100.01, 6.200.00]
[Pipeline] readProperties
[Pipeline] }
[Pipeline] // node
[Pipeline] echo
"6.200.01"
[Pipeline] lock
First of all these are strings so you should change them to double. Much easier to compare them: 6.200.21 becomes 6200,21 (or 6200.21 depending on your localization)
Keep them in a list, it is much easier to work on them
The rest is simple Groovy List operations
BRANCH_VERSION = ver_list.contains(BRANCH_VERSION) ? BRANCH_VERSION : ver_list.max()
Of course if you need it as string then convert it back using the DecimalFormat Object and replace the commas with dots.
I'm working on a pipeline script that isn't even building anything. It clones a repo and then gets some info about the repo, and also uses the BitBucket REST API to get other information about the repository.
The following is an excerpt of the Jenkinsfile:
stageName = 'GET-COMMITS-AND-USERS'
stage (stageName) {
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: params.JP_MechIdCredentials, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
def uniqueCommitterMap = {}
def format = 'yyyy-MM-dd'
def now = new Date()
def aWhileAgo = now - params.JP_DaysInPastToLookFor.toInteger()
def uniqueCommitterEmails = sh(returnStdout: true, script:"git log --date=short --pretty=format:'%ce' --after='${aWhileAgo.format(format)}' --before='${now.format(format)}' | sort -u")
now = null
aWhileAgo = null
println "uniqueCommitterEmails[${uniqueCommitterEmails}]"
def uniqueCommitterEmailList = uniqueCommitterEmails.split(/[ \t\n]+/)
uniqueCommitterEmails = null
println "uniqueCommitterEmailList[${uniqueCommitterEmailList}] size[${uniqueCommitterEmailList.size()}]"
for (int ctr = 0; ctr < uniqueCommitterEmailList.size(); ++ ctr) {
println "entry[${uniqueCommitterEmailList[ctr]}]"
println "entry[${uniqueCommitterEmailList[ctr].split('#')}]"
uniqueCommitterMap[uniqueCommitterEmailList[ctr].split("#")[0]] = uniqueCommitterEmailList[ctr]
}
println "uniqueCommitterMap[${uniqueCommitterMap}]"
println "end of uCM."
uniqueCommitterEmailList = null
def cmd = "curl -u ${USERNAME}:${PASSWORD} https://.../rest/api/1.0/projects/${params.JP_ProjectName}/repos/${params.JP_RepositoryName}/permissions/users?limit=9999"
USERNAME = null
PASSWORD = null
println "cmd[${cmd}]"
def usersJson = sh(returnStdout: true, script:cmd.toString())
println "Past curl call." // Don't get here
The following is an excerpt of the console output when I run this job with appropriate parameters:
[Pipeline] echo
end of uCM.
cmd[curl -u ****:**** https://.../rest/api/1.0/projects/.../repos/.../permissions/users?limit=9999]
[Pipeline] echo
[Pipeline] sh
[workspace] Running shell script
[Pipeline] }
[Pipeline] // withCredentials
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
[DOSSIER] Response Code: 201
java.io.NotSerializableException: java.io.StringWriter
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
at java.util.HashMap.internalWriteEntries(HashMap.java:1777)
at java.util.HashMap.writeObject(HashMap.java:1354)
at sun.reflect.GeneratedMethodAccessor28.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
As you can see, it appears to execute the "sh" step to call "curl" for the BitBucket REST API, but it doesn't get past that. I can't figure out what object it's complaining about.
Update:
I'm running Jenkins 2.19.2.
The pipeline has the following settings:
"Do not allow concurrent builds": on
10 total defined parameters, one a Credentials parameter, which is referenced in this block
To answer your question I ran Jenkins v2.32.2 from the official Dockerfile and created the following test pipeline:
node() {
stage('serialize') {
def USERNAME = 'myusername'
def PASSWORD = 'mypassword'
def cmd = "echo curl -u ${USERNAME}:${PASSWORD} https://.../${params.TEST_PARAM1}/permissions/users?limit=9999"
USERNAME = null
PASSWORD = null
println "cmd[${cmd}]"
def usersJson = sh(returnStdout: true, script:cmd)
println "Past curl call."
}
}
I also added a text parameter to the build job to have something similar than your params.JP_ProjectName variables.
And this is my output when running with the text parameter set to "defaultValue modified":
Started by user admin
[Pipeline] node
Running on master in /var/jenkins_home/workspace/42217046
[Pipeline] {
[Pipeline] stage
[Pipeline] { (serialize)
[Pipeline] echo
cmd[echo curl -u myusername:mypassword https://.../defaultValue modified/permissions/users?limit=9999]
[Pipeline] sh
[42217046] Running shell script
+ echo curl -u myusername:mypassword https://.../defaultValue modified/permissions/users?limit=9999
[Pipeline] echo
Past curl call.
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
As you can see, the pipeline finished successully. And I can see no issue with the pipeline.
Maybe you can update your question with a screenshot of your job configuration and the version number of your jenkins installation.
I came across the same issue, but it seems that the issue is not caused by sh at all. It is probably caused by a variable you've defined above the sh step, which is not Serializable.