有效调试 GitHub Actions 工作流🚀
去年,当我在为 SciPy重新设计 CI/CD 管道时,我有机会使用GitHub Actions。 GitHub Actions 是GitHub 的内部 CI/CD 服务,希望能够说服许多项目维护人员和开发人员从外部CI/CD服务(如TravisCI中的TravisCI)转移到 GitHub Actions希望有一个可以构建、测试和部署的中央服务。
然而,与其他 CI/CD 服务(如CircleCI)不同,它具有使用CLI和SSH 机制的适当调试机制,GitHub Actions 不提供任何调试工具失败的工作流程。它通常会导致开发人员多次提交,以触发和重新触发 CI/CD 工作流,以确保他们的提交旁边有一个绿色的勾号。有效调试 GitHub Actions 工作流程的要求让我陷入了困境。

使用 GitHub Actions 最好的部分是GitHub API的可用性,我们可以从我们的工作流程本身使用它。 GitHub Actions 还具有一个充满活力的市场,其中的应用程序旨在让开发人员更直接地使用 GitHub Actions。更有意义的是,一定有人已经解决了这个问题,而且我发现的解决方案不是一两个,而是多个!
在本博客中,我们将探讨几种有效调试 GitHub Actions 工作流程的方法。其中一些方法已经过实战测试(在调试许多项目的工作流程时),而有些方法对我来说是新的尝试并开始使用!
创建 GitHub Actions 工作流
我将使用一个简单的Flask 应用程序和一个返回Hello World消息的 API 端点来开始。我还为其添加了一个测试,以确保我们可以安装所有依赖项并在 CI 管道上运行测试以及使用Flake8进行一些 linting。测试我们的应用程序的最基本工作流程类似于以下内容:
# Path: .github/workflows/ci.yml
name: Flask CI
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: |
python -m pytest
- name: Run Flake8
run: |
pip install flake8
flake8 .
工作流用YAML编写,然后作为项目.github/workflows目录中存储库的一部分提交。一旦代码被推送,GitHub 将根据它们包含的指令检测需要触发和处理的工作流。
上面的工作流程启动了一个工作流程,每个推送和拉取请求都会触发该工作流程,并在 Ubuntu 运行器上检查代码。它将进一步安装依赖项、运行测试并检查代码库以确保样式检查到位。现在我们有了一个基本的工作流程设置,这就是它在推送后的样子:

让我们检查一下如何进一步深入研究这些工作流程。
使用act在本地运行工作流
act是Nektos提供的一个工具,它提供了一种在本地运行 GitHub Actions 的便捷方式。它提供了一种快速的方法来在本地验证您对 CI 的更改,而无需将更改提交/推送到工作流以触发和验证它们。作为本地任务运行程序,它可以带来快速反馈和兼容性,以验证我们所有的 CI 作业。
在内部,act通过构建和运行执行作业的 Docker 容器来模拟我们想要运行的工作流。act将市场操作作为单独的 Docker 镜像拉取,并允许我们以优雅的方式在 Docker 容器中使用它们。虽然内部实现很复杂,但act为您提供了一种简洁的方式,只需一个命令即可在本地运行 GitHub Actions 工作流!
可以使用Homebrew、Chocolatey甚至是简单的 BASH 脚本在本地设置 act。要使用 BASH 脚本进行设置,请在终端上推送以下命令:
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
如果您有可用的 Homebrew,请使用以下命令安装它:
brew install act
下一步是定义我们可以用来在本地运行工作流的自定义图像。act为 Ubuntu GitHub runner 提供了一个微型、中型和更大的 Docker 镜像。但是,act还不支持 Windows 和 macOS 镜像。第一次运行 act 时,我们可以定义要用于本地 CI 运行的图像。配置保存在~/.actrc文件中。您可以选择直接从 GitHub Container Registry 拉取镜像:
docker pull ghcr.io/catthehacker/ubuntu:act-latest
在 GitHub 存储库中,第一次运行act时,它会找到./.github/workflows和所有存在的工作流。要签出作为 GitHub Actions CI 的一部分列出的作业,请推送以下命令:
act -l
它返回以下内容:
$ act -l
Stage Job ID Job name Workflow name Workflow file Events
0 build build Flask CI ci.yml push,pull_request
您现在可以通过指定act来运行工作流,或者如果有多个工作流,您可以通过指定act -j <job_name>调用单个工作流:
act -j build
成功完成工作流后,您将看到✅ Success表示工作流已成功执行!

但是如果工作流运行失败怎么办?在这种情况下,最好使用-v, --verbose标志添加详细选项,以尽可能多地获取有关act运行时发生的工作流运行的信息。
您还可以使用以下命令获取 shell 访问权限,因为act实际上是 GitHub Action 工作流程的本地复制,尽管位于 Docker 容器内:
docker run -it -v $(pwd):/app/ ghcr.io/catthehacker/ubuntu:act-latest
由于本地项目文件映射到/app/目录,您可以开始运行 apt 命令、编辑文件以及确保工作流有效运行所需的任何操作!如果镜像标签不可用,请使用docker images检查您机器上可用的镜像标签(对于中等大小的镜像,默认为act-latest)。
查看法案的综合文档了解更多配置细节。
使用tmate获取SSH访问
虽然大多数 CI 服务,例如 CircleCI 或 TravisCI,都有一个特色调试模式,可以让你的 SSH 在运行的实例(VM 或容器)中,但 GitHub Actions 没有这样的功能(还没有!)。要在正在运行的操作中进行 SSH,您可能会发现tmateGitHub 操作对您的用例很有用。
此 GitHub Action 允许您访问正在运行的 GitHub Actions 运行程序。一旦 Action 到达此步骤,就会调用 SSH 服务器,并且每隔 5 秒将连接信息打印到 Checks 选项卡的输出中。您可以为您的用例打开一个 Web 终端,也可以使用 SSH 直接从您的终端验证和调试您的工作流程。
要开始,请在您的工作流作业中添加此步骤:
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
触发工作流后,您现在会注意到 tmate 会话可用于您的 GitHub Action 运行器:

你可以打开你的终端(我使用Warp)并输入:
ssh 6EJCQMtC5ET9RaPhVu3DCwfnj@nyc1.tmate.io
但是 tmate 是如何工作的呢? tmate 是一个终端多路复用器,具有即时终端共享功能,您可以通过 SSH 将终端访问权限共享给多个用户。您可以与希望一起调试失败的工作流的各种用户共享上述 Web shell 链接和 SSH 访问权限。
为了充分利用它,建议将它与${{ failure() }}的 if 条件一起使用,以确保仅在上述任何步骤失败时才调用 tmate。它确保您在不需要时不会调用 tmate。还建议添加timeout-minutes以减少 GitHub Action 运行器的使用,并且不让它在运行器超时之前占用整个持续时间。
为确保您是唯一能够获得 SSH 访问权限的人(如果它是公共项目),请使用您在 GitHub 上注册的公共 SSH 密钥向运行器进行身份验证。为此,请添加:
with:
limit-access-to-actor: true
这也确保了在工作流运行时不会有人访问您的GITHUB_TOKEN,并且您可以安全地调试失败的工作流。
如果您不是 tmate 的忠实粉丝,您可以选择使用Debug via SSH操作,该操作使用 Ngrok。但是,请记住在问题解决后删除调试步骤,并且您的 CI 状态为绿色!
使用 Foresight 调试工作流
我遇到的一个新工具是Thundra 的 Foresight,它有助于调试和分析你的 GitHub Actions 工作流程。 Foresight 为 GitHub Actions 工作流提供监控/调试功能,并支持跨 Java、JavaScript (Jest) 和 Python (PyTest) 的测试。虽然Thundra不适合上述两个用例,但它允许大型组织批判性地分析其失败的测试套件并显着降低 CI 成本和构建时间。
首先,我们需要在 Thundra 上创建一个帐户并选择 Foresight 作为我们希望使用的产品。我们现在可以继续创建一个新项目。通过项目设置,获取Thundra API 密钥和 Thundra 项目 ID,这是在我们的工作流程中配置 Foresight 所必需的。添加以下步骤作为工作流作业的一部分:
- name: Install Thundra Python Agent
uses: thundra-io/thundra-foresight-python-action@v1
with:
apikey: ${{ secrets.THUNDRA_APIKEY }}
project_id: ${{ secrets.THUNDRA_PROJECT_ID }}
command: pytest
您也可以单独运行pytest命令。您现在可以在相应的小部件上查看最新的测试运行详细信息。 Foresight 可以向您显示整体测试运行时间,并帮助您发现不稳定、跳过或非常慢的测试。

通过 Foresight,您可以查看更多 CI 可观察性数据,例如测试套件的性能指标、失败的频率、操作日志,并通过创建“快照”帮助您跟踪错误并找出特定测试失败的原因。与启用本地运行的act相比,Foresight 提供回放功能来帮助您指出失败的测试,从而确保时间旅行调试。
结论
在此博客中,我们发现了许多调试、模拟和分析 GitHub Actions 工作流程以确保它们正常工作的方法。不再需要通过随机修复进行连续提交,以确保您的 CI 是绿色的并且部署成功! GitHub Actions 还具有更多附加功能,允许您跨多个场景、架构和环境测试您的部署,使其成为可靠测试和部署的协作工具,而不仅仅是简单的 CI/CD 工具。
谢谢阅读!查看Pajamas 2021 存储库,其中托管 Flask 应用程序和 GitHub Actions 工作流程的源代码,我在睡衣会议 2021期间介绍了这些源代码。
更多推荐

所有评论(0)