act 怎么通过 --env-file 加载本地环境:.env 与 YAML 文件的识别规则和参数优先级
2026/9/9 19:17:38 网站建设 项目流程

act 怎么通过 --env-file 加载本地环境:.env 与 YAML 文件的识别规则和参数优先级

【免费下载链接】actRun your GitHub Actions locally 🚀项目地址: https://gitcode.com/GitHub_Trending/ac/act

用 act 在本地运行 GitHub Actions 工作流时,常需要把本地环境里的变量(数据库地址、API 密钥所在的中间变量等)注入到 job 容器中。act提供了--env-file参数完成这件事:它把指定文件读成键值对,作为容器内的环境变量使用。这个参数的默认值是.env,文件既可以是 dotenv 格式(如.env),也可以是 YAML(扩展名为.yml/.yaml)。本文说明它的文件识别规则、路径解析方式,以及当同一变量在--env参数、.actrc和 env-file 中同时出现时谁生效,并给出验证加载结果的方法。

--env-file的定义与路径解析

在 cmd/root.go 中,该参数被注册为全局持久参数:

rootCmd.PersistentFlags().StringVarP(&input.envfile, "env-file", "", ".env", "environment file to read and use as env in the containers")

即默认读取工作目录下的.env,读取结果"作为容器内的环境变量使用"。不显式传参时就是走.env这个默认路径。

路径解析逻辑在 cmd/input.go 的Input.resolve中:相对路径会拼接到--directory(短选项-C)指定的工作目录(默认.)之后,绝对路径则原样使用。也就是说:

# 在仓库根目录下运行 push 事件的工作流,env 文件取默认的 ./.env act push # 显式指定 env 文件;相对路径相对于当前目录(-C 未指定时) act push --env-file env/local.yml # 用 -C 把工作目录切到别的目录,--env-file 的相对路径也相对该目录解析 act -C /home/user/myrepo push --env-file .env

运行入口在 cmd/root.go 的newRunCommand中,加载顺序是:

log.Debugf("Loading environment from %s", input.Envfile()) envs := parseEnvs(input.envs) // 先放入命令行 --env 的键值对 _ = readEnvs(input.Envfile(), envs) // 再读 env-file 文件

.env与 YAML 文件的识别规则

格式识别只看文件扩展名。readEnvsEx(cmd/root.go)先检查文件是否存在,然后:

  • 扩展名为.yml.yaml:按 YAML 解析成map[string]string,即键: 值的映射;
  • 其他扩展名(包括无扩展名、.env等):交给godotenv.Read解析,即KEY=value每行一个键值对。

dotenv 风格文件的最小例子(与仓库测试数据 pkg/container/testdata/valid.env 相同):

ENV1=value1

YAML 文件支持多行值。仓库的 cmd/testdata/secrets.yml 就是这样一份测试数据,cmd/root_test.go 中的TestReadEnv验证了它被读成mysecret键、值为三行line1/line2/line3(块量级|保留换行):

mysecret: | line1 line2 line3

两个边界行为要注意:

  1. 文件不存在时不报错readEnvsExos.Stat失败静默返回false,act 继续运行,只是没有从该文件注入任何变量。拼错--env-file路径时不会出现任何提示,这是排查"变量没生效"时首先要确认的点。
  2. 文件存在但解析失败时会直接终止。代码路径是log.Fatalf("Error loading from %s: %v", path, err),即 YAML 写错缩进或格式非法时 act 会报错退出,错误信息包含出问题的文件路径。

另外,env-file 的键名按原样使用,不会做大小写转换:readEnvs调用的是readEnvsEx(path, envs, false)(cmd/root.go),caseInsensitivefalse。测试数据中的小写键mysecret就以小写键名被写入环境(见 cmd/root_test.go)。而--secret-file走的是大小写不敏感分支,两者不要混为一谈。

参数优先级:同一变量多处定义时谁生效

优先级规则同样来自 cmd/root.go 的代码。

--env参数优先于 env-file。newRunCommand先用parseEnvs(input.envs)把命令行--env KEY=value的键值对放进envs,随后readEnvsEx写入文件内容时有显式判断:

if _, ok := envs[k]; !ok { envs[k] = v }

也就是说,env-file 只会补齐--env里不存在的键;同名键以--env的值为准。parseEnvs按第一个=拆分,--env FOO=prefix/foo/suffix这种带=的值是安全的(只拆一次)。仓库测试数据 cmd/testdata/env.actrc 中就有一条--env FOO=prefix/${FOO}/suffix,测试 cmd/root_test.go 确认它最终生成了--env FOO=prefix/foo/suffix

--env-file参数本身的取值,命令行优先于.actrcact 支持.actrc配置文件,查找顺序(见 cmd/root.go 的configLocations注释与实现):

  1. XDG 规范路径(xdg.ConfigFile("act/actrc"));
  2. 主目录下的~/.actrc
  3. 当前调用目录下的./.actrc

args()把三个文件中读到的参数按上述顺序依次追加,最后再追加os.Args[1:](命令行实参):

for _, f := range actrc { args = append(args, readArgsFile(f, true)...) } args = append(args, os.Args[1:]...)

同一参数名出现多次时,后面的值覆盖前面的,因此最终优先级为:命令行 >./.actrc>~/.actrc> XDG 配置路径.actrc每行写一个选项(可带参数),并且支持${VAR}形式的环境变量展开,例如 cmd/testdata/env.actrc 的内容:

--artifact-server-path $FAKEPWD/.artifacts --env FOO=prefix/${FOO}/suffix

测试 cmd/root_test.go 的TestReadArgsFile表明:当宿主环境中设置了FAKEPWDFOO时,上面两行会被展开为--artifact-server-path /fake/test/pwd/.artifacts--env FOO=prefix/foo/suffix。所以你也可以把--env-file env/local.yml写进.actrc,省去每次敲参数。

验证加载是否生效

看调试日志。-v(verbose,把日志级别调到 Debug)后,newRunCommand会打印加载的文件路径:

act -v push --env-file env/local.yml

输出中的Loading environment from <路径>一行会给出解析后的完整路径,可以先确认文件是否指向你以为的那个文件。

--dryrun校验组合是否正确。--dryrun(短选项-n)的说明是 "disable container creation, validates only workflow correctness",即不创建容器、只校验工作流正确性。在不打算真正跑容器时,可以用它配合--env-file快速确认参数组合没有报错(注意--dryrun下不会真正在容器里验证变量值)。

用测试用例作为参照。pkg/container/docker_cli_test.go 的TestParseEnvfileVariables展示了预期行为(文档示例,非运行时固定输出):

  • --env-file=testdata/valid.env解析出的容器环境为ENV1=value1
  • 同时给出--env=ENV2=value2时,容器环境包含ENV1=value1ENV2=value2两项;
  • 文件不存在时返回open nonexistent: no such file or directory(该用例针对 docker 参数层,与前述"act 层文件缺失静默跳过"是两个不同层次,排查时注意区分报错来自哪一层)。

工作流内部的步骤读取的是注入到容器中的环境变量(参数说明原文为 "use as env in the containers"),变量是否可用以步骤内的实际行为为准。

限制与注意点

  • 文件不存在是静默行为:--env-file指到不存在的路径时 act 不会报错,只是没有注入任何变量。变量"没生效"时,先用-vLoading environment from的路径是否是你预期的文件。
  • 文件存在但内容非法(如 YAML 缩进错误)会直接终止 act,错误信息为Error loading from <路径>: <原因>
  • 识别规则完全由扩展名决定:内容写成 dotenv 但扩展名是.yaml会被按 YAML 解析而失败;反之.env扩展名的 YAML 内容也走 dotenv 解析。想使用 YAML 的多行值等能力,文件必须命名为.yml.yaml
  • env-file 的键区分大小写且不自动大写;需要大小写不敏感读取的是--secret-file路径,不要靠改 env-file 的键名大小写去对齐 secret。
  • --env-file注入的是容器环境变量,不会改变宿主 shell 的环境;.actrc里的${VAR}展开读取的是运行 act 的宿主环境。

排查与扩展的入口文件:cmd/root.go(参数定义与加载顺序)、cmd/input.go(路径解析)、cmd/root_test.go(actrc 与 YAML 读取的测试用例)。

【免费下载链接】actRun your GitHub Actions locally 🚀项目地址: https://gitcode.com/GitHub_Trending/ac/act

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询