【问题标题】:Jenkins and return code from windows batch詹金斯并从 Windows 批处理返回代码
【发布时间】:2013-10-14 07:12:17
【问题描述】:

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

@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

在使用 google 一段时间后发现,调用 Ant 目标的返回码没有正确传递给 Jenkins 进行调用的 java 环境。我已经测试过使用“call”或“set ERRORLEVEL=1”之类的方法,但还没有找到解决方案。

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

问候

【问题讨论】:

    标签: windows batch-file ant jenkins


    【解决方案1】:

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

    我认为你必须使用setlocal EnableDelayedExpansion

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

    (参考是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!
       )
    )
    

    它没有解释为什么它在您的计算机上运行...可能是因为 EnableDelayedExpansion 已经在您的 dos 窗口中设置。

    编辑

    在批处理文件中:

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

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

    【讨论】:

    • 您建议的解决方案有效。你能解释一下 %FOO% 和 !FOO! 之间的区别吗? ?
    【解决方案2】:
    @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
    )
    

    【讨论】:

    • 正如我所提到的,我已经用“call”测试了一些东西。因此,您提出的解决方案导致:BUILD FAILED ... foo.xml:111: exec returned: 1 Total time: 5 seconds ELVL 0 PROCEED: 0
    • 以更好的方式更新
    • 您的更新会生成干净可读的代码。我现在将它与 SetLocale 和 !FOO! 一起使用。解决方案。完美运行!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-10
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多