Jenkins pipeline not failing based on batch exit code - batch-file

I am having trouble with a Jenkins pipeline that is not failing when a called batch file fails. I have checked the batch file, it returns a non-zero status code, but somehow this seems to be not considered. Does anyone of you have a hint for me?
desired pipeline
node {
stage('1'){
dir('_src') {
bat 'call test.bat'
}
}
}
Calling the batch in cmd window results in the following
>call test.bat
INFO: Started ...
ERROR
Press any key to continue . . .
>echo %ERRORLEVEL%
2
I also used the following pipeline for testing
node {
stage('1'){
dir('_src') {
bat '''call test.bat
echo %ERRORLEVEL%'''
}
}
}
... with this output
C:\_src>call test.bat
INFO: Started ...
ERROR
Press any key to continue . . .
2
Still, the pipeline is not failing. Any ideas?

It should be:
node {
stage('1'){
dir('_src') {
bat '''call test.bat
exit %ERRORLEVEL%'''
}
}
}

You only write an echo, not actually doing a return/ exit. Try to add a concrete Exit 0 or in your case Exit 2 in your script.

Related

Save commit message strng value in an envionment variable via Jenkins with bat (Windows) and using Pipeline?

I would like to save the value of some string (in this case the commit message from Git) as an environment variable for a multibranch pipeline in Jenkins. This is part of my my pipeline:
pipeline {
agent any
environment {
GIT_MESSAGE = """${bat(
script: 'git log --no-walk --format=format:%s ${%GIT_COMMIT%}',
returnStdout: true
)}""".trim()
}
stages {
stage('Environment A'){
steps{
bat 'echo %GIT_MESSAGE%'
bat '%GIT_MESSAGE%'
}
}
...
}
But after this, the echo %GIT_MESSAGE% is retruning:
echo D:\.jenkins\workspace\folder log --no-walk --format=format:GIT_COMMIT} 1>git
And naturally if I run it with bat '%GIT_MESSAGE%' it fails. I know part of the answer may lay in the way to pass the environment variable to the bat script ${%GIT_COMMIT%} but I do not seem to be able to figure out how.
Any ideas?
I just solved this issue. It had to do with the way groovy performs string interpolation. I left it working with single line strings (i.e. "...") but I am pretty sure it should work with multiline strings ("""...""").
This is the working solution for now:
pipeline {
agent any
environment {
GIT_MESSAGE = "${bat(script: "git log --no-walk --format=format:%%s ${GIT_COMMIT}", returnStdout: true)}".readLines().drop(2).join(" ")
}
stages {
stage('Environment A'){
steps{
bat 'echo %GIT_MESSAGE%'
bat '%GIT_MESSAGE%'
}
}
...
}
Notice that readLines(), drop(2) and join(" ") where necessary in order to get the commit message only without the path from which the command was run.
Also it was important to use "..." inside the script parameter of the bat function, otherwise interpolation does not happen and the environment variable GIT_COMMIT would have not been recognized.

How to add a delay after getting the list before starting the loop in the shell script

Below script list, the files, change the permissions on the file and moving it to a different folder. Sometimes the script is moving the file before the contents fully generated.
Need to add a delay after getting the list before starting the loop. Is this possible? Please help how to achieve this scenario to implement.
Can we use the sleep command to achieve this?
Script to change the file permissions and move it to main folder
function starts here
function mv_purge_files
{
cd $SRC
if  [ "$?" = "0" ]; then
for c in $(/usr/bin/ls *)
do
echo "ext: changing file permission $c"
/usr/bin/chmod 775 $c
echo "ext: moving $c"
/usr/bin/mv $c $TGT/$c
done
else
echo "Error accessing folder " $SRC
fi
}
program starts here 
SRC=/temp/file.in
TGT=/tgt/purge
mv_purge_files

Retrieve output/status of a variable from batch file to jenkins pipeline

I am trying the retrieve the output/status of a variable available in bat to a jenkins pipeline by setting env variable initially as true.
My expectation is that based on the value of a variable assigned inside bat (i.e., status=false), next stage could not be executed since when expression is given in that stage:
pipeline {
agent any
environment{
STATUS='TRUE'
}
stages {
stage('test1') {
steps {
bat '''set status=FALSE
echo %status%'''
echo "$status"
}
}
stage('test2') {
when{
environment name: 'STATUS', value: 'TRUE'
}
steps {
input message: 'Push', ok: 'GO!!'
}
}
}
}
The output which I am currently getting is o/p: false for bat execution and next step provides the output as true.
The echo "$status" is in pipeline, where as the environment STATUS changes are done on the node. AFAIK this won't get reflected in the pipeline itself.
What you could do is use returnStdout: true and maintain this variable state in the pipeline
def script = '''set status=FALSE
echo %status%'''
def status = bat(script: script, returnStdout: true)
echo "$status"
Following hakamairi answer above, #echo off should be added to the beginning of the script string, otherwise returnStdout: true will return the command prompt as well.
Also, adding .trim() by the end of the bat script (after its closing bracket) might prove useful if using the value of the assigned status variable somewhere else, where line break by the end is undesirable.

Launch PL/SQL script from batch file (with arguments)

I'm strugling at passing arguments to a PL/SQL script from a Windows .bat file.
Here is the content of the batch file :
#echo off
set mName = "test"
exit | sqlplus <connection_string> #test.sql %mName%
pause
And here is the content of test.sql :
set verify off
set serveroutput on size unlimited
BEGIN
DBMS_OUTPUT.PUT_LINE('&&1');
END;
/
I would expect to see "test" appearing in the shell but instead, I get the following message :
Enter value for 1:
SP2-0546: User requested Interrupt or EOF detected.
Does anyone have a solution to this problem ?
Remove the spaces around your = sign. Here's my working batch file:
#echo off
set mName="test"
exit | sqlplus <connection_string> #test.sql %mName%
pause
Also note that you can use the -L option on sqlplus for batch jobs:
-L Attempts to log on just once, instead of reprompting on error.

Batch with No args runs as job (scheduled task) with no errors, Batch with 1 arg fails with Access Denied. Why?

Here's a trivial batch:
#echo off
if not .%1==.-b goto else
echo Running with -b flag ON
goto endif
:else
echo Running with NO flags
:endif
Now, trying to run this from a scheduled task on a Windows Server 2003...
If the task is ran like: "C:\Test\test.bat" then the log (Schedlgu.txt) says:
"Test Job.job" (test.bat)
Started 7/14/2010 10:27:19 AM
"Test Job.job" (test.bat)
Finished 7/14/2010 10:27:19 AM
Result: The task completed with an exit code of (0).
However, when running like: "C:\Test\test.bat -b" then:
"Test Job.job" (test.bat -b) 7/14/2010 10:28:02 AM ** ERROR **
Unable to start task.
The specific error is:
0x80070005: Access is denied.
Try using the Task page Browse button to locate the application.
The task is running under the Admin account (of the domain). I have also granted full access to this user to the local cmd.exe
Any thoughts why the task fails when running a batch with one argument?
Thx
Run the task with parameters like this:
"C:\Test\test.bat" -b
Note the different quoting!
The fisrt string inside quotes is always considered the file name, hence the error message you see.

Resources