stede
stede

Reputation: 355

Jenkins and return code from windows batch

I using a Jenkins (on a windows machine) job to compile some code for different targets via Ant. For doing so, I wrap the call to the ant target within a (windows) batch loop like this:

@echo off
for %%t in (target1 target2 target3) do (
  ant -f build.xml build -DPARAM_TARGET=%%t
)

That was my first idea ... but this codes leads to an successful build even if (e.g.) target1 failed. So I put some more lines to the windows batch build step to get more overview. Also I have checekdout the code to get the same workingspace than Jenkins has to my local machine and add an test.bat to check the windows batch code can work at all.

@echo off
for %%t in (target1 target2 target3) do (
  ant -f build.xml build -DPARAM_TARGET=%%t
  echo ELVL: %ERRORLEVEL% 
  IF NOT %ERRORLEVEL% == 0 ( 
    echo ABORT: %ERRORLEVEL%
    exit /b %ERRORLEVEL%
  ) ELSE (
    echo PROCEED: %ERRORLEVEL%
  )
)

Testing this on my local windows machine shows the expected behaviour - here on success:

BUILD SUCCESSFUL
Total time: 3 seconds
ELVL: 0
PROCEED: 0

And on failure:

BUILD FAILED
C:\Work\...
C:\Work\...

Total time: 0 seconds
ELVL: 9009
ABORT: 9009

The same code on Jenkins do this:

BUILD FAILED
C:\Work\...
C:\Work\...

Total time: 4 seconds
ELVL: 0
PROCEED: 0

After using google for a while it reveals, that the return code from calling the Ant target is not properly passed to the java enviornment wherefrom Jenkins do the calls. I have tested around using "call" or "set ERRORLEVEL=1" something like this, but haven't found a soloution yet.

Anyone has an idea? Put the loop (target1-3) into a system groovy script and hande the callc manually - does that work?

Regards

Upvotes: 3

Views: 28046

Answers (2)

ben75
ben75

Reputation: 28726

I think your problem is because you read %ERROR_LEVEL% in a for loop.

I think you must use setlocal EnableDelayedExpansion

EnableDelayedExpansion : Expand variables at execution time rather than at parse time.

(ref is here)

Try to do something like this :

setlocal EnableDelayedExpansion

for %%t in (target1 target2 target3) do (
   ant -f build.xml build -DPARAM_TARGET=%%t
   echo ELVL: !ERRORLEVEL! 
   IF NOT !ERRORLEVEL! == 0 ( 
     echo ABORT: !ERRORLEVEL!
     exit /b !ERRORLEVEL!
   ) ELSE (
     echo PROCEED: !ERRORLEVEL!
   )
)

It don't explain why it runs on your computer... maybe because the EnableDelayedExpansion is already set in your dos windows.

EDIT

In batch-file :

  • %var% will be expanded when the code is parsed (i.e. before execution !)
  • !var! will be expanded when the code is executed

Since you are in a loop : %ERROR_LEVEL% is expanded once (i.e. just before first execution). But what you need is to re-expand ERROR_LEVEL for each iteration and that's the purpose of !ERROR_LEVEL! syntax.

Upvotes: 5

Stephen Connolly
Stephen Connolly

Reputation: 14116

@echo off
for %%t in (target1 target2 target3) do (
  ant -f build.xml build -DPARAM_TARGET=%%t
  echo ELVL: %ERRORLEVEL% 
  IF NOT %ERRORLEVEL% == 0 ( 
    echo ABORT: %ERRORLEVEL%
    exit /b %ERRORLEVEL%
  ) ELSE (
    echo PROCEED: %ERRORLEVEL%
  )
)

IIRC The issue is that ant.bat is a batch file, so you need to call it, e.g.

@ECHO OFF
FOR %%t IN (target1 target2 target3) DO (
  CALL ant.bat -f build.xml build -DPARAM_TARGET=%%t
  ECHO ELVL: %ERRORLEVEL% 
  IF NOT %ERRORLEVEL% == 0 ( 
    ECHO ABORT: %ERRORLEVEL%
    EXIT /b %ERRORLEVEL%
  ) ELSE (
    ECHO PROCEED: %ERRORLEVEL%
  )
)

Update

Actually there is a nicer way:

@ECHO OFF
FOR %%t IN (target1 target2 target3) DO (
  CALL ant.bat -f build.xml build -DPARAM_TARGET=%%t || EXIT /b 1
)

Upvotes: 0

Related Questions