Windows 主机上的 GitHub Actions(powershell?):前几行的退出代码被忽略

Posted

技术标签:

【中文标题】Windows 主机上的 GitHub Actions(powershell?):前几行的退出代码被忽略【英文标题】:GitHubActions on Windows host (powershell?): exit code of previous lines being ignored 【发布时间】:2021-12-05 11:01:36 【问题描述】:

我在 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、函数、脚本文件或可运行程序的名称。检查 名称的拼写,或者如果包含路径,请验证路径 是正确的,然后再试一次。

然后我看到this other SO answer,所以我把它转换成:

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 工作流程中的行吗?

【问题讨论】:

【参考方案1】:

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

if ($LASTEXITCODE)  exit $LASTEXITCODE 

如果您想保持代码较小,您可以通过 automatic $? variable 检查中间成功与失败,如果最近的命令或表达式成功,则它是一个包含 $true 的布尔值,在这种情况下如果退出代码为0,则推断外部程序:

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

请注意,如果您要使用 PowerShell (Core) 7+,您可以使用类似 bash 的方法,因为 &&||,pipeline-chain operators,现在支持 - 只要您以 && 结束每个语句内部行,您就可以将每个调用放在自己的行上:

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

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

【讨论】:

您的 PSv7+ 建议将保留为一,因为最初的动机是拆分线路,而不是只要您放好它就离开它 @knocte,如果这是关于可读性,您应该能够将声明分散到多行 - 请查看我的更新,它现在还显示了更简洁的 WinPS 解决方案。 嗯,它是关于可读性但不会失去功能(因此我的退出代码有问题);谢谢,将测试您的解决方案

以上是关于Windows 主机上的 GitHub Actions(powershell?):前几行的退出代码被忽略的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Windows 10 上的容器连接到 docker 主机(Docker for Windows)

Windows 7 上的本地主机

多台主机上的 Docker(Windows 和 Ubuntu)

主机 myhost 的 epmd 错误:Windows 10 上的地址(无法连接到主机/端口)

Windows 10 上的 Apache 2.4.46 虚拟主机

怎么把Windows主机上的目录共享到Ubuntu上