Jenkinsfile not executing entire shell script - bash

I have the following in a Jenkinsfile as a discrete stage:
stage("Check if Postman scripts are already cloned, delete") {
steps {
sh "[ -d postman-scripts ] && rm -rf postman-scripts && echo 'Directory cleared.'"
}
}
However when I look at my Jenkins pipeline it looks like it fails and doesn't run the entire script:
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Check if Postman scripts are already cloned, delete)
[Pipeline] sh
+ '[' -d postman-scripts ']'
[Pipeline] }
Is that because it's not finding the postman-scripts directory, so it's not executing the rest of the script? And is that being counted as a build failure? It skips all following stages, so logically I think it's doing that.
Also any help with the bash scripting would be nice, I'm not entirely sure how I can string this all together on one line to do what I want (IF directory exists, remove directory. Otherwise do nothing).

Your shell test condition [ -d postman-scripts ] will FAIL if the directory does not exist. That is a failure like any other command, so it exits. #jordanm is correct, using -f will return success even if nothing exists to remove, so your next step will continue. Exception if unable to remove files because of a system lock or similar, which is probably a good thing,

Related

Cannot call ruby rake with parameter containing spaces in jenkins pipeline

I have Jenkins Pipeline that will deploy a pod with a container using my ruby's application image, and there is a stage that will run a rake command from a $COMMAND parameter like this:
rake db_command:count_data[histories,status IN ("active","pending")] inside the container.
this is the step I wrote on my stage to run the rake command from a $COMMAND parameter:
stage("Rake Task") {
try {
container("ruby-rake-task") {
sh '''
cd /var/www/mos
${COMMAND}
'''
}
} catch(e) {
echo "rake failed"
sh "exit 1"
}
}
but I get this error from console output jenkins:
+ cd /var/www/mos
+ rake 'db_command:count_data[histories,status' IN '("active","pending")]'
rake aborted!
Don't know how to build task 'db_command:count_data[histories,status' (See the list of available tasks with `rake --tasks`)
/usr/local/bundle/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
(See full trace by running task with --trace)
it seems the jenkins or groovy won't execute the rake command as a whole command, and instead it split the command to three parts. Jenkins is somehow always give a quote for all parameters after 'rake' command this really hard when the parameter is having spaces like above.
I already try adjust my stage step like this:
stage("Rake Task") {
try {
container("ruby-rake-task") {
sh "cd /var/www/mos"
def rakeTask = $/eval ${COMMAND}/$
resultRake = sh(script: "${rakeTask}", returnStdout: true).toString()
echo "${resultRake}"
}
} catch(e) {
echo "rake failed"
sh "exit 1"
}
}
yet the result is produce another error like this:
[Pipeline] stage
[Pipeline] { (Rake Task)
[Pipeline] container
[Pipeline] {
[Pipeline] sh
+ cd /var/www/mos
[Pipeline] sh
/home/jenkins/agent/workspace/RUBY-APP-RAKE-TASK#tmp/durable-c0e8d0d4/script.sh: line 1: syntax error: unexpected "("
[Pipeline] }
[Pipeline] // container
what do I need to do to be able run this rake task as a whole command included the spaces parameter? can someone tell me what am I missing here?
Thank you!
I'm using a node container with entrypoint "bash" and resolved errors like your.
I adapt it for you:
"-c \"cd /var/www/mos && ${command}\""
I hope it helps.

Jenkins groovy scripted pipeline variables not substituting correctly

I'm running a very simple pipeline to create maven projects, the pipeline is to run a single maven install command.
The trouble is substituting variables into the one-liner. I've tried various different things but stuck in a strange place. Take example pipeline below:
node {
stage('Set Vars') {
GIT_HASH = sh (script: "git log -n 1 --pretty=format:'%H'" , returnStdout: true)
echo "git hash is >>>>>>>> $GIT_HASH"
BUILD_NUM="${env.BUILD_NUMBER}"
echo "build no is >>>>>>>> ${BUILD_NUM}"
}
stage('Build Project') {
sh "mvn clean install -PrunInstallPackage -Duser=admin -Dpass=guessing -Dip=200.0.0.1 -Dport=4444 -Dhash=${GIT_HASH} -Dbuildnumber=${BUILD_NUM}"
}
}
I would expect to see the variables substitued in the mvn install command, this does not seem to work this way though.
This build results in:
sh "mvn clean install -PrunInstallPackage -Duser=admin -Dpass=guessing -Dip=200.0.0.1 -Dport=4444 -Dhash=${GIT_HASH}
Both echo commands print out correct output.
Why does the last command get cut off after the first variable substitution?
Also, for some unknown reason, I cannot substitute -Dbuildnumber=${env.BUILD_NUMBER}" directly into the maven command. Seems like something that a user should be able to do. What am I missing here?
Many thanks in advance
I am trying to remember how I solved same issues in the past..
Problem 1
You are using the GIT_HASH variable across two stages, so you have to declare it global to share it across them:
// Global variables declaration
GIT_HASH = null
// Pipeline code
node {
stage('Set Vars') {
GIT_HASH = sh (script: "git log -n 1 --pretty=format:'%H'" , returnStdout: true)
echo "git hash is >>>>>>>> $GIT_HASH"
BUILD_NUM="${env.BUILD_NUMBER}"
echo "build no is >>>>>>>> ${BUILD_NUM}"
}
stage('Build Project') {
sh "mvn clean install -PrunInstallPackage -Duser=admin -Dpass=guessing -Dip=200.0.0.1 -Dport=4444 -Dhash=${GIT_HASH} -Dbuildnumber=${BUILD_NUM}"
}
}
Problem 2
env.BUILD_NUMBER is a Groovy statement, instead mvn gets executed inside a shell instance by the sh command.
For that reason I suggest you to use the BUILD_NUM variable way.

Bash script never receives arguments when called from Jenkins pipeline

I'm running a declarative Jenkins pipeline on Ubuntu 18.04 slave. My issue is that whenever I'm trying to provide arguments from a sh step to a bash script, the arguments are not there. When running the exact same commands from either a terminal directly or another script file (similarly how Jenkins does it via temp file) the arguments work fine.
The Jenkinsfile looks something like
pipeline {
agent { label "ubuntu" }
options { timeout(time: 1, unit: 'HOURS') }
stages {
stage('Build') {
steps {
sh """
#!/bin/bash
...
. ./Scripts/install_tools.sh "force"
"""
}
}
}
}
The pipeline itself runs smooth and does what I need it to do. The problem is that when calling install_tools.sh no arguments are found. The script looks something like
#!/bin/bash
echo "Running $0"
echo "Args: $#"
...
The line echo "Args: $#" I have tried also with $* and $1 - Each time the arguments are returned as empty, but only when running from the pipeline. It seems to me that this is related to some Groovy stuff, but I have no clue what.
How do I call a bash script during the pipeline and get the arguments passed properly?
put #!/bin/bash into the first line
sh """#!/bin/bash
. ./Scripts/install_tools.sh "force"
"""
otherwise . (dot) command could have different meaning

Getting Error while Passing variables extracted from shell in Jenkinsfile

I am setting up Jenkins pipeline, but getting an error while Passing variables extracted from the shell in the environment
pipeline {
agent any
environment {
PHP_CHANGE_SET = sh (script: "git diff-tree --no-commit-id --name-only -r HEAD | grep '.php'",returnStdout: true).trim()
}
I am getting mentioned ERROR
[Pipeline] { (Declarative: Post Actions)
[Pipeline] sh
Required context class hudson.FilePath is missing
Perhaps you forgot to surround the code with a step that provides this, such as: node
Error when executing failure post condition:
org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Required context class hudson.FilePath is missing
at org.jenkinsci.plugins.workflow.steps.StepDescriptor.checkContextAvailability(StepDescriptor.java:260)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:262)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:178)
at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
I need PHP files name only which are in commit and store in variable
As mentioned in the comment, you cannot use it outside node block. If you really need to do this and this is the first thing you want for your job(A), what you can do is make another job (B) and there run this command in the directory you want and then trigger this job(A). You can have "PHP_CHANGE_SET" as a parameter which you can pass from job B.

Jenkins build says successful but no output is seen

My Jenkins build job indicates success but none of the scripts I am executing seem to do anything. I put a simple "pwd" command to echo current working directory but nothing happens. All Jenkins reports is "Running shell script" and then nothing is seen.
Snippet of Jenkins log:
First time build. Skipping changelog.
[Pipeline] sh
[an_example_test3-26UQSYQ445FSBP4QRKEWLPQCJH545MLQVD6B552CIGPOXLZO4G5A] Running shell script
[Pipeline] sh
[an_example_test3-26UQSYQ445FSBP4QRKEWLPQCJH545MLQVD6B552CIGPOXLZO4G5A] Running shell script
[Pipeline] sh
[an_example_test3-26UQSYQ445FSBP4QRKEWLPQCJH545MLQVD6B552CIGPOXLZO4G5A] Running shell script
[Pipeline] sh
[an_example_test3-26UQSYQ445FSBP4QRKEWLPQCJH545MLQVD6B552CIGPOXLZO4G5A] Running shell script
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
Jenkinsfile that is used to define the builds:
node {
stage 'build'
sh "echo ${env.BRANCH_NAME}"
git url: 'git#hd1:testing', branch: "${env.BRANCH_NAME}"
sh "ls -rtl"
sh "pwd"
sh "csh ${workspace}/simple.csh"
sh "csh ${workspace}/source.csh"
}

Resources