Jenkins并从windows批处理中返回代码

时间:2013-10-14 07:12:18

标签: windows batch-file ant jenkins

我使用Jenkins(在Windows机器上)作业通过Ant为不同的目标编译一些代码。 为此,我将调用包含在(windows)批处理循环中的ant目标中,如下所示:

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

这是我的第一个想法......但即使(例如)target1失败,此代码也会导致成功构建。因此,我在Windows批处理构建步骤中添加了更多行,以获得更多概述。另外,我已经知道代码来获得与Jenkins相同的工作空间到我的本地机器并添加一个test.bat来检查windows批处理代码是否可以工作。

@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%
  )
)

在我的本地Windows机器上测试它会显示预期的行为 - 这是成功的:

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

失败时:

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

Total time: 0 seconds
ELVL: 9009
ABORT: 9009

Jenkins上的相同代码执行此操作:

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

Total time: 4 seconds
ELVL: 0
PROCEED: 0

使用谷歌一段时间后,它显示,调用Ant目标的返回代码没有正确传递给Jenkins进行调用的java环境。我已经测试过使用“call”或“set ERRORLEVEL = 1”这样的东西,但还没有找到解决方案。

有人有想法吗? 将循环(target1-3)放入系统groovy脚本并手动处理callc - 这有用吗?

此致

2 个答案:

答案 0 :(得分:5)

我认为您的问题是因为您在for循环中读取了%ERROR_LEVEL%。

我认为你必须使用setlocal EnableDelayedExpansion

  

EnableDelayedExpansion:在执行时而不是在解析时扩展变量。

(ref is here

尝试做这样的事情:

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!
   )
)

它无法解释为什么它会在您的计算机上运行...可能是因为已在您的DOS窗口中设置了EnableDelayedExpansion。

修改

在批处理文件中:

    解析代码时(即执行前!)将扩展
  • %var%
  • !var!将在代码执行时展开

由于你处于循环中:%ERROR_LEVEL%被展开一次(即在第一次执行之前)。但你需要的是为每次迭代重新扩展ERROR_LEVEL,这就是!ERROR_LEVEL!语法的目的。

答案 1 :(得分:0)

@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问题是ant.bat是一个批处理文件,所以你需要调用它,例如

@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%
  )
)

更新

实际上有一种更好的方式:

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