act 常用 CLI 命令与工具详解

act v0.2.89 全参数详解:--help 全量整理、-l/--graph/-j/-n/-e/-a/-s/--var/--env/-P/--json/-q 等逐条实测回显,附 `#` 截断、schema 校验、git 依赖等注意事项与排障结论。

actact2026/10/18

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 这类子命令,一切能力都通过「命令 + 事件名 + 参数」表达,命令形态只有三种:

  1. 信息查看:act --help、act -l、act --graph、act --list-options、act --bug-report 等,只读不执行。
  2. 事件执行:act [事件名]——事件名直接写在命令尾部(act push、act pull_request);不带事件名时默认按 push 处理(--help 原文:If no event name passed, will default to "on: push"),再叠加范围与注入参数。
  3. 配置输出:--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/actstring
actornektos/actstring
artifact-server-addr172.17.0.30(取本机网卡地址,随环境变化)string
artifact-server-port34567string
cache-server-path/root/.cache/actcachestring
cache-server-port0(随机端口)uint16
concurrent-jobs0(默认取 CPU 数)int
directory.string
dryrunfalsebool
env-file.envstring
github-instancegithub.comstring
input-file.inputstring
networkhoststring
platform[]stringArray
pulltruebool
rebuildtruebool
remote-nameoriginstring
secret-file.secretsstring
use-gitignoretruebool
var-file.varsstring
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,- 表示不挂载未实测
--networkJob 使用的网络模式,默认 host未实测
-b --bind以绑定挂载方式使用工作目录,而非复制修改即时可见;未实测
--no-skip-checkout真正执行 actions/checkout 而非本地复制实测见五章第 4 条
--action-offline-modeaction 内容已存在时不再拉取离线环境;未实测
--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-instanceGitHub Enterprise Server 场景指定实例配合 --replace-ghe-action-* 使用;未实测

五、注意事项

  1. secrets 的脱敏与安全输入:日志中 secrets 自动脱敏(4.5 节 token length=15 而非明文);需要看明文排障时才用 --insecure-secrets 且用完即弃。命令行传敏感值会进 shell 历史,官方推荐 -s MY_TOKEN(不带值)触发安全输入,或 act -s GITHUB_TOKEN="$(gh auth token)"。
  2. .env/.secrets/.vars 会自动生效且不应提交:act 在仓库根目录按默认文件名自动读取(4.5 节实测),.secrets 一旦误提交,任何在该目录跑 act 的人都会加载其中敏感值。
  3. 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 ${{ ... }} 写法)。
  4. 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(重试可成功)。
  5. -j 会连带执行 needs 依赖(4.3 节实测),只想跑单个 Job 时确认其依赖是否会被先跑。
  6. schema 错误在任何命令解析期暴露:字段拼写错误(如 stratgy)会让 -l、--validate、-n、真实执行全部失败(实测回显见六章 Q5),先跑 act -l 是最快校验。
  7. 退出码语义:步骤脚本以非零退出时,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 节)。

七、参考链接