Jenkins - simply robocopy in Jenkins finishes marks build with failure - batch-file

I have a simply windows batch command (robocopy) that returns zero errors but is always marked as a failure in Jenkins. I would like to know why?
D:\Jenkins\jobs\Jenkins Config Backup\workspace>exit 1
Build step 'Execute Windows batch command' marked build as failure
Finished: FAILURE

robocopy returns a bit map
For details see here: http://ss64.com/nt/robocopy-exit.html
In summary: All exit codes up to '3' are fine.
This is the batch file code I usually use:
set SOURCE= ...
set DESTINATION= ...
robocopy /MIR %SOURCE% %DESTINATION%
#echo robocopy exit code: %ERRORLEVEL%
#if %ERRORLEVEL% GTR 3 ( echo robocopy ERROR )
#if %ERRORLEVEL% GTR 3 ( exit %ERRORLEVEL% )
#set ERRORLEVEL=0
You could also do a "goto" and not exit.

Jenkins marks a build as failed when the exist code of a batch script is not 0. If robocopy is the last command in your script, the robocopy exit code will be taken.
Robocopy does not adhere to the standard that an exit code other then 0 means a failed build. You need to evaluate the robocopy exit code and end your script with exit 0 or exit 1 depending on the success of robocopy.
Have a look at the robocopy exit codes.

Updating this question for jenkins pipelines - this works for me:
def robocopy(cmd)
{
// robocopy uses non-zero exit code even on success, status below 3 is fine
def status = bat returnStatus: true, script: "ROBOCOPY ${cmd}"
println "ROBOCOPY returned ${status}"
if (status < 0 || status > 3)
{
error("ROBOCOPY failed")
}
}
Alternatively, you may want to look at the File Operations Plugin

Related

Why batch sometimes does not process commands like CMD does and gives unexpected and different results [duplicate]

This question already has an answer here:
wrong value of %errorlevel% in nested if in .bat file
(1 answer)
Closed 2 years ago.
When I run a command from the CMD directly it works perfectly fine but when run the same command in a batch file (or Jenkins using batch) it gives me a different result and I dont understand why.
To explain it simple, I'm running command below to search for a literal string within a log file:
findstr /C:"MY STRING WITH A %variable%" M:\Logs\output.log
If I check the %ERRORLEVEL% of the result it shows the expected values (0 = found the string or 1 = didnt find it)
However, when I run the same line from a batch file, even from Jenkins, the result is always 0, even though the string is not present in the log, the %ERRORLEVEL% is always 0.
This is the portion of the batch file which includes the command:
if %COUNTER% ==1 (
if not exist M:\Logs\current_bak (
ROBOCOPY "M:\Logs\tkcurrent" "M:\Logs\tkcurrent_bak"
REN "M:\Logs\current" "M:\Logs\current_bak"
MKDIR M:\Logs\current
echo Folders have been backed up
) else (
echo Back up folders are already in place )
findstr /C:"MY STRING WITH A %variable%" M:\Logs\output.log
if %ERRORLEVEL% == 0 (
echo Process has already being kicked off for the files with date %YYMMDD%, skipping it...
echo Download and backup compleated
exit /b 0 )
else (
echo Triggering next Jenkins Job:
curl -I http://<user>:<token>#remoteserver.domain.com:<port>/job/Hello_World/build?token=hello_world
exit /b 0 )
)
Has someone experienced this in the past or can guide me better on what I'm doing wrong or not understanding?
Thanks a lot!
Your error is a basic syntactical error that I've made plenty of times as well :P. The issue is in your else statement which is a peculiar issue, but what happens is that the else only will get processed if it is on the same line as the if statement.
PROOF OF CONCEPT
If I have the if statement and else on different lines like so:
#echo off
echo test
if errorlevel 1 (echo here)
else (echo not there)
pause
This will have the error:
'else' is not recognized as an internal or external command,
operable program or batch file.
However if I change the code a tiny bit so that the else is on the same line as the if, like so:
#echo off
echo test
if errorlevel 1 (echo here
) else (echo not there)
pause
It will not have an error and output
test
not there
Your code done correctly would be:
if %COUNTER%==1 (
if not exist M:\Logs\current_bak (
ROBOCOPY "M:\Logs\tkcurrent" "M:\Logs\tkcurrent_bak"
REN "M:\Logs\current" "M:\Logs\current_bak"
MKDIR M:\Logs\current
echo Folders have been backed up
) else (
echo Back up folders are already in place )
findstr /C:"MY STRING WITH A %variable%" M:\Logs\output.log
if %ERRORLEVEL% == 0 (
echo Process has already being kicked off for the files with date %YYMMDD%, skipping it...
echo Download and backup compleated
exit /b 0
) else (
echo Triggering next Jenkins Job:
curl -I http://<user>:<token>#remoteserver.domain.com:<port>/job/Hello_World/build?token=hello_world
exit /b 0 )
)
For more information on this type in if /? into cmd.
Note: I also fixed I believe a typo in your code of findsrt instead of findstr

JENKINS job is failed even if ROBOCOPY command successfully executed in a BAT script

I am executing a windows bat script through jenkins. Batch file is giving the desired output,however build is failing.My batch file is..
cd /d D:\\Bank\\Member\\ID
if %errorlevel% neq 0 exit /b %errorlevel%
mkdir OTP
if %errorlevel% neq 0 exit /b %errorlevel%
robocopy C:\Corporate D:\\Bank\\Member\\ID\ /E /XF *.bat
if %errorlevel% neq 1 exit /b %errorlevel%
cd /d D:\\Bank\\Staff\\ID
ROBOCOPY GIVES EXIT CODE 1 AFTER SUCESSFULLY COPYING FILES.
BUT JENKINS FAILS BUILD AND GIVING BELOW ERROR:
Build step 'Execute Windows batch command' marked build as failure
Finished: FAILURE
I Want the build to be successful if robocopy exits code 1.
My best advise would be to use jenkins-pipeline, try/catch block, and use bat commands as few as possible (or do not use at all).
But considering your case there's a simple solution as well: just set the field "ERRORLEVEL to set build unstable" to 1 (or other suitable number). The field appears if you click "Advanced" button under the "Execute Windows batch command" block:
This method will check your build as "Unstable", but will continue to execute.
please use like following to avoid:
bat "robocopy /s source dest & EXIT /B 0"
The above will continue the jenkins build even if robocopy returns non-zero errorlevel. Robocopy does not return 0 for various reasons even after successfull copy, as it compared the two folders. Please lookup for it's return code to know more details
As mentioned here, the first criteria to check is the account used to run Jenkins.
Type services.msc to open the Windows services and look for the Jenkins service.
Instead of "Local Service Account", use your own account: that will avoid any right issue.
But: the other criteria is to display the error code.
As mentioned here:
All exit codes up to '3' are fine.
So after robocopy, you can add:
#echo robocopy exit code: %ERRORLEVEL%
#if %ERRORLEVEL% GTR 3 ( echo robocopy ERROR )
#if %ERRORLEVEL% GTR 3 ( exit %ERRORLEVEL% )
#set ERRORLEVEL=0
REM at the end:
exit /b 0
That will ensure Jenkins don't fail the batch step, even though the original error level for robocopy was 1.

Batch script starting javafx bundled application shows no output [duplicate]

I have a batch file that will run several other file (lets call it procedure file) such as .bat,.exe,.py, etc...
if Not Exist JobStreamUnitTest_CreateTextPython_4-27-2015.txt (
Start /wait /b C:\Users\blee2\Documents\UnitTest\CreateTextFile.py || exit %errorlevel%
copy /y nul JobStreamUnitTest_CreateTextPython_4-27-2015.txt
)
if Not Exist JobStreamUnitTest_CreateTextBatch_4-27-2015.txt (
Start /wait /b C:\Users\blee2\Documents\UnitTest\CreateNewFile.bat || exit %errorlevel%
copy /y nul JobStreamUnitTest_CreateTextBatch_4-27-2015.txt
)
if Not Exist JobStreamUnitTest_CreateTextConsole_4-27-2015.txt (
Start /wait /b C:\Users\blee2\Documents\UnitTest\TestConsole.exe apple || exit %errorlevel%
copy /y nul JobStreamUnitTest_CreateTextConsole_4-27-2015.txt
)
if Not Exist JobStreamUnitTest_HelloWorld_4-27-2015.txt (
Start /wait /b C:\Users\blee2\Documents\UnitTest\HelloWorld.bat || exit %errorlevel%
copy /y nul JobStreamUnitTest_HelloWorld_4-27-2015.txt
)
So basically, the batch file will check if the following file need to be run based on the existence of dummy file associate with each of the procedure file.
This will prevent us from running successfully run if we are to run the batch file the second time.
If there is no error in any of the procedure file then the code will work fine.
The exit error will only work if the file/filepath is incorrect.
The problem I am facing is that, since the Start /wait /b will always execute regardless of if one of my procedure file have an error. Therefore the exit %errorlevel% would not be run.
How do I allow the batch file to detect an error if a procedure file is broken?
I would like to exit/terminal the batch file if one of the procedure file is not working. Any thoughts?
PS. /wait is needed because the start should be running in a sequential order.
/b is needed or else the program will stop after running a .bat ; /b allow us to run the batch file in the same cmd window.
Appreciate any help and thank you
Edited:
The code would work if i do the following. But I am hoping to have a consistency format in my batch file, since the batch file is being generated by C# with parsing of .xml files.
if Not Exist JobStreamUnitTest_CreateTextPython_4-27-2015.txt (
C:\Users\blee2\Documents\UnitTest\CreateTextFile.py || exit %errorlevel%
copy /y nul JobStreamUnitTest_CreateTextPython_4-27-2015.txt
)
if Not Exist JobStreamUnitTest_CreateTextBatch_4-27-2015.txt (
Start /wait /b C:\Users\blee2\Documents\UnitTest\CreateNewFile.bat || exit %errorlevel%
copy /y nul JobStreamUnitTest_CreateTextBatch_4-27-2015.txt
)
I have found some issues in start /WAIT /B any_program || exit %errorlevel%:
#1 - %errorlevel% variable will be expanded at parse time. Thus your script never returns proper exit code. See EnableDelayedExpansion.
#2 - || conditional command execution: unfortunately I can't document it properly, but all my attempts with it failed in relation to start command...
IMHO next code snippet (the only example) could work as expected:
if Not Exist JobStreamUnitTest_CreateTextBatch_4-27-2015.txt (
start /B /WAIT C:\Users\blee2\Documents\UnitTest\CreateNewFile.bat
SETLOCAL enabledelayedexpansion
if !errorlevel! NEQ 0 exit !errorlevel!
ENDLOCAL
copy /y nul JobStreamUnitTest_CreateTextBatch_4-27-2015.txt
)
#3 - a bug in the implementation of the start command.
start /WAIT /B doesn't work (the /wait argument is ignored):
==>start /WAIT /B wmic OS GET Caption & echo xxx
xxx
==>Caption
Microsoft Windows 8.1
There's a simple workaround (from SupeUser) as start /B /WAIT works:
==>start /B /WAIT wmic OS GET Caption & echo xxx
Caption
Microsoft Windows 8.1
xxx

Batch exit if drive device not ready/unavailable

I need to force a batch file to stop and exit the batch program (but not the command prompt) if selecting a drive/device fails because it is not ready/unavailable.
I've tried...
d: || exit /b
...and I also tried...
IF %ERRORLEVEL% NEQ 0 exit /b %errorlevel%
...after every line without success.
Like this :
if not exist d: exit/b

using errorlevel in a batch file to know if a program exited normally

We have a program that is occasionally crashing. The customer runs the program from a scheduled task. When the program is run with a certain parameter, the program runs as an interface engine, creating a file and then ftp'ing the file to another server for import by another program.
I was wondering if I might have the scheduled task instead run a batch file. The batch file would run the program and check errorlevel as the program exits. If errorlevel is not equal to zero, then batch file would run the program again. Does anyone see problem with my plan to use errorlevel in a batch file?
Here's an example of the batch file:
:start
myPgm.exe intfc
if errorlevel <> 0 then start
I would write it like so:
:start
myPgm.exe intfc
IF %errorlevel% NEQ 0 GOTO :error
GOTO :end
:error
echo There was an error.
EXIT 1
:end
echo End.
EXIT 0
Your IF statement is wrong. It should read
if %errorlevel% neq 0 goto start
Or your script could read
:start
myPgm.exe intfc || goto start

Resources