setting environment variable in scripted pipeline - jenkins

Im trying to create a virtualenv(stage) in Jenkins and setting the needed environment variables before the virtualenv can be created.
stage('create virtualenvironment') {
sh 'export PATH=/usr/local/bin/virtualenv:$PATH'
sh 'export VIRTUALENVWRAPPER_PYTHON=/usr/local/bin/python'
sh 'export VIRTUALENVWRAPPER_VIRTUALENV=/usr/local/bin/virtualenv'
sh 'source /usr/local/bin/virtualenvwrapper.sh'
echo 'createvirtualenvwrapper'
sh 'mkvirtualenv testproject'
}
When I execute this script - I get this message -
mkvirtualenv: command not found
When I print all the above env variables nothing is set? Not sure if the sh command is working as expected in scripted pipeline.

I'm not 100% sure but my guess is that, when you do a sh 'Some command' it executes a shell script and it is done.
So what is happening is that, each of your sh commands is being treated as a separate shell script which is executing the commands and is alive only for that session and closes once the script is done.
So try to combine all of the above commands to a single sh command along with the mkvirtualenv testproject and it should work.
For readability create a new Shell script like runProject.sh and the above commands in this shell script and then you can just call
sh runProject.sh
Hope it helps :)

Related

how to go inside a specific directory and run commands inside it in a jenkins pipeline

I am trying to run a gradle command inside a jenkins pipeline and for that i should cd <location> where gradle files are.
I added a cd command inside my pipeline but that is not working. I did this
stage('build & SonarQube Scan') {
withSonarQubeEnv('sonarhost') {
sh 'cd $WORKSPACE/sonarqube-scanner-gradle/gradle-basic'
sh 'echo ${PWD}'
sh 'gradle tasks --all'
sh 'gradle sonarqube --debug'
}
}
But the cd is not working, I tried dir step as suggested in pipeline docs, but i want to cd inside $WORKSPACE folder.
How can i fix this?
Jenkins resets the directory after each command. So after the first sh, it goes back to the previous location. The dir command is the correct approach, but it should be used like this:
dir('') {
}
Similar to how you have used withSonarQubeEnv
Alternatively, you can simply chain all the commands
sh 'cd $WORKSPACE/sonarqube-scanner-gradle/gradle-basic & echo ${PWD} & ...'
But this is not recommended. Since this will all be in the same command, it will run fine though.

Accessing jenkins shell variables within a k8s container

stages
{
stage('test')
{
steps
{
withCredentials([string(credentialsId: 'kubeconfigfile', variable: 'KUBECONFIG' )])
{
container('deploycontainer')
{
sh 'TEMPFILE=$(mktemp -p "${PWD}" kubeconfig.XXXXX)'
sh 'echo "${TEMPFILE}"'
}
}
}
}
}
I'm new to creating pipelines and am trying to covert a freestyle job over to a pipeline.
I'm trying to create a temp file for a kubeconfig file within the container.
I've tried everyway I could think of to access the vars for the shell and not a groovy var.
even trying the below prints nothing on echo:
sh 'TEMPFILE="foo"'
sh 'echo ${TEMPFILE}'
I've tried escaping and using double quotes as well as single and triple quote blocks.
How do you access the shell vars from within the container block/how do you make a temp file and echo it back out within that container block?
With Jenkinsfiles, each sh step runs its own shell. When each shell terminates, all of its state is lost.
If you want to run multiple shell commands in order, you can do one of two things.
You can have a long string of commands separated by semi-colons:
sh 'cmd1; cmd2; cmd3; ...'
Or you can use ''' or """ to extend the commands over multiple lines (note of course that if you use """ then groovy will perform string interpolation):
sh """
cmd1
cmd2
cmd3
...
"""
In your specific case, if you choose option 2, it will look like this:
sh '''
TEMPFILE=$(mktemp -p "${PWD}" kubeconfig.XXXXX)
echo "${TEMPFILE}"
'''
Caveat
If you are specifying a particular shebang, and you are using a multiline string, you MUST put the shebang immediately after the quotes, and not on the next line:
sh """#!/usr/bin/env zsh
cmd1
cmd2
cmd3
...
"""

How to access subdirectory inside of Jenkins ${workspace}/?

I've been trying to access a subdirectory inside of my Jenkins workspace with unix command : sh "cd ${workspace}/Myfolder", however the command does not work. I am using groovy script in Jenkins (Jenkinsfile).
My ${workspace} directory is: /var/lib/jenkins/workspace/test_sam_single_pipeline
When I execute command: sh "cd ${workspace}/Myfolder"
I use command: sh "pwd"
The output is:
/var/lib/jenkins/workspace/test_sam_single_pipeline
It seems I cannot access "Myfolder" subdirectory by using the "cd" command.
What am I missing?
in declarative pipeline you can use
dir('MyFolder') {
sh "pwd"
}
or use one shell for all your commands
sh """
cd MyFolder
pwd
"""
or join commands
sh "cd MyFolder && pwd"

Access a Groovy variable from within shell step in Jenkins pipeline

Using the Pipeline plugin in Jenkins 2.x, how can I access a Groovy variable that is defined somewhere at stage- or node-level from within a sh step?
Simple example:
node {
stage('Test Stage') {
some_var = 'Hello World' // this is Groovy
echo some_var // printing via Groovy works
sh 'echo $some_var' // printing in shell does not work
}
}
gives the following on the Jenkins output page:
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test Stage)
[Pipeline] echo
Hello World
[Pipeline] sh
[test] Running shell script
+ echo
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
As one can see, echo in the sh step prints an empty string.
A work-around would be to define the variable in the environment scope via
env.some_var = 'Hello World'
and print it via
sh 'echo ${env.some_var}'
However, this kind of abuses the environmental scope for this task.
To use a templatable string, where variables are substituted into a string, use double quotes.
sh "echo $some_var"
I am adding the comment from #Pedro as an answer because I think it is important.
For sh env vars we must use
sh "echo \$some_var"
You need to do something like below if a bash script is required :
Set this variable at global or local(function) level where from these can be accessible to sh script:
def stageOneWorkSpace = "/path/test1"
def stageTwoWorkSpace = "/path/test2"
In shell script call them like below
sh '''
echo ''' +stageOneWorkSpace+ '''
echo ''' +stageTwoWorkSpace+ '''
cp -r ''' +stageOneWorkSpace+'''/qa/folder1/* ''' +stageOneWorkSpace+'''/qa/folder2
'''
Make sure you start and end sh with three quotes like '''
I would like to add another scenario to this discussion.
I was using shell environment variables and groovy variables in the same script.
format='html'
for file in *.txt;
do mv -- "\$file" "\${file%.txt}.$format";
done
So here, What I have done is use \$ only for shell environment variables and use $ for groovy variables.
This is extension to #Dave Bacher's answer. I'm running multiple shell command in Groovy file & want to use output of one shell command to the next command as groovy variable. Using double quotes in shell command, groovy passes variable from one to another command but using single quotes it does not work, it returns null.
So use shell command like this in double quotes: sh "echo ${FOLDER_NAME}"
FOLDER_NAME = sh(script: $/
awk -F '=' '/CODE_COVERAGE_FOLDER/ {gsub("\"","");print$2}' ${WORKSPACE}/test.cfg
/$, returnStdout: true).trim()
echo "Folder: ${FOLDER_NAME}" // print folder name in groovy console
sh "mkdir -p ${WORKSPACE}/${FOLDER_NAME} && chmod 777 ${WORKSPACE}/${FOLDER_NAME}"

How can I start a bash login shell in jenkins pipeline (formerly known as workflow)?

I am just starting to convert my Jenkins jobs into the new Jenkins Pipeline(workflow) tool, and I'm having trouble getting the sh command to use a bash login shell.
I've tried
sh '''
#!/bin/bash -l
echo $0
'''
but the echo $0 command is always being executed in an interactive shell, rather then a bash login shell.
#izzekil is right!!!! Thank you so much!
So to elaborate a little bit about what is going on. I used sh with ''' , which indicates a multiple line script. HOWEVER, the resulting shell script that gets dumped on to the jenkins node will be one line down, rather then the first line. So I was able to fix this with this
sh '''#!/bin/bash -l
echo $0
# more stuff I needed to do,
# like use rvm, which doesn't work with shell, it needs bash.
'''

Resources