首页 > 解决方案 > Windows 主机上的 GitHubActions(powershell?):前几行的退出代码被忽略

问题描述

我在 macOS 通道中有这一步:

jobs:
  macOS_build:
    runs-on: macOS-latest
    steps:
    - uses: actions/checkout@v1
    - name: Build in DEBUG and RELEASE mode
      run: ./configure.sh && make DEBUG && make RELEASE

然后我以这种方式成功拆分它:

jobs:
  macOS_build:
    runs-on: macOS-latest
    steps:
    - name: Build in DEBUG and RELEASE mode
      run: |
        ./configure.sh
        make DEBUG
        make RELEASE

此转换有效,因为如果make DEBUG失败,make RELEASE则不会执行,整个步骤被 GitHubActions 标记为 FAILED。

但是,尝试从 Windows 通道转换它:

jobs:
  windows_build:
    runs-on: windows-latest
    steps:
    - uses: actions/checkout@v1
    - name: Build in DEBUG and RELEASE mode
      shell: cmd
      run: configure.bat && make.bat DEBUG && make.bat RELEASE

对此:

jobs:
  windows_build:
    runs-on: windows-latest
    steps:
    - uses: actions/checkout@v1
    - name: Build in DEBUG and RELEASE mode
      shell: cmd
      run: |
        configure.bat
        make.bat DEBUG
        make.bat RELEASE

不起作用,因为奇怪的是,只执行了第一行。所以我尝试将shell属性更改为powershell

jobs:
  windows_build:
    runs-on: windows-latest
    steps:
    - uses: actions/checkout@v1
    - name: Build in DEBUG and RELEASE mode
      shell: powershell
      run: |
        configure.bat
        make.bat DEBUG
        make.bat RELEASE

然而,这失败了:

configure.bat :术语“configure.bat”未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。检查名称的拼写,或者如果包含路径,请验证路径是否正确并重试。

然后我看到了另一个 SO 答案,所以我将其转换为:

jobs:
  windows_build:
    runs-on: windows-latest
    steps:
    - uses: actions/checkout@v1
    - name: Build in DEBUG and RELEASE mode
      shell: powershell
      run: |
        & .\configure.bat
        & .\make.bat DEBUG
        & .\make.bat RELEASE

这最终独立启动了所有批处理文件,但是它似乎忽略了退出代码(所以如果 configure.bat 失败,它仍然运行下一行)。

知道如何正确分隔 GithubActions 工作流程中的行吗?

标签: windowspowershellbatch-filegithub-actionsexit-code

解决方案


在 PowerShell 中,如果要对最近执行的外部程序或脚本的(非零)退出代码执行操作,则必须在每次调用后检查自动$LASTEXITCODE变量:

if ($LASTEXITCODE) { exit $LASTEXITCODE }

如果你想保持代码小,你可以通过自动$?变量检查中间​​成功与失败,这是一个布尔值,包含$true最近的命令或表达式是否成功,在外部程序的情况下,如果退出则推断代码是0

.\configure.bat
if ($?) { .\make.bat DEBUG }
if ($?) { .\make.bat RELEASE }
exit $LASTEXITCODE

请注意,如果您要使用PowerShell (Core) 7+,则可以使用bash类似方法,因为现在支持&&and||管道链运算符- 只要您以 结束每个语句内部行,您就可以放置每个电话都在自己的线路上:&&

# PSv7+
.\configure.bat && 
.\make.bat DEBUG && 
.\make.bat RELEASE

但是,请注意,当调用1PowerShell CLI-Command时,任何非零退出代码都会被映射到,我认为这是在幕后发生的,并假设调用了外部程序last。也就是说,特定的非零退出代码会丢失。如果感兴趣,exit $LASTEXITCODE请在上面添加一行。


推荐阅读