本地运行GitHub Actions:使用act工具提升CI/CD开发调试效率
1. 项目概述为什么我们需要在本地运行 GitHub Actions如果你和我一样日常开发中重度依赖 GitHub Actions 来自动化构建、测试和部署那你一定也经历过这样的场景为了测试一个简单的.yml配置文件里的语法错误或者验证某个步骤的输出不得不反复地git push到远程仓库然后眼巴巴地等着 GitHub 的 Runner 排队、拉取代码、执行任务。这个过程短则几分钟长则十几二十分钟宝贵的开发时间就在等待中溜走了。更不用说如果 Action 涉及到敏感信息或者需要访问内部资源直接在云端跑总让人心里不踏实。这就是我们今天要解决的核心痛点提升 GitHub Actions 的开发和调试效率并增强其可控性。通过将 Actions 的运行环境“搬”到本地我们能够实现即时反馈、离线测试、以及更安全的沙盒验证。本文将手把手带你搭建一套完整的本地 GitHub Actions 运行与测试环境核心工具是act。我会基于自己多次搭建和踩坑的经验不仅告诉你“怎么做”更会详细解释每个步骤“为什么这么做”以及过程中可能遇到的“坑”和“避坑指南”。2. 核心工具选型与原理浅析2.1 为什么是act在本地运行 GitHub Actions社区有几个选择但act是目前最成熟、最活跃的开源项目。它的工作原理可以简单理解为一个本地的 GitHub Actions Runner 模拟器。解析工作流文件act会读取你项目根目录下的.github/workflows/*.yml文件解析其中定义的on触发器、jobs和steps。创建 Docker 容器环境GitHub Actions 的每个 Job 都在一个干净的 Runner 环境中执行。act利用 Docker 来模拟这个环境。它会根据工作流中指定的runs-on如ubuntu-latest,macos-latest拉取或使用对应的 Docker 镜像作为运行环境。执行 Action 步骤对于工作流中的每个stepact会区分两种情况使用uses的 Action这通常是引用社区或自定义的 Action如actions/checkoutv4。act会尝试从 GitHub 或本地缓存中获取该 Action 的定义本身也是一个包含action.yml的仓库并在容器内执行它。使用run的命令这是直接执行 shell 命令。act会直接在当前的 Docker 容器中执行这些命令。模拟 GitHub 上下文act会向容器内注入一系列模拟的环境变量如GITHUB_SHA,GITHUB_REPOSITORY使得 Action 脚本认为自己正在真实的 GitHub Runner 中运行。注意act的模拟并非 100% 完美。特别是对于macos和windows环境由于它底层依赖 DockerLinux 容器只能使用特定的替代镜像来近似模拟无法完全复现原生系统的行为。对于ubuntu环境其还原度非常高足以满足绝大多数开发测试场景。2.2 环境依赖Docker 是基石act的强大依赖于 Docker 提供的容器化隔离能力。因此安装 Docker 是第一步也是最重要的一步。在不同的操作系统上安装方式略有差异。macOS推荐使用 Docker Desktop for Mac安装简单集成度高。Linux可以直接使用各发行版的包管理器安装 Docker Engine 和 Docker Compose。Windows情况稍复杂也是本文会重点讲解的部分因为涉及到 WSL 的最佳实践。3. Windows 环境下的详细搭建流程在 Windows 上获得最佳体验的方案是WSL 2 Docker Desktop。WSL 2 提供了一个完整的 Linux 内核让 Docker 能够高效运行。3.1 安装与配置 WSL 2启用 WSL 功能以管理员身份打开 PowerShell执行以下命令。这会在后台启用必要的 Windows 功能。wsl --install这个命令通常会默认安装 Ubuntu 发行版。如果你想安装其他发行版可以先运行wsl --install -d DistributionName或者去 Microsoft Store 搜索安装。设置 WSL 2 为默认版本安装完成后确保新发行版使用 WSL 2。wsl --set-default-version 2启动并初始化 Linux 发行版从开始菜单找到你安装的 Linux 发行版如 Ubuntu并启动。首次启动需要等待几分钟进行解压并让你设置 UNIX 用户名和密码。3.2 安装 Docker Desktop for Windows下载安装包前往 Docker 官网下载 Docker Desktop for Windows 安装程序。关键安装选项安装过程中务必勾选“Use WSL 2 instead of Hyper-V”相关选项。这能让 Docker 与 WSL 2 深度集成性能更好资源占用更合理。启动与登录安装完成后启动 Docker Desktop。首次启动可能会提示你登录 Docker Hub 账号虽然对于act的基本使用不是必须的但登录后可以解除拉取镜像的速率限制建议操作。常见问题排查启动卡在 “Starting the Docker Engine...”这是一个经典问题通常与后台服务冲突或权限有关。方案一重启 Docker 服务以管理员身份打开 PowerShell 或 CMDnet stop com.docker.service net start com.docker.service然后重新打开 Docker Desktop。方案二重置 Docker Desktop在系统托盘右键点击 Docker 图标选择 “Troubleshoot” - “Clean / Purge data”。这是一个比较彻底的方法会删除所有镜像、容器和卷慎用但通常有效。方案三检查 WSL 2 状态确保 WSL 2 运行正常。在 PowerShell 中运行wsl -l -v查看你的发行版是否处于 “Running” 状态且 VERSION 为 2。3.3 配置国内镜像加速器由于后续act需要拉取多种系统镜像如node:16-buster-slim从 Docker Hub 拉取速度可能很慢。配置镜像加速器至关重要。在系统托盘右键 Docker 图标选择 “Settings”。进入 “Docker Engine” 选项卡。你会看到一个 JSON 格式的配置框。在registry-mirrors数组中添加国内镜像源。配置完成后大致如下{ registry-mirrors: [ https://registry.docker-cn.com, https://hub-mirror.c.163.com, https://mirror.baidubce.com, https://docker.mirrors.ustc.edu.cn ], builder: { gc: { defaultKeepStorage: 20GB, enabled: true } }, experimental: false, features: { buildkit: true } }点击 “Apply Restart” 使配置生效。实操心得不要把所有镜像地址都加上有时某个镜像源不稳定会导致所有拉取失败。我个人的经验是保留https://docker.mirrors.ustc.edu.cn中科大源和https://hub-mirror.c.163.com网易源这两个稳定性比较好。可以在配置后在终端运行docker info查看Registry Mirrors是否生效。3.4 安装act工具act是一个单独的二进制文件安装非常简单。访问发布页打开act的 GitHub 仓库发布页面https://github.com/nektos/act/releases。下载对应版本找到最新的 release根据你的系统下载。对于 Windows通常下载act_Windows_x86_64.zip。解压并放置将压缩包中的act.exe文件解压出来。添加到系统路径可以将act.exe放在一个固定的目录例如C:\Tools\act\。然后将此目录C:\Tools\act\添加到系统的PATH环境变量中。具体步骤系统属性-高级-环境变量- 在“用户变量”或“系统变量”中找到并编辑Path- 添加新的路径条目。验证安装打开一个新的 PowerShell 或 CMD 窗口输入act --version。如果显示出版本号如act version 0.2.55说明安装成功。进阶安装适用于所有平台推荐给开发者 如果你熟悉包管理器可以使用更便捷的方式macOS (Homebrew):brew install actLinux (部分发行版): 可以使用curl安装脚本具体参考官方文档。4.act工具核心使用详解安装好环境后我们就可以开始使用act了。它的命令设计非常直观。4.1 基础命令结构act [event] [options]event指定要触发的工作流事件如push,pull_request,workflow_dispatch。如果不指定默认是push。options各种选项用于控制运行行为。4.2 常用命令与场景示例假设我们有一个项目其.github/workflows/ci.yml内容如下name: CI Pipeline on: [push, workflow_dispatch] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Run a one-line script run: echo Hello, world! test: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Run tests run: echo Running tests...1. 列出所有工作流和任务在项目根目录下执行act -l输出会列出所有可被触发的工作流及其包含的 Job。这对于了解项目中有哪些自动化流程非常有用。Stage Job ID Job name Workflow name Workflow file Events 0 build build CI Pipeline ci.yml push,workflow_dispatch 0 test test CI Pipeline ci.yml push,workflow_dispatch2. 运行默认事件pushact这会模拟一次push事件并运行所有被push事件触发的工作流中的所有 Job。act会依次为每个 Job 创建 Docker 容器并执行。3. 运行特定事件如果你想测试workflow_dispatch手动触发事件act workflow_dispatch4. 运行特定 Job如果工作流中有多个 Job但你只想运行其中一个例如testact -j test5. 指定工作流文件运行当你的项目中有多个.yml文件或者 Job 名称有重复时需要精确指定act -j build -W .github/workflows/ci.yml6. 干跑模式Dry-run此模式不会真正执行步骤中的命令只会解析工作流文件并列出将要执行的动作。非常适合用来检查工作流语法和流程。act -n7. 详细日志模式当运行出错需要排查时详细日志是必不可少的。act -v或者更详细act -v -v # 两个 -v4.3 实战案例运行一个真实的开源项目工作流让我们以RT-Thread这个开源物联网操作系统的 CI 流程为例进行一次完整的本地测试。克隆代码并进入目录git clone https://github.com/RT-Thread/rt-thread.git cd rt-thread查看工作流首先我们看看这个项目有哪些 Actions。act -l你可能会看到很多行输出其中有些 Job ID 可能是重复的因为它们定义在不同的工作流文件中。运行特定的测试 Job假设我们想运行一个名为test的 Job但它出现在多个文件中。我们需要指定具体的工作流文件。通过观察act -l的输出找到testJob 对应的Workflow file。例如它可能在.github/workflows/action_tools.yml中。act -j test -W .github/workflows/action_tools.yml观察执行过程act会开始执行准备阶段它会检查并拉取runs-on指定的镜像如node:16-buster-slim。首次使用会下载镜像需要一些时间。执行 Action它会依次执行steps。例如actions/checkoutv4会将你的本地代码“拷贝”到容器环境中。执行命令运行你在run中定义的命令如makepython test.py等。所有的日志输出都会显示在你的终端里就像在 GitHub 上查看 Action 运行日志一样。处理镜像拉取失败如果遇到镜像拉取非常慢或失败除了前面配置的 Docker 镜像加速器act本身也允许指定替代镜像。你可以创建一个~/.actrc文件在用户家目录下进行配置# 为 ubuntu-latest 标签指定一个更快的镜像 -P ubuntu-latestghcr.io/catthehacker/ubuntu:act-latest # 为 node:16 指定镜像 -P node:16node:16-buster-slimcatthehacker/ubuntu:act-latest是一个社区维护的、为act优化过的 Ubuntu 镜像通常比官方镜像小拉取更快。5. 高级配置与调试技巧5.1 绑定本地目录与缓存优化默认情况下act会将你的项目目录挂载到容器中。但有时 Action 步骤会产生一些构建产物如dist/,node_modules/你希望这些能持久化在本地或者利用本地缓存加速。绑定目录使用-b或--bind参数可以额外绑定目录。但通常默认的项目绑定已经足够。缓存处理act支持 GitHub Actions 的cache动作。缓存会存储在 Docker 卷中。你可以通过docker volume ls和docker volume rm来管理这些缓存卷。如果测试时缓存导致问题可以尝试用--rm参数运行act来清理容器但注意这不会删除卷。5.2 处理 Secrets 和环境变量在真实的 GitHub Actions 中我们经常使用secrets和env。在本地act提供了多种方式来模拟使用.env文件在项目根目录创建.env文件。MY_SECRETsuper_secret_value GITHUB_TOKENfake_token_for_local_test运行act时这些变量会被注入到环境中。务必确保.env文件在.gitignore中不要提交使用-s参数通过命令行传递 secret。act -s MY_SECRETsuper_secret_value使用--secret-file参数指定一个包含 secrets 的文件。act --secret-file .secrets重要安全提示本地测试时切勿使用真实的、有高权限的GITHUB_TOKEN或生产环境密钥。始终使用模拟的、权限受限的测试用密钥。5.3 调试复杂工作流当工作流运行失败时按以下步骤排查启用详细日志act -v -v是首选。查看错误发生前最后几步的详细输出。进入容器调试有时需要查看容器内部状态。act本身不提供直接进入容器的命令但你可以通过修改工作流文件临时添加一个“睡眠”步骤来获得时间然后用docker exec进入。- name: Debug shell run: | echo Container is running, you can now attach to it. sleep 300s # 睡眠5分钟在另一个终端运行docker ps找到对应的容器然后docker exec -it container_id /bin/bash进入。分步执行如果工作流很长可以先用act -n查看流程然后通过-j单独运行出错的 Job甚至通过修改-W指向一个你简化过的测试工作流文件。6. 常见问题与解决方案实录以下是我在长期使用act过程中积累的一些典型问题及其解决方法希望能帮你快速排雷。问题现象可能原因解决方案错误Error: image for node:16-buster-slim not found1. Docker 镜像加速器未生效或配置错误。2. 网络问题导致无法拉取镜像。1. 运行docker info确认镜像加速器。尝试拉取基础镜像docker pull node:16-buster-slim测试。2. 在~/.actrc中为node:16指定一个已知存在的镜像如-P node:16node:16-alpine更小。act -l不显示任何工作流未在正确的项目根目录下执行。.github/workflows目录不存在或为空。确保当前目录是 Git 仓库根目录并且存在.github/workflows/*.yml文件。Action 步骤失败提示Requiredifcondition was false本地运行的事件 (push) 不满足工作流中某个步骤的if条件。使用-W指定具体工作流文件并用act event指定正确的事件来触发。例如有些步骤只在pull_request时运行。运行速度慢每次都要重新拉取镜像/安装依赖Docker 层缓存未有效利用或者 Action 本身没有配置缓存。1. 确保 Docker 有足够磁盘空间。2. 在工作流中合理使用actions/cache。3. 对于apt-get等操作可以考虑在自定义的 Docker 镜像中预先安装好常用依赖。无法模拟macos-latest或windows-latest环境act本质是 Linux Docker 容器无法模拟非 Linux 系统。对于runs-on: macos-latest在~/.actrc中配置替代镜像-P macos-latestghcr.io/catthehacker/ubuntu:act-latest。注意这只能保证运行但无法测试 macOS 特有的行为如某些预装软件。actions/checkout失败提示找不到.git你的本地目录可能不是一个完整的 Git 仓库比如是源码压缩包解压的。确保使用git clone下来的仓库或者已执行git init。act需要 Git 元数据来模拟 GitHub 的上下文。容器内无法访问本地服务如 localhost:3000Docker 容器网络与主机隔离。在act命令中使用--container-options --networkhostLinux可以让容器共享主机网络。在 macOS/Windows 的 Docker Desktop 下可以使用主机名host.docker.internal来访问主机服务。7. 将本地测试集成到开发工作流掌握了act的基本和高级用法后如何让它真正提升你的效率关键在于将其融入日常开发习惯。预提交检查在本地编写或修改.github/workflows/*.yml文件后在git commit之前先运行act -n或act进行快速验证。这可以避免将一个有语法错误或逻辑错误的工作流推送到远程从而阻塞 CI/CD 管道。复杂 Action 的迭代开发如果你在编写自定义的 GitHub ActionJavaScript 或 Docker 类型本地测试更是不可或缺。你可以在 Action 项目中使用act来运行其自带的测试工作流或者创建一个简单的测试仓库来调用你本地开发的 Action实现快速迭代。与 IDE/编辑器集成你可以在 VS Code 等编辑器中配置任务Tasks或使用终端插件将act命令绑定到快捷键上实现一键测试。团队共享配置建议在项目文档或README.md中加入一小节说明如何使用act进行本地 Actions 测试。可以将推荐的~/.actrc配置如镜像替代也分享出来统一团队内的测试环境。最后我想分享一个最深切的体会本地运行 GitHub Actions 的最大价值在于它将“猜测”变成了“验证”。以前需要推代码、等结果、看日志、再修改的漫长循环现在在几秒到几分钟内就能完成。这种即时反馈对开发体验的提升是巨大的。尤其是当你调试一个涉及多个 Job、有复杂依赖关系的工作流时本地测试节省的时间是以小时计的。当然act不是银弹它无法完全替代云端 Runner 进行最终集成测试特别是对于需要特定硬件环境或严格安全隔离的场景。但它无疑是一把极其锋利的“开发阶段”的瑞士军刀。花一点时间搭建好这个环境并将其作为你 CI/CD 开发流程的标准一环长期来看这笔时间投资回报率会非常高。