【问题标题】:For loop in gilab-ci exits when inner command produces non-zero exit code当内部命令产生非零退出代码时,gitlab-ci 中的 for 循环存在
【发布时间】:2023-12-30 22:07:01
【问题描述】:

我正在尝试在我的 gitlab-ci 中启动 mypy 代码分析。我用下面的代码来做:

mypy:
  only:
  - master
  script:
  - for config_path in $(find * -regex '.*__init__.py' -mindepth 2); do mypy $config_path; exit_code=$?; done
  allow_failure: true

不幸的是,CI 在对 find 命令找到的列表中的第一个元素执行 mypy 后停止。命令 mypy 返回 RC=2。

由于警告,我将退出代码的提取放入变量中:如果任何脚本命令返回的退出代码不为零,则作业将失败并且不会执行进一步的命令。通过将退出代码存储在此处提到的变量中,可以避免这种行为:https://docs.gitlab.com/ee/ci/yaml/README.html#script

我如何才能启动整个 for 循环,尽管它的主体内有非零退出代码?

【问题讨论】:

  • 试试do mypy $config_path || true; done
  • @Grumbunks:谢谢,您的解决方案有效。您可以将其发布为答案让我标记它。

标签: bash gitlab gitlab-ci


【解决方案1】:

我通过在子shell中执行以下命令避免了非零退出代码的退出:

bash -c "set +e; for i in {1..30}; do (INSERT YOUR COMMAND HERE) && exit 0; sleep 1; done; exit 1"

【讨论】:

    【解决方案2】:

    试试

    do mypy $config_path || true; done
    

    无论mypy $config_path 有什么返回码,|| true 都会强制返回 0。

    【讨论】:

      【解决方案3】:

      我只是将脚本放在文本文件中,将其添加到 git,然后从 .gitlab-ci.yml 调用它。比如:

      //run_mypy.sh
      for config_path in $(find * -regex '.*__init__.py' -mindepth 2); do mypy $config_path; exit_code=$?; done
      
      //.gitlab-ci.yml
      mypy:
        only:
         - master
        script:
         - run_mypy.sh
        allow_failure: true
      

      为了让复杂的脚本直接从.gitlab-ci.yml 文件运行,我已经尝试并挣扎了太多次。在我的例子中,它是 windows 批处理文件和 powershell 脚本,但它们都遇到了同样的问题:你有一个支持某种格式并使用某些特殊字符的 yaml 文件,而在其中你试图表达一种完全不同的格式.

      从单独的脚本控制退出代码也更容易,然后尝试弄清楚 GitLab 如何处理退出代码。同样,这可能主要是 powershell 脚本的问题,但我仍然建议大家将您的复杂脚本存储在 .gitlab-ci.yml 之外。

      【讨论】:

        【解决方案4】:

        我不确定 gitlab-ci 是否支持

        while read -r -d '' config_path; do mypy "$config_path"; exit_code=$?; done < <(find . -mindepth 2 -name '*__init__.py' -print0)
        

        错误可能是由于 -mindepth 2 出现在 -regex 标志之后,但是 -name 或 -iname 可能更适合此

        【讨论】:

        • 感谢您的回复,但很遗憾没有成功。它在第一个 Pyhon 文件后停止处理,其中 mypy 返回非零 RC,而仍有数百个文件需要检查:$ while read -r -d '' config_path; do mypy "$config_path"; exit_code=$?; done &lt; &lt;(find . -mindepth 2 -name '*__init__.py' -print0)test_path_1 is not a valid Python package nameERROR: Job failed: exit code 1
        • 这看起来是 mypy 特定的。尝试在 test_path_1 中添加一个空的 __init__.py 文件,看看它是否会自行修复:github.com/python/mypy/issues/1645
        • 情况是命令(你和我的)在我的本地操作系统上正常工作(mypy 检查循环中找到的所有文件)。它们只是在 gitlab-ci 中不能正常工作(只检查第一个找到的文件)。
        • 这听起来像是环境变量问题。我需要查看您的完整配置才能确切知道是什么,但如果您可以尝试在 mypy 脚本上方添加 PYTHONPATH="$PYTHONPATH:." ,它会将基本目录添加到路径中。此配置看起来正确:patricksoftwareblog.com/…