首页
/ act 本地运行 GitHub Actions 全解:工作原理、实战命令与源码构建

act 本地运行 GitHub Actions 全解:工作原理、实战命令与源码构建

2026-09-03 16:05:11作者:邵娇湘

本文基于 act 仓库根目录的 README.md 展开,讲清楚三件事:为什么要用 act 在本地执行 .github/workflows/ 中的工作流、act 是如何借助 Docker API 解析并执行这些工作流的,以及如何从源码构建、测试并安装 act。读完后,你将能够独立完成工作流的本地运行、常用命令行参数的配置,以及基于 Makefile 的完整开发工作流。

为什么要在本地跑 GitHub Actions

act 的核心定位可以浓缩成一句话:"Think globally, act locally"——用本地环境模拟 GitHub Actions 的完整行为。README 给出了两个动机,二者覆盖了 CI 调试与日常开发两类场景:

  • 快速反馈(Fast Feedback):修改 .github/workflows/ 下的文件或内嵌的 GitHub Actions 时,不必每次改动都 commit/push 到远端等待 GitHub Runner 排队执行。act 在本地直接运行这些 action,并且环境变量与文件系统都配置为与 GitHub 提供的运行环境一致,因此本地通过的结果与远端行为高度对齐。
  • 本地任务运行器(Local Task Runner):作者对 Makefile 的态度是"爱 make,但讨厌重复"。借助 act,你可以把 .github/workflows/ 中定义的 GitHub Actions 当作本地 Makefile 的替代品——用同一份 YAML 声明构建、测试、发布等任务,本地和云端共用一份定义。

README 同时推荐了 VS Code 扩展(GitHub Local Actions),可以直接在编辑器内调用 act 的能力运行和测试本地工作流。

act 是如何工作的:从工作流到容器

README 的 "How Does It Work?" 一节描述了 act 的完整链路,结合源码可以逐段印证:

  1. 读取工作流:运行 act 时,它会读取 .github/workflows/ 下的文件并确定需要执行的 action 集合。对应实现位于 pkg/model/planner.goNewWorkflowPlanner 支持传入单个工作流文件,或一个目录(可递归扫描子目录),把每个 .yml/.yaml 解析为工作流模型;
  2. 准备镜像:使用 Docker API 按工作流文件中的定义拉取或构建所需镜像(例如 docker://node:16-buster-slim 这类 Docker action 需要拉取镜像,本地 Dockerfile action 需要构建);
  3. 推导执行路径:根据 needs 等依赖关系计算执行计划。从源码结构看,pkg/model/planner.go 中的 Plan 由若干 Stage(串行阶段)组成,每个 Stage 内含一批可并行执行的 Run(即工作流中的 job);
  4. 逐 action 运行容器:拿到执行路径后,再次通过 Docker API 为每个 action 启动容器,并注入与 GitHub 一致的环境变量和文件系统布局。

pkg/runner/runner.go 中可以看到计划如何变成执行链:NewPlanExecutor 把每个 Stage 包装为一个串行节点,Stage 内部的 job 用 NewParallelExecutor 并行执行,整体再套上 NewPipelineExecutor——即"阶段串行、阶段内并行",与 GitHub Actions 的调度语义一致。此外,job 的 strategy.matrix 会在这里展开为多个带编号的并行实例(maxParallel 受工作流中 max-parallel 控制,默认 4),needs 依赖失败则通过 handleFailureJob '%s' failed 报错。

一个最小工作流示例

仓库测试目录中的 pkg/runner/testdata/basic/push.yml 是一个可以直接读懂的最小示例,涵盖了 act 支持的主要 step 类型:

name: basic
on: push

env:
  TEST: value

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - run: '[[ "$(pwd)" == "${GITHUB_WORKSPACE}" ]]'   # 工作目录与 GitHub 一致
      - run: echo ${{ env.TEST }} | grep value           # 表达式与上下文
      - uses: docker://node:16-buster-slim              # Docker action(对应 README 第 2 步"pull")
        with:
          somekey: ${{ env.TEST }}
          args: echo ${INPUT_SOMEKEY} | grep somevalue
      - run: ls                                          # 普通 shell step
  build:
    runs-on: ubuntu-latest
    needs: [check]                                      # 依赖关系,决定执行路径
    steps:
      - uses: actions/checkout@v2                        # 远程 action
      - uses: ./actions/action1                         # 本地 action
        with:
          args: echo 'build'

在任意包含该文件的仓库中执行 act(不带参数时默认按 on: push 事件过滤,若工作流只处理单一事件则自动使用它),check 会先运行,buildcheck 成功后进入下一 Stage 执行。act -l(list)可先查看工作流与 job 清单,act -g(graph)可将执行路径绘制为图形。

常用命令行参数速览

act 的 CLI 基于 Cobra 构建,全部参数在 cmd/root.go 中注册,act --help 可直接查看。以下是从源码中摘录的高频参数及默认值:

参数 默认值 说明
act [event] push 位置参数指定要触发的事件名;工作流只含一个事件时可省略
-l / --list - 列出所有工作流及其 job
-g / --graph - 以图形方式绘制工作流依赖
-j / --job - 只运行指定 job ID
-P / --platform - 为各平台指定镜像,如 -P ubuntu-latest=catthehacker/ubuntu:act-latest
-s / --secret - 传入 secret,支持 -s mysecret=foo 或只给名字从环境中取
--var / --env / --input - 向工作流注入 vars / 环境变量 / workflow_dispatch 输入
-r / --reuse false 工作流成功后保留容器,便于在多次运行间保持状态调试
-b / --bind false 将工作目录 bind 进容器而非拷贝,加快文件变更同步
-p / --pull true 镜像已存在时也强制拉取
-e / --eventpath - 指定事件 JSON 文件(模拟 github.event 数据)
-a / --actor nektos/act 触发事件的"用户"名,影响 github.actor 上下文
-C / --directory . 工作目录
-W / --workflows ./.github/workflows/ 工作流文件路径,可指向单个或多个文件
-n / --dryrun false 不创建容器,仅校验工作流正确性
-v / --verbose false 输出调试级日志
--json false 日志以 JSON 格式输出
--matrix - 筛选矩阵配置,如 --matrix java:13
--rm false 工作流失败后自动清理容器与卷
--container-architecture 主机架构 指定容器架构(如 linux/amd64),需要 Docker Engine API 1.41+
--network host 容器使用的 Docker 网络名
--concurrent-jobs CPU 核数 最大并发 job 数(见 pkg/runner/runner.goGetConcurrentJobs 的实现)

几个值得注意的实现细节:

  • .actrc 配置文件act 会依次从 XDG 配置目录(act/actrc)、$HOME/.actrc、当前目录 .actrc 三个位置读取参数文件,命令行参数优先级更高(见 cmd/root.goconfigLocationsargs)。每行一条参数,支持环境变量展开;
  • 首次运行的镜像选择:若未指定 --platform 且不存在任何 .actrcact 会交互式询问使用 Large / Medium / Micro 三档预置镜像(分别对应 catthehacker/ubuntu:full-*catthehacker/ubuntu:act-*node:16-*-slim),并把结果写入全局配置,避免重复打扰。可镜像列表的详细说明见仓库根目录的 IMAGES.md
  • Apple Silicon 提示:在 M 系列芯片的 Mac 上未指定 --container-architecture 时,cmd/root.go 会打印警告,建议尝试 --container-architecture linux/amd64

本地 secret 与变量文件

-s 直接传值外,act 还支持批量文件:--secret-file(默认 .secrets)、--var-file(默认 .vars)、--env-file(默认 .env)、--input-file(默认 .input)。文件格式为 KEY=VALUE,也支持 .yml/.yaml(见 cmd/root.goreadEnvsEx)。注意 secret 文件按"大写不敏感"方式读取,且当未显式提供 GITHUB_TOKEN 时,act 会尝试从 gh 工具链获取 token 注入。

从源码构建与安装

README 的 "Manually building from source" 一节给出了最简流程,结合仓库实际文件可以补全如下(适用前提:Linux/macOS/类 Unix shell 环境):

  1. 安装 Go 工具链:README 声明需要 Go 1.20+;但当前主线 go.mod 声明 go 1.25.0,因此构建当前 master 分支实际需要一个能自动下载/切换到 1.25+ 工具链的 Go 环境;
  2. 克隆仓库git clone 仓库地址(官方源地址为 nektos/act 的 Git 仓库);
  3. 运行单元测试make test——它先执行 go test ./...,再运行一次 go run main.go 做冒烟检查(见 Makefiletest 目标);
  4. 构建并安装make install——其内部先 buildgo build -ldflags "-X main.version=..." -o dist/local/act main.go,版本号由 git describe --tags 推导),再把二进制复制到 $(PREFIX)/bin/actPREFIX 默认 /usr/local)并执行 act --version 验证。

入口逻辑非常薄:main.go 将仓库根目录的 VERSION 文件通过 go:embed 编入二进制,创建可优雅取消的 context 后调用 cmdExecute。当前版本号记录在根目录的 VERSION 文件中(本仓库快照为 0.2.88)。

除手动构建外,仓库还提供 install.sh 安装脚本(由 godownloader 生成),支持 -b 指定安装目录(默认 ./bin)、-f 强制安装、传入 tag 安装指定版本,安装前会做 SHA256 校验。

开发者的完整检查清单

Makefile 中还定义了面向贡献者的更多目标,配合 CONTRIBUTING.md 中的贡献流程使用:

目标 作用
make pr PR 前完整检查:tidyformat-alllinttest
make lint-go 运行 golangci-lint(规则配置见 .golangci.yml
make lint-md 用 markdownlint 检查 Markdown
make tidy go mod tidy
make format go fmt ./...
make snapshot 用 goreleaser 构建快照版二进制
make security-check 用 govulncheck 扫描依赖漏洞

代码仓库自身的工程约束也值得参考:.golangci.yml 强制使用标准库 errorslogrus(别名 log)、testify,循环复杂度上限 20。

测试即文档:testdata 目录

act 的功能面很大,pkg/runner/testdata/ 下数百个样例工作流是最好的"活文档":matrix/composite-fail-with-output/uses-workflow/services/job-container/ 等目录分别对应矩阵展开、composite action、可复用工作流、服务容器、job 容器等能力,每个目录下的 push.yml(或 main.yaml)都是可直接运行的最小复现。调试本地工作流问题时,先在该目录找同构样例是高效的排障路径。

获取帮助

按 README 的建议,遇到问题可以先到项目的 discussions 区提问;更深入的使用文档(安装、.actrc 配置、平台镜像选择等)维护在 act 的官方用户指南站点 nektosact.com 上(README 中的外链)。在仓库内查阅材料时,建议的阅读顺序是:README.mdIMAGES.mdCONTRIBUTING.md → 对应功能的 pkg/ 源码与 testdata/ 样例。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
docsdocs
暂无描述
Markdown
899
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
924
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
599
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
525
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
394