act 常用 CLI 命令与工具详解
act v0.2.89 全参数详解:--help 全量整理、-l/--graph/-j/-n/-e/-a/-s/--var/--env/-P/--json/-q 等逐条实测回显,附 `#` 截断、schema 校验、git 依赖等注意事项与排障结论。
act 常用 CLI 命令与工具详解
> 目标:系统整理 act(nektos/act,本地运行 GitHub Actions 的命令行工具)v0.2.89 的命令形态与全部参数,按「帮助信息 → 工作流查看 → 运行控制 → 变量注入 → 平台镜像 → 输出控制」逐条给出实测命令与真实回显,并沉淀使用注意事项与排障结论。全部命令在 Ubuntu 22.04(x86_64)+ Docker Engine 环境实测,实测日期 2026-10-18;act 的定位与安装分别见 《act 介绍与选型指南》 与 《Ubuntu 22.04 安装 act 指南》。
一、环境信息
| 项目 | 内容 |
|---|---|
| 操作系统 | Ubuntu 22.04(x86_64) |
| act 版本 | v0.2.89(act --version 实测:act version 0.2.89) |
| 依赖组件 | Docker Engine(运行中;act 经 Docker API 执行) |
| 演示仓库 | /opt/act-demo(git 仓库,main 分支,.github/workflows/ 下含 ci.yml、pr.yml、secret.yml、env.yml 四个工作流,内容见三章) |
| 演示事件文件 | /tmp/pr-event.json(pull_request 事件载荷,内容见 4.6 节) |
| 帮助信息来源 | act --help(v0.2.89 实测全量 75 行)与官方 Usage guide(https://nektosact.com/usage/index.html ,查询日期 2026-10-18) |
二、工具概览
act 是单命令 CLI:没有 act run、act list 这类子命令,一切能力都通过「命令 + 事件名 + 参数」表达,命令形态只有三种:
- 信息查看:
act --help、act -l、act --graph、act --list-options、act --bug-report等,只读不执行。 - 事件执行:
act [事件名]——事件名直接写在命令尾部(act push、act pull_request);不带事件名时默认按push处理(--help原文:If no event name passed, will default to "on: push"),再叠加范围与注入参数。 - 配置输出:
--json、-q、-v等控制日志形态。
常用参数按用途分组如下(每组在第四章逐条实测):
| 分组 | 代表参数 |
|---|---|
| 查看类 | -l、-g --graph、--list-options、--man-page、--bug-report、--version |
| 范围选择 | -W --workflows、-j --job、-n --dryrun、--detect-event、--matrix |
| 事件与输入 | 事件名、-e --eventpath、--input/--input-file |
| 变量注入 | -s --secret、--secret-file、--var、--var-file、--env、--env-file、-a --actor |
| 平台镜像 | -P --platform、-p --pull、--container-architecture、--network |
| 输出与生命周期 | --json、-q --quiet、-v --verbose、-w --watch、-r --reuse、--rm |
三、前置条件
3.1 环境就绪检查
Docker Engine 处于运行状态(act 执行类命令的硬前置,不可用时实测报错形式:failed to connect to the docker API at ... dial unix ...: connect: no such file or directory);act 已安装并在 PATH:
act --version
实测回显:
act version 0.2.89
3.2 演示仓库
本文所有示例基于 /opt/act-demo 仓库(git 仓库,main 分支)。注意:act 运行时需要读取 git ref/revision,目录必须位于 git 仓库内(非 git 目录运行时的实测报错见六章 Q3,纯列表命令 -l/--graph 不受影响)。
.github/workflows/ 下四个工作流文件内容如下(原样):
# ci.yml
name: CI
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Hello
run: echo "hello act on $(uname -m)"
- name: Show env
run: echo "CI=$CI, actor=$GITHUB_ACTOR"
test:
runs-on: ubuntu-latest
needs: build
steps:
- name: Test
run: echo "run tests"
# pr.yml
name: PR Check
on: pull_request
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Lint
run: echo "linting PR number ${{ github.event.pull_request.number }}"
# secret.yml
name: Secrets Demo
on: push
jobs:
use-secret:
runs-on: ubuntu-latest
steps:
- name: Read secret
run: echo "token length=${#MY_TOKEN}, env APP_MODE=$APP_MODE"
env:
MY_TOKEN: ${{ secrets.MY_TOKEN }}
APP_MODE: ${{ vars.APP_MODE }}
# env.yml
name: EnvFile Demo
on: push
jobs:
show:
runs-on: ubuntu-latest
steps:
- name: Show env
run: echo "MY_ENV=$MY_ENV, token length=${#MY_TOKEN}, APP_MODE=$APP_MODE"
env:
MY_TOKEN: ${{ secrets.MY_TOKEN }}
APP_MODE: ${{ vars.APP_MODE }}
actrc 已预写平台映射(安装与配置方法见《Ubuntu 22.04 安装 act 指南》第七章):
-P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest
-P ubuntu-22.04=ghcr.io/catthehacker/ubuntu:act-22.04
-P ubuntu-20.04=ghcr.io/catthehacker/ubuntu:act-20.04
四、各命令详解
4.1 帮助与信息类命令
act --help(全量)。以下为 v0.2.89 实测全量输出(75 行,原样照抄,是本文参数表的唯一权威依据):
Run GitHub actions locally by specifying the event name (e.g. `push`) or an action name directly.
Usage:
act [event name to run] [flags]
If no event name passed, will default to "on: push"
If actions handles only one event it will be used as default instead of "on: push"
Flags:
--action-cache-path string Defines the path where the actions get cached and host workspaces created. (default "/root/.cache/act")
--action-offline-mode If action contents exists, it will not be fetch and pull again. If turn on this, will turn off force pull
-a, --actor string user that triggered the event (default "nektos/act")
--artifact-server-addr string Defines the address to which the artifact server binds. (default "172.17.0.30")
--artifact-server-path string Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified the artifact server will not start.
--artifact-server-port string Defines the port where the artifact server listens. (default "34567")
-b, --bind bind working directory to container, rather than copy
--bug-report Display system information for bug report
--cache-server-addr string Defines the address to which the cache server binds. (default "172.17.0.30")
--cache-server-external-url string Defines the external URL for if the cache server is behind a proxy. e.g.: https://act-cache-server.example.com. Be careful that there is no trailing slash.
--cache-server-path string Defines the path where the cache server stores caches. (default "/root/.cache/actcache")
--cache-server-port uint16 Defines the port where the artifact server listens. 0 means a randomly available port.
--concurrent-jobs int Maximum number of concurrent jobs to run. Default is the number of CPUs available.
--container-architecture string Architecture which should be used to run containers, e.g.: linux/amd64. If not specified, will use host default architecture. Requires Docker server API Version 1.41+. Ignored on earlier Docker server platforms.
--container-cap-add stringArray kernel capabilities to add to the workflow containers (e.g. --container-cap-add SYS_PTRACE)
--container-cap-drop stringArray kernel capabilities to remove from the workflow containers (e.g. --container-cap-drop SYS_PTRACE)
--container-daemon-socket string URI to Docker Engine socket (e.g.: unix://~/.docker/run/docker.sock or - to disable bind mounting the socket)
--container-options string Custom docker container options for the job container without an options property in the job definition
--defaultbranch string the name of the main branch
--detect-event Use first event type from workflow as event that triggered the workflow
-C, --directory string working directory (default ".")
-n, --dryrun disable container creation, validates only workflow correctness
--env stringArray env to make available to actions with optional value (e.g. --env myenv=foo or --env myenv)
--env-file string environment file to read and use as env in the containers (default ".env")
-e, --eventpath string path to event JSON file
--github-instance string GitHub instance to use. Only use this when using GitHub Enterprise Server. (default "github.com")
-g, --graph draw workflows
-h, --help help for act
--input stringArray action input to make available to actions (e.g. --input myinput=foo)
--input-file string input file to read and use as action input (default ".input")
--insecure-secrets NOT RECOMMENDED! Doesn't hide secrets while printing logs.
-j, --job string run a specific job ID
--json Output logs in json format
-l, --list list workflows
--list-options Print a json structure of compatible options
--local-repository stringArray Replaces the specified repository and ref with a local folder (e.g. https://github.com/test/test@v0=/home/act/test or test/test@v0=/home/act/test, the latter matches any hosts or protocols)
--log-prefix-job-id Output the job id within non-json logs instead of the entire name
--man-page Print a generated manual page to stdout
--matrix stringArray specify which matrix configuration to include (e.g. --matrix java:13
--network string Sets a docker network name. Defaults to host. (default "host")
--no-cache-server Disable cache server
--no-recurse Flag to disable running workflows from subdirectories of specified path in '--workflows'/'-W' flag
--no-skip-checkout Use actions/checkout instead of copying local files into container
-P, --platform stringArray custom image to use per platform (e.g. -P ubuntu-18.04=nektos/act-environments-ubuntu:18.04)
--privileged use privileged mode
-p, --pull pull docker image(s) even if already present (default true)
-q, --quiet disable logging of output from steps
--rebuild rebuild local action docker image(s) even if already present (default true)
--remote-name string git remote name that will be used to retrieve url of git repo (default "origin")
--replace-ghe-action-token-with-github-com string If you are using replace-ghe-action-with-github-com and you want to use private actions on GitHub, you have to set personal access token
--replace-ghe-action-with-github-com stringArray If you are using GitHub Enterprise Server and allow specified actions from GitHub (github.com), you can set actions on this. (e.g. --replace-ghe-action-with-github-com =github/super-linter)
-r, --reuse don't remove container(s) on successfully completed workflow(s) to maintain state between runs
--rm automatically remove container(s)/volume(s) after a workflow(s) failure
-s, --secret stringArray secret to make available to actions with optional value (e.g. -s mysecret=foo or -s mysecret)
--secret-file string file with list of secrets to read from (e.g. --secret-file .secrets) (default ".secrets")
--strict use strict workflow schema
--use-gitignore Controls whether paths specified in .gitignore should be copied into container (default true)
--use-new-action-cache Enable using the new Action Cache for storing Actions locally
--userns string user namespace to use
--validate validate workflows
--var stringArray variable to make available to actions with optional value (e.g. --var myvar=foo or --var myvar)
--var-file string file with list of vars to read from (e.g. --var-file .vars) (default ".vars")
-v, --verbose verbose output
--version version for act
-w, --watch watch the contents of the local repo and run when files change
-W, --workflows string path to workflow file(s) (default "./.github/workflows/")
act --bug-report(输出节选,实测首段)。自诊断信息包含版本、构建信息、actrc 内容与 Docker Engine 探测,报障时随 issue 提交:
act version: 0.2.89
GOOS: linux
GOARCH: amd64
NumCPU: 12
Docker host: DOCKER_HOST environment variable is not set
Sockets found:
/var/run/docker.sock
Config files:
/root/.config/act/actrc:
-P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest
-P ubuntu-22.04=ghcr.io/catthehacker/ubuntu:act-22.04
-P ubuntu-20.04=ghcr.io/catthehacker/ubuntu:act-20.04
Build info:
Go version: go1.25.0
Module path: github.com/nektos/act
Main version: v0.2.89
Main path: github.com/nektos/act
Main checksum:
Build settings:
-buildmode: exe
-compiler: gc
-ldflags: -s -w -X main.version=0.2.89 -X main.commit=4f411281417e88660bea1c1a1749aa71ae0bd60f -X main.date=2026-06-01T03:17:53Z -X main.builtBy=goreleaser
CGO_ENABLED: 0
act --man-page(输出节选,实测首段)。生成 roff 格式手册页,可重定向给 man 使用:
.nh
.TH "act" "1" "Oct 2026" "act 0.2.89" ""
.SH NAME
act - Run GitHub actions locally by specifying the event name (e.g. \fBpush\fR) or an action name directly.
.SH SYNOPSIS
**act [event name to run] [flags]
act --list-options。以 JSON 输出全部兼容参数及真实默认值,适合脚本化读取。以下为实测节选(原始输出为单行 JSON,此处按条目整理,全部为实测值):
| 参数 | 默认值 | 类型 |
|---|---|---|
| action-cache-path | /root/.cache/act | string |
| actor | nektos/act | string |
| artifact-server-addr | 172.17.0.30(取本机网卡地址,随环境变化) | string |
| artifact-server-port | 34567 | string |
| cache-server-path | /root/.cache/actcache | string |
| cache-server-port | 0(随机端口) | uint16 |
| concurrent-jobs | 0(默认取 CPU 数) | int |
| directory | . | string |
| dryrun | false | bool |
| env-file | .env | string |
| github-instance | github.com | string |
| input-file | .input | string |
| network | host | string |
| platform | [] | stringArray |
| pull | true | bool |
| rebuild | true | bool |
| remote-name | origin | string |
| secret-file | .secrets | string |
| use-gitignore | true | bool |
| var-file | .vars | string |
| workflows | ./.github/workflows/ | string |
验证方式:任选一项与 act --help 中对应参数的 (default ...) 标注比对,两者一致。
4.2 工作流查看类:-l 与 --graph
-l/--list 列出当前仓库全部工作流的 Stage 拓扑,是写 workflow 时最常用的检查手段:
cd /opt/act-demo && act -l
实测回显:
time="2026-10-18T02:06:51Z" level=info msg="Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock'"
Stage Job ID Job name Workflow name Workflow file Events
0 build build CI ci.yml push
0 lint lint PR Check pr.yml pull_request
0 use-secret use-secret Secrets Demo secret.yml push
1 test test CI ci.yml push
列含义:Stage(执行波次,needs 决定)、Job ID(-j 选择的取值)、Job name、Workflow name(name: 字段)、Workflow file、Events(触发事件)。首行 Using docker host ... 是 act 每次运行的标准提示行。
可按事件过滤列表(官方用法 act -l <事件名>),实测只列 pull_request 触发的工作流:
Stage Job ID Job name Workflow name Workflow file Events
0 lint lint PR Check pr.yml pull_request
-g/--graph 用字符图画出同一拓扑,比表格更直观:
╭───────╮ ╭──────╮ ╭────────────╮
│ build │ │ lint │ │ use-secret │
╰───────╯ ╰──────╯ ╰────────────╯
⬇
╭──────╮
│ test │
╰──────╯
💡 说明:
-l/--graph是纯解析操作,不依赖 Docker 守护进程可用——实测把 Docker 访问指向不存在的套接字(DOCKER_HOST=unix:///run/nonexistent.sock act -l)仍能完整列出并返回 0;真正执行 Job 的命令则会失败。
4.3 运行控制类
act push(执行 push 事件全部工作流)。加 --pull=false 跳过远端镜像检查(本地已有平台镜像时显著加速)。完整实测回显(原样照抄,观察执行顺序:build 与 use-secret 同 Stage 并行,test 等 build 完成后执行):
act push --pull=false
time="2026-10-18T02:07:43Z" level=info msg="Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock'"
[CI/build ] ⭐ Run Set up job
[CI/build ] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
[Secrets Demo/use-secret] ⭐ Run Set up job
[Secrets Demo/use-secret] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
[Secrets Demo/use-secret] 🐳 docker pull image=ghcr.io/catthehacker/ubuntu:act-latest platform= username= forcePull=false
[CI/build ] 🐳 docker pull image=ghcr.io/catthehacker/ubuntu:act-latest platform= username= forcePull=false
[Secrets Demo/use-secret] 🐳 docker create image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[CI/build ] 🐳 docker create image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[CI/build ] 🐳 docker run image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[Secrets Demo/use-secret] 🐳 docker run image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[Secrets Demo/use-secret] 🐳 docker exec cmd=[node --no-warnings -e console.log(process.execPath)] user= workdir=
[CI/build ] 🐳 docker exec cmd=[node --no-warnings -e console.log(process.execPath)] user= workdir=
[Secrets Demo/use-secret] ✅ Success - Set up job
[CI/build ] ✅ Success - Set up job
[CI/build ] ⭐ Run Main Hello
[Secrets Demo/use-secret] ⭐ Run Main Read secret
[Secrets Demo/use-secret] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/0] user= workdir=
[CI/build ] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/0] user= workdir=
[Secrets Demo/use-secret] | token length=0, env APP_MODE=
[Secrets Demo/use-secret] ✅ Success - Main Read secret [46.848571ms]
[CI/build ] | hello act on x86_64
[CI/build ] ✅ Success - Main Hello [48.065311ms]
[Secrets Demo/use-secret] ⭐ Run Complete job
[Secrets Demo/use-secret] Cleaning up container for job use-secret
[CI/build ] ⭐ Run Main Show env
[Secrets Demo/use-secret] ✅ Success - Complete job
[Secrets Demo/use-secret] 🏁 Job succeeded
[CI/build ] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/1] user= workdir=
[CI/build ] | CI=true, actor=nektos/act
[CI/build ] ✅ Success - Main Show env [43.314267ms]
[CI/build ] ⭐ Run Complete job
[CI/build ] Cleaning up container for job build
[CI/build ] ✅ Success - Complete job
[CI/build ] 🏁 Job succeeded
[CI/test ] ⭐ Run Set up job
[CI/test ] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
[CI/test ] 🐳 docker pull image=ghcr.io/catthehacker/ubuntu:act-latest platform= username= forcePull=false
[CI/test ] 🐳 docker create image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[CI/test ] 🐳 docker run image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[CI/test ] 🐳 docker exec cmd=[node --no-warnings -e console.log(process.execPath)] user= workdir=
[CI/test ] ✅ Success - Set up job
[CI/test ] ⭐ Run Main Test
[CI/test ] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/0] user= workdir=
[CI/test ] | run tests
[CI/test ] ✅ Success - Main Test [43.260836ms]
[CI/test ] ⭐ Run Complete job
[CI/test ] Cleaning up container for job test
[CI/test ] ✅ Success - Complete job
[CI/test ] 🏁 Job succeeded
EXIT=0
输出结构规律:⭐ Run ... 开始一个步骤;🐳 行是 act 对 Docker API 的调用记录(pull/create/run/exec);| 前缀行是步骤脚本的真实输出;✅/❌ 是步骤结果(含耗时);🏁 Job succeeded/failed 是 Job 结果;两个 Job 都成功时进程退出码为 0(实测 EXIT=0)。不带事件名的 act 等价于 act push。
-j(只运行指定 Job,连带其依赖)。选择下游 Job 时,needs 依赖会先执行——实测选 test(依赖 build),build 也被运行:
act push -j test --pull=false
time="2026-10-18T02:09:23Z" level=info msg="Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock'"
[CI/build] ⭐ Run Set up job
[CI/build] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
[CI/build] ✅ Success - Set up job
[CI/build] ⭐ Run Main Hello
[CI/build] | hello act on x86_64
[CI/build] ✅ Success - Main Hello [45.107167ms]
[CI/build] ⭐ Run Main Show env
[CI/build] | CI=true, actor=nektos/act
[CI/build] ✅ Success - Main Show env [42.873399ms]
[CI/build] ⭐ Run Complete job
[CI/build] Cleaning up container for job build
[CI/build] ✅ Success - Complete job
[CI/build] 🏁 Job succeeded
[CI/test ] ⭐ Run Set up job
[CI/test ] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
[CI/test ] ✅ Success - Set up job
[CI/test ] ⭐ Run Main Test
[CI/test ] | run tests
[CI/test ] ✅ Success - Main Test [44.970894ms]
[CI/test ] ⭐ Run Complete job
[CI/test ] Cleaning up container for job test
[CI/test ] ✅ Success - Complete job
[CI/test ] 🏁 Job succeeded
EXIT=0
-n/--dryrun(只模拟不执行)。逐步骤打印将要发生的 Docker 调用但不动真格,用于执行前核对范围,日志带 *DRYRUN* 前缀:
act -n push
time="2026-10-18T02:07:42Z" level=info msg="Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock'"
*DRYRUN* [CI/build ] ⭐ Run Set up job
*DRYRUN* [Secrets Demo/use-secret] ⭐ Run Set up job
*DRYRUN* [CI/build ] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
*DRYRUN* [Secrets Demo/use-secret] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
*DRYRUN* [Secrets Demo/use-secret] 🐳 docker pull image=ghcr.io/catthehacker/ubuntu:act-latest platform= username= forcePull=true
*DRYRUN* [CI/build ] 🐳 docker pull image=ghcr.io/catthehacker/ubuntu:act-latest platform= username= forcePull=true
*DRYRUN* [Secrets Demo/use-secret] 🐳 docker create image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
*DRYRUN* [Secrets Demo/use-secret] 🐳 docker run image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
*DRYRUN* [CI/build ] 🐳 docker create image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
*DRYRUN* [CI/build ] 🐳 docker run image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
*DRYRUN* [Secrets Demo/use-secret] ✅ Success - Set up job
*DRYRUN* [CI/build ] ✅ Success - Set up job
*DRYRUN* [CI/build ] ⭐ Run Main Hello
*DRYRUN* [Secrets Demo/use-secret] ⭐ Run Main Read secret
*DRYRUN* [Secrets Demo/use-secret] ✅ Success - Main Read secret [17.488351ms]
*DRYRUN* [Secrets Demo/use-secret] ⭐ Run Complete job
*DRYRUN* [Secrets Demo/use-secret] Cleaning up container for job use-secret
*DRYRUN* [CI/build ] ✅ Success - Main Hello [17.509701ms]
*DRYRUN* [CI/build ] ⭐ Run Main Show env
*DRYRUN* [Secrets Demo/use-secret] ✅ Success - Complete job
*DRYRUN* [Secrets Demo/use-secret] 🏁 Job succeeded
*DRYRUN* [CI/build ] ✅ Success - Main Show env [16.972585ms]
*DRYRUN* [CI/build ] ⭐ Run Complete job
*DRYRUN* [CI/build ] Cleaning up container for job build
*DRYRUN* [CI/build ] ✅ Success - Complete job
*DRYRUN* [CI/build ] 🏁 Job succeeded
*DRYRUN* [CI/test ] ⭐ Run Set up job
*DRYRUN* [CI/test ] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
*DRYRUN* [CI/test ] 🐳 docker pull image=ghcr.io/catthehacker/ubuntu:act-latest platform= username= forcePull=true
*DRYRUN* [CI/test ] 🐳 docker create image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
*DRYRUN* [CI/test ] 🐳 docker run image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
*DRYRUN* [CI/test ] ✅ Success - Set up job
*DRYRUN* [CI/test ] ⭐ Run Main Test
*DRYRUN* [CI/test ] ✅ Success - Main Test [20.15379ms]
*DRYRUN* [CI/test ] ⭐ Run Complete job
*DRYRUN* [CI/test ] Cleaning up container for job test
*DRYRUN* [CI/test ] ✅ Success - Complete job
*DRYRUN* [CI/test ] 🏁 Job succeeded
EXIT=0
💡 说明:对比可见 dryrun 模式下
docker pull ... forcePull=true(默认-p --pull=true,每次检查远端),而带--pull=false的真实执行为forcePull=false——-p参数改变的就是这个 forcePull 标志。
--detect-event(自动选用首个事件)。不带事件名运行时让 act 自动采用工作流声明的首个事件类型,实测自动选中 PR Check 的 pull_request 并进入 dryrun:
act --detect-event -n
time="2026-10-18T02:09:27Z" level=info msg="Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock'"
*DRYRUN* [PR Check/lint] ⭐ Run Set up job
*DRYRUN* [PR Check/lint] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
*DRYRUN* [PR Check/lint] ✅ Success - Set up job
*DRYRUN* [PR Check/lint] ⭐ Run Main Lint
*DRYRUN* [PR Check/lint] ✅ Success - Main Lint [16.822125ms]
*DRYRUN* [PR Check/lint] ⭐ Run Complete job
*DRYRUN* [PR Check/lint] Cleaning up container for job lint
*DRYRUN* [PR Check/lint] ✅ Success - Complete job
*DRYRUN* [PR Check/lint] 🏁 Job succeeded
EXIT=0
-a(指定触发者身份)。改写 GITHUB_ACTOR,工作流内 $GITHUB_ACTOR 随之变化:
act push -a mydevuser -j build --pull=false
实测关键输出行(节选):
[CI/build] | CI=true, actor=mydevuser
4.4 事件与事件载荷:pull_request 与 -e
pull_request 等事件在本地没有真实载荷,需要用 -e/--eventpath 提供 JSON 事件文件。官方说明(https://nektosact.com/usage/index.html Events 节,查询日期 2026-10-18):部分模拟 pull_request 事件至少要提供 head_ref 与 base_ref,工作流内经 ${{ github.event.pull_request.<...> }} 访问。
事件文件 /tmp/pr-event.json(实测使用的内容):
{"number":42,"pull_request":{"number":42,"title":"demo PR","head":{"ref":"feature-x"},"base":{"ref":"main"}}}
执行 pull_request 事件工作流:
act pull_request -e /tmp/pr-event.json --pull=false
实测回显(工作流内 ${{ github.event.pull_request.number }} 成功取到 42):
time="2026-10-18T02:09:24Z" level=info msg="Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock'"
[PR Check/lint] ⭐ Run Set up job
[PR Check/lint] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
[PR Check/lint] ✅ Success - Set up job
[PR Check/lint] ⭐ Run Main Lint
[PR Check/lint] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/0] user= workdir=
[PR Check/lint] | linting PR number 42
[PR Check/lint] ✅ Success - Main Lint [43.039948ms]
[PR Check/lint] ⭐ Run Complete job
[PR Check/lint] Cleaning up container for job lint
[PR Check/lint] ✅ Success - Complete job
[PR Check/lint] 🏁 Job succeeded
EXIT=0
-W(指定工作流文件或目录)。只跑某个文件,便于聚焦调试(实测单跑 env.yml):
act push -W .github/workflows/env.yml --pull=false
实测关键输出行(节选):
[EnvFile Demo/show] | MY_ENV=production, token length=9, APP_MODE=
[EnvFile Demo/show] 🏁 Job succeeded
(该回显对应 4.5 节的 --env MY_ENV=production -s MY_TOKEN=secret123 注入,参数含义见下节。)
4.5 变量注入类:-s、--var、--env 及对应文件
三类注入通道与工作流取值的对应关系:-s → ${{ secrets.* }};--var → ${{ vars.* }};--env → 进程环境变量 $XXX。逐一实测:
命令行注入 secrets 与 vars(跑 secret.yml,注意 secrets 在日志中自动脱敏,token length=${#MY_TOKEN} 只泄露长度):
act push -j use-secret -s MY_TOKEN=q1w2e3r4-secret --var APP_MODE=debug --pull=false
实测关键输出行:
[Secrets Demo/use-secret] | token length=15, env APP_MODE=debug
[Secrets Demo/use-secret] 🏁 Job succeeded
命令行注入 env 与 secrets(跑 env.yml,$MY_ENV 取到命令行值):
act push -W .github/workflows/env.yml --env MY_ENV=production -s MY_TOKEN=secret123 --pull=false
实测关键输出行:
[EnvFile Demo/show] | MY_ENV=production, token length=9, APP_MODE=
文件默认加载。在仓库根目录准备三个文件(dotenv 格式,KEY=VALUE):
printf "MY_ENV=from-dotenv-file\n" > .env
printf "MY_TOKEN=filetoken99\n" > .secrets
printf "APP_MODE=debug-from-varfile\n" > .vars
不带任何注入参数重跑 env.yml——.env 与 .secrets 自动加载:
act push -W .github/workflows/env.yml --pull=false
实测关键输出行(MY_ENV 来自 .env,token 长度 11 来自 .secrets;APP_MODE 为空,说明 vars 不会从 .secrets 读取):
[EnvFile Demo/show] | MY_ENV=from-dotenv-file, token length=11, APP_MODE=
补上 .vars 后重跑同一命令——${{ vars.APP_MODE }} 才有值:
[EnvFile Demo/show] | MY_ENV=from-dotenv-file, token length=11, APP_MODE=debug-from-varfile
⚠️ 注意:官方对 secrets 有专门警告(https://nektosact.com/usage/index.html Secrets 节)——在终端明文输入敏感值可能被 shell 存入历史文件;推荐用
-s MY_TOKEN(不带=值)的形式,act 会改为安全输入提示且不落历史。工作流需要GITHUB_TOKEN时按官方建议传入:act -s GITHUB_TOKEN="$(gh auth token)"(安装了 GitHub CLI 时)。
4.6 平台镜像类:-P 与 -p
-P/--platform 把 runs-on: 标签映射到具体平台镜像。演示工作流(platform.yml):
name: Platform Demo
on: push
jobs:
show-os:
runs-on: ubuntu-22.04
steps:
- name: Show OS
run: grep PRETTY_NAME /etc/os-release
actrc 映射生效(actrc 中 -P ubuntu-22.04=ghcr.io/catthehacker/ubuntu:act-22.04,实测启动镜像与系统版本):
act push -W .github/workflows/platform.yml --pull=false
实测关键输出行:
[Platform Demo/show-os] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-22.04
[Platform Demo/show-os] | PRETTY_NAME="Ubuntu 22.04.5 LTS"
[Platform Demo/show-os] 🏁 Job succeeded
命令行覆盖 actrc(临时改映射到 act-latest,同一条 runs-on: ubuntu-22.04 换了镜像):
act push -W .github/workflows/platform.yml -P ubuntu-22.04=ghcr.io/catthehacker/ubuntu:act-latest --pull=false
实测关键输出行:
[Platform Demo/show-os] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
[Platform Demo/show-os] | PRETTY_NAME="Ubuntu 24.04.4 LTS"
[Platform Demo/show-os] 🏁 Job succeeded
-p/--pull 默认 true:每次执行都向远端确认镜像(4.3 节日志中的 forcePull=true);本地已有镜像时加 --pull=false 跳过远端检查(forcePull=false),重复验证速度明显更快。镜像本地不存在时,即使 --pull=false,act 也会尝试拉取(见六章 Q4 报错样例)。
4.7 输出控制类:--json、-q
--json。全部日志转为结构化 JSON 行,便于程序消费。实测(跑 env.yml,节选首尾):
{"level":"info","msg":"Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock'","time":"2026-10-18T02:10:15Z"}
{"dryrun":false,"job":"EnvFile Demo/show","jobID":"show","level":"info","matrix":{},"msg":"⭐ Run Set up job","step":"Set up job","stepid":["--setup-job"],"time":"2026-10-18T02:10:15Z"}
...
{"dryrun":false,"job":"EnvFile Demo/show","jobID":"show","level":"info","matrix":{},"msg":"MY_ENV=from-dotenv-file, token length=11, APP_MODE=debug-from-varfile\n","raw_output":true,"stage":"Main","step":"Show env","stepID":["0"],"time":"2026-10-18T02:10:16Z"}
...
{"dryrun":false,"job":"EnvFile Demo/show","jobID":"show","jobResult":"success","level":"info","matrix":{},"msg":"🏁 Job succeeded","time":"2026-10-18T02:10:16Z"}
字段规律:步骤输出行带 "raw_output":true;Job 结果行带 "jobResult";每行都含 job/jobID/step/time,可直接用 jq 过滤。
-q/--quiet。抑制步骤输出(| 行),保留 act 自身的调度与状态行,适合只要「过没过」的场景。实测(单跑 env.yml):
time="2026-10-18T02:38:12Z" level=info msg="Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock'"
[EnvFile Demo/show] ⭐ Run Set up job
[EnvFile Demo/show] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
[EnvFile Demo/show] 🐳 docker pull image=ghcr.io/catthehacker/ubuntu:act-latest platform= username= forcePull=false
[EnvFile Demo/show] 🐳 docker create image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[EnvFile Demo/show] 🐳 docker run image=ghcr.io/catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[EnvFile Demo/show] 🐳 docker exec cmd=[node --no-warnings -e console.log(process.execPath)] user= workdir=
[EnvFile Demo/show] ✅ Success - Set up job
[EnvFile Demo/show] ⭐ Run Main Show env
[EnvFile Demo/show] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/0] user= workdir=
[EnvFile Demo/show] ✅ Success - Main Show env [44.674619ms]
[EnvFile Demo/show] ⭐ Run Complete job
[EnvFile Demo/show] Cleaning up container for job show
[EnvFile Demo/show] ✅ Success - Complete job
[EnvFile Demo/show] 🏁 Job succeeded
EXIT=0
对比 4.5 节同一工作流的普通输出:| MY_ENV=... 行消失,仅剩 ✅ 状态行——这就是 -q 的确切效果。
4.8 其余常用参数速查
以下参数定义均摘自 4.1 节 act --help 实测原文(标注「未实测」的表示本文仅核对定义、未给出运行回显,使用前建议先 -n dryrun 验证):
| 参数 | 作用(help 原文意译) | 备注 |
|---|---|---|
-w --watch | 监视本地仓库内容变化并自动重跑 | 本地开发循环;未实测 |
-r --reuse | 成功后不销毁执行实例,保留状态供下次复用 | 调试有状态步骤;未实测 |
--rm | 失败后自动清理执行实例与卷 | 未实测 |
--concurrent-jobs | 最大并行 Job 数,默认取 CPU 数 | 未实测 |
--container-architecture | 指定目标架构(如 linux/amd64),需 Docker API 1.41+ | 跨架构模拟;未实测 |
--container-cap-add/drop | 增/删执行实例的内核能力(如 SYS_PTRACE) | 未实测 |
--container-daemon-socket | 指定 Docker 套接字 URI,- 表示不挂载 | 未实测 |
--network | Job 使用的网络模式,默认 host | 未实测 |
-b --bind | 以绑定挂载方式使用工作目录,而非复制 | 修改即时可见;未实测 |
--no-skip-checkout | 真正执行 actions/checkout 而非本地复制 | 实测见五章第 4 条 |
--action-offline-mode | action 内容已存在时不再拉取 | 离线环境;未实测 |
--local-repository | 把指定仓库/ref 替换为本地目录 | GHE/私有 action 场景;未实测 |
--strict | 严格 workflow schema 校验 | 未实测 |
--validate | 校验工作流后退出 | 实测见六章 Q5 |
--no-cache-server | 关闭内置缓存服务 | 未实测 |
--insecure-secrets | 日志中不隐藏 secrets(官方标注 NOT RECOMMENDED) | 仅排障临时使用;未实测 |
--log-prefix-job-id | 非 JSON 日志前缀改用 job id | 未实测 |
-C --directory | 指定工作目录(默认 .) | 未实测 |
--github-instance | GitHub Enterprise Server 场景指定实例 | 配合 --replace-ghe-action-* 使用;未实测 |
五、注意事项
- secrets 的脱敏与安全输入:日志中 secrets 自动脱敏(4.5 节
token length=15而非明文);需要看明文排障时才用--insecure-secrets且用完即弃。命令行传敏感值会进 shell 历史,官方推荐-s MY_TOKEN(不带值)触发安全输入,或act -s GITHUB_TOKEN="$(gh auth token)"。 .env/.secrets/.vars会自动生效且不应提交:act 在仓库根目录按默认文件名自动读取(4.5 节实测),.secrets一旦误提交,任何在该目录跑 act 的人都会加载其中敏感值。- run 脚本中的
#会截断命令:act 预处理步骤脚本时按 shell 词法把「空格 +#」起的内容当注释剥掉,即使它在引号内。实测run: echo "linting PR #${{ github.event.pull_request.number }}"生成的脚本在#处被截断,报错(完整实测回显):规避:[Hash Bug/lint] | /var/run/act/workflow/0: line 2: unexpected EOF while looking for matching `"' [Hash Bug/lint] ❌ Failure - Main Lint [44.76996ms] [Hash Bug/lint] exitcode '2': failure [Hash Bug/lint] 🏁 Job failed Error: Job 'lint' failed#紧贴前词(如PR#42)不触发;或改写不带#(本文演示仓库即用linting PR number ${{ ... }}写法)。 - actions/checkout 默认被本地复制替代:act 默认把仓库目录直接复制进执行器工作区(实测日志行
docker cp src=/opt/act-demo/. dst=/opt/act-demo,checkout 步骤 14ms 完成),.git、.github都在。确需真实远端 checkout 用--no-skip-checkout,但该模式要求本机能访问 github.com——实测内网直连不稳定时报git clone 'https://github.com/actions/checkout' # ref=v4后net/http: TLS handshake timeout(重试可成功)。 -j会连带执行needs依赖(4.3 节实测),只想跑单个 Job 时确认其依赖是否会被先跑。- schema 错误在任何命令解析期暴露:字段拼写错误(如
stratgy)会让-l、--validate、-n、真实执行全部失败(实测回显见六章 Q5),先跑act -l是最快校验。 - 退出码语义:步骤脚本以非零退出时,act 打印
exitcode 'N': failure并在全部 Job 结束后以退出码 1 结束(即使步骤内部是exit 3,act 进程仍是 1,实测见六章 Q1)——CI 脚本判断 act 结果只看 0/非 0。
六、常见问题
Q1:步骤失败了,act 的退出码是多少?
以演示工作流(step 内 exit 3,后随一个本不应执行的步骤)实测:
act push -W .broken/fail.yml --pull=false
实测回显(节选):
[Fail Demo/fail] ⭐ Run Main Boom
[Fail Demo/fail] | about to fail
[Fail Demo/fail] ❌ Failure - Main Boom [42.79627ms]
[Fail Demo/fail] exitcode '3': failure
[Fail Demo/fail] ⭐ Run Complete job
[Fail Demo/fail] ✅ Success - Complete job
[Fail Demo/fail] 🏁 Job failed
Error: Job 'fail' failed
EXIT=1
结论:失败步骤之后的步骤不再执行(输出中无 "should not see me");步骤自身的 exit 3 反映在 exitcode '3' 行;act 进程退出码为 1。
Q2:非交互终端首次运行报 level=fatal msg=EOF?
未预写 actrc 时 act 会弹出平台镜像三档选择提示(Large/Medium/Micro),非交互终端无人应答即报 EOF 退出(完整实测回显见《Ubuntu 22.04 安装 act 指南》7.4 节,其中包含提示原文与退出码 1)。解决:预写 actrc 平台映射后重跑。
Q3:报 not located inside a git repository?
运行类命令要求目录位于 git 仓库内(act 需读取 git ref/revision)。实测在非 git 目录执行 act push -n 的回显:
time="2026-10-18T02:16:13Z" level=error msg="path/tmp/gitlessnot located inside a git repository" error="repository does not exist"
time="2026-10-18T02:16:13Z" level=warning msg="unable to get git ref: repository does not exist"
time="2026-10-18T02:16:13Z" level=error msg="path/tmp/gitlessnot located inside a git repository" error="repository does not exist"
time="2026-10-18T02:16:13Z" level=warning msg="unable to get git revision: repository does not exist"
解决:git init && git add -A && git commit 后重跑即干净(实测验证)。
Q4:平台镜像拉取失败?
-P 指向不存在的镜像时,Set up job 阶段直接失败。实测回显:
act push -W .github/workflows/ci.yml -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:no-such-tag-404 --pull=false
[CI/build] ⭐ Run Set up job
[CI/build] 🚀 Start image=ghcr.io/catthehacker/ubuntu:no-such-tag-404
[CI/build] 🐳 docker pull image=ghcr.io/catthehacker/ubuntu:no-such-tag-404 platform= username= forcePull=false
[CI/build] Error response from daemon: failed to resolve reference "ghcr.io/catthehacker/ubuntu:no-such-tag-404": ghcr.io/catthehacker/ubuntu:no-such-tag-404: not found
[CI/build] ❌ Failure - Set up job
[CI/build] 🏁 Job failed
Error: Error response from daemon: failed to resolve reference "ghcr.io/catthehacker/ubuntu:no-such-tag-404": ghcr.io/catthehacker/ubuntu:no-such-tag-404: not found
EXIT=1
排查方向:标签拼写、镜像仓库可达性、Docker Engine 的代理/镜像源配置(见《act 运维手册》故障排查手册)。
Q5:workflow YAML 写错时如何快速定位?
两类典型错误实测。字段拼写错误(stratgy:)——act -l 与 act --validate 同样报错,给出行列号与官方修复指引:
Error: workflow is not valid. 'broken-schema.yml': Line: 5 Column 5: Failed to match job-factory: Line: 6 Column 5: Unknown Property stratgy
Line: 5 Column 5: Failed to match workflow-job: Line: 5 Column 5: Unknown Property runs-on
Line: 6 Column 5: Unknown Property stratgy
Line: 9 Column 5: Unknown Property steps
Actions YAML Schema Validation Error detected:
For more information, see: https://nektosact.com/usage/schema.html
EXIT=1
YAML 用 tab 缩进——解析器直接拒绝:
Error: workflow is not valid. 'broken-tab.yml': yaml: line 4: found character that cannot start any token
EXIT=1
结论:YAML 一律用空格缩进;写完先 act -l 过一遍。workflow YAML 语法本身的系统讲解见 《GitHub Actions 工作流配置详解》。
Q6:明明有工作流,act push 却没跑?
核对触发事件是否匹配:act push 只运行 on: push 的工作流,on: pull_request 的工作流要用 act pull_request -e <事件文件>。用 act -l 看 Events 列即可确认每个工作流的触发事件(实测回显见 4.2 节)。
七、参考链接
- 官方 Usage guide(事件/Secrets/配置文件/矩阵):https://nektosact.com/usage/index.html
- workflow schema 校验说明:https://nektosact.com/usage/schema.html
- 平台镜像说明(Runners):https://nektosact.com/usage/runners.html
- GitHub 仓库与 Releases:https://github.com/nektos/act
- 触发工作流的事件列表(GitHub 官方):https://docs.github.com/actions/using-workflows/events-that-trigger-workflows
- 站内相关:《act 介绍与选型指南》(定位与选型);《Ubuntu 22.04 安装 act 指南》(安装与 actrc);《GitHub Actions 常用 CLI 命令详解》(gh CLI 云端操作对照);《GitHub Actions 工作流配置详解》(workflow YAML 语法)