Earthly 内置参数(Builtin Args)完全指南:通用、目标、Git 与平台参数详解
2026/9/23 18:38:28 网站建设 项目流程

Earthly 内置参数(Builtin Args)完全指南:通用、目标、Git 与平台参数详解

【免费下载链接】earthlySuper simple build framework with fast, repeatable builds and an instantly familiar syntax – like Dockerfile and Makefile had a baby.项目地址: https://gitcode.com/gh_mirrors/ea/earthly

导读

本文以 docs/earthfile/builtin-args.md 为骨架,系统讲解 Earthly 内置参数(builtin args)的完整体系:它们由 Earthly 自动填充、无法被覆盖,但可以借助"默认值取自内置参数的普通ARG"实现可覆盖的二次包装。阅读完本文,你将掌握通用参数、目标相关参数、Git 相关参数与平台相关参数四类内置参数的全部名称、语义、示例值与底层实现原理,并能在 Earthfile 中正确预声明、安全引用它们,构建可复现、支持多平台与 CI 场景的构建配方。


一、什么是 Builtin args

Builtin args 是 Earthly 在构建过程中自动填充值的变量。与普通ARG不同,内置参数的值永远不能被覆盖——无论是通过命令行--build-arg--pass-args,还是在 Earthfile 内的ARG默认值,都无法改变其实际取值。

但 Earthly 提供了一种灵活的变通模式:你可以声明一个额外的普通ARG,将其默认值设为内置参数的值,随后这个新参数就可以被正常覆盖。典型场景是镜像标签:

ARG EARTHLY_TARGET_TAG ARG TAG=$EARTHLY_TARGET_TAG SAVE IMAGE --push some/name:$TAG

这里TAG的默认值取自内置参数EARTHLY_TARGET_TAG,当用户在命令行传入--build-arg TAG=...时即可覆盖默认值,实现"默认跟随构建上下文、必要时人工指定"的双重灵活性。

使用前提:必须先预声明

内置参数必须先声明后使用。例如直接引用EARTHLY_TARGET而不先声明会报错:

# 错误:EARTHLY_TARGET 未声明 RUN echo "The current target is $EARTHLY_TARGET"

正确的写法是先通过ARG声明:

ARG EARTHLY_TARGET RUN echo "The current target is $EARTHLY_TARGET"

这一约束在源码中可以得到印证:variables/reserved/names.go将所有内置参数名登记在一个 map 中,并通过IsBuiltIn函数判定名称是否属于内置参数(见 variables/reserved/names.go);内置参数的实际赋值则统一发生在variables/builtin.goBuiltinArgs函数中(见 variables/builtin.go),该函数根据目标引用、平台解析器、Git 元数据与功能开关(feature flags)等输入,构造出一个包含全部内置参数的变量作用域。

从源码结构可以推断:内置参数并非运行时"魔法注入",而是由 Earthly 在构建启动阶段一次性计算并放入内置作用域,Earthfile 解析器随后要求使用前显式ARG声明,从而保证构建配方的可读性与显式性。


二、通用参数(General args)

名称描述示例值
EARTHLY_CI构建是否运行在--ci模式下。truefalse
EARTHLY_BUILD_SHA构建当前运行的 Earthly 版本时所用的 Git 提交哈希。1a9eda7a83af0e2ec122720e93ff6dbe9231fc0c
EARTHLY_LOCALLY当前 target 是否以LOCALLY方式执行。truefalse
EARTHLY_PUSHearthly命令是否带有--push标志。truefalse
EARTHLY_VERSION当前运行的 Earthly 版本号。v0.8.0

这些参数在 variables/builtin.go 中的注入逻辑如下:

  • EARTHLY_PUSH仅在启用WaitBlock--wait-block)功能开关时注入,值为push布尔量的字符串形式;
  • EARTHLY_VERSIONEARTHLY_BUILD_SHA仅在启用EarthlyVersionArg--earthly-version-arg,VERSION 0.7 起默认启用)时注入,值来自外部传入的DefaultArgs结构体(见 variables/builtin.go);
  • EARTHLY_CI仅在启用EarthlyCIArg--ci-arg)时注入;
  • EARTHLY_LOCALLY仅在启用EarthlyLocallyArg--earthly-locally-arg)时注入,且初始值为false

从 features/features.go 可以看到,这些功能开关大多在VERSION 0.7中随版本默认启用,因此现代 Earthfile(如VERSION 0.7+)中可以放心使用。

LOCALLY模式下,EARTHLY_LOCALLY会被置为true:源码中 earthfile2llb/converter.go 在进入本地执行分支时调用SetLocally(true),而常规构建则调用SetLocally(false)(见 earthfile2llb/converter.go)。


三、目标相关参数(Target-related args)

这组参数描述"当前正在构建的 target"的规范引用(canonical reference)各组成部分。

名称描述示例值
EARTHLY_TARGET_NAME当前 target 规范引用的名字部分。对于github.com/bar/buz/src:john/work+foo,名字为foo
EARTHLY_TARGET_PROJECT_NO_TAG当前 target 规范引用的项目部分,不含 tag。对于github.com/bar/buz/src:john/work+foo,为github.com/bar/buz/src
EARTHLY_TARGET_PROJECT当前 target 规范引用的项目部分。对于github.com/bar/buz/src:john/work+foo,为github.com/bar/buz/src:john
EARTHLY_TARGET_TAG_DOCKER当前 target 规范引用的 tag 部分,经过净化处理,保证可作为合法的 Docker tag 使用;即使不存在规范形式,也会保证是合法的 Docker tag(此时用latest)。对于github.com/bar/buz/src:john/work+foo,为john_work
EARTHLY_TARGET_TAG当前 target 规范引用的 tag 部分;若 target 没有规范形式,则为空字符串。对于github.com/bar/buz/src:john/work+foo,为john/work
EARTHLY_TARGET当前 target 的完整规范引用。见下

footarget 为例:它存在于john/work分支、仓库位于github.com/bar/buz、子目录为src,则规范引用为github.com/bar/buz/src:john/work+foo。关于规范引用的完整定义,参见 导入指南(canonical form):规范引用本质上是 target 的远程形式,仓库位置取自origin远程,子目录即 target 所在目录,tag 则按"首个 Git tag → 当前分支 → 当前 Git hash"的优先级推断;如果 Earthly 未检测到任何 Git 上下文,则该 target 不具有规范形式。

源码实现细节

在 variables/builtin.go 中:

ret.Add(arg.EarthlyTarget, target.StringCanonical()) ret.Add(arg.EarthlyTargetProject, target.ProjectCanonical()) targetNoTag := target targetNoTag.Tag = "" ret.Add(arg.EarthlyTargetProjectNoTag, targetNoTag.ProjectCanonical()) ret.Add(arg.EarthlyTargetName, target.Target) setTargetTag(ret, target, gitMeta)

其中setTargetTag(见 variables/builtin.go)的取值逻辑值得注意:如果检测到 Git 元数据且存在分支覆盖标志(BranchOverrideTagArg),则优先使用分支名作为EARTHLY_TARGET_TAG;否则使用 target 自身的 tag。EARTHLY_TARGET_TAG_DOCKER则通过llbutil.DockerTagSafe函数将 tag 净化成合法的 Docker tag 形式(如将john/work转换为john_work)。

实战示例:用内置 tag 给镜像打标签

build: FROM alpine:3.18 ARG EARTHLY_TARGET_TAG ARG TAG=$EARTHLY_TARGET_TAG SAVE IMAGE --push some/name:$TAG

若在带规范引用的 Git 仓库中运行,TAG默认为当前分支/tag;在命令行传入--build-arg TAG=stable即可覆盖。

仓库中的集成测试 tests/builtin-args.earth 验证了这些行为:在无 Git 上下文的本地构建中,EARTHLY_TARGET等于+builtin-args-testEARTHLY_TARGET_PROJECT为空、EARTHLY_TARGET_TAG为空字符串(test -z断言),这正对应"无规范形式时 tag 为空"的文档描述。


四、Git 相关参数(Git-related args)

这组参数从构建上下文目录中检测到的 Git 仓库提取信息;若未检测到 Git 目录,值为空字符串。

名称描述示例值功能开关(Feature Flag)
EARTHLY_GIT_AUTHOR构建上下文目录中检测到的 Git 作者。未检测到 Git 目录时为空字符串。当前默认只含作者邮箱,启用开关后包含姓名。john@example.com(开启开关后为John Doe <john@example.com>--earthly-git-author-individual-args
EARTHLY_GIT_AUTHOR_EMAIL构建上下文目录中检测到的 Git 作者邮箱。未检测到 Git 目录时为空字符串。john@example.com--earthly-git-author-individual-args
EARTHLY_GIT_AUTHOR_NAME构建上下文目录中检测到的 Git 作者姓名。未检测到 Git 目录时为空字符串。John Doe--earthly-git-author-individual-args
EARTHLY_GIT_CO_AUTHORS构建上下文目录中检测到的 Git 共同作者,以空格分隔。未检测到 Git 目录时为空字符串。Jane Doe <jane@example.com Jack Smith <jack@example.com>
EARTHLY_GIT_COMMIT_AUTHOR_TIMESTAMP检测到的 Git 提交的作者时间戳(Unix 秒)。未检测到 Git 目录时为空字符串。1626881847
EARTHLY_GIT_BRANCH检测到的 Git 提交所在分支。未检测到 Git 目录时为空字符串。main
EARTHLY_GIT_COMMIT_TIMESTAMP检测到的 Git 提交的提交者时间戳(Unix 秒)。未检测到 Git 目录时为空字符串。1626881847
EARTHLY_GIT_HASH检测到的 Git 提交哈希。未检测到 Git 目录时为空字符串。注意:该值频繁变化,可能导致无法命中缓存,使用需谨慎。41cb5666ade67b29e42bef121144456d3977a67a
EARTHLY_GIT_ORIGIN_URL检测到的 Git 远程 URL。未检测到 Git 目录时为空字符串。注意该值可能不一致,取决于使用的是 HTTPS 还是 SSH URL。git@github.com:bar/buz.githttps://github.com/bar/buz.git
EARTHLY_GIT_PROJECT_NAME从 Git URL 中提取的项目名。未检测到 Git 目录时为空字符串。bar/buz
EARTHLY_GIT_REFS检测到的 Git 提交的引用(refs),以空格分隔。未检测到 Git 目录时为空字符串。issue-2735-git-ref main
EARTHLY_GIT_SHORT_HASH检测到的 Git 提交哈希的前 8 个字符。未检测到 Git 目录时为空字符串。注意:同样频繁变化,可能影响缓存命中。41cb5666
EARTHLY_SOURCE_DATE_EPOCH检测到的 Git 提交时间戳(Unix 秒)。未检测到 Git 目录时为0(Unix 纪元)。16268818470

功能开关与版本演进

这些参数的注入严格受功能开关控制(见 features/features.go):

  • --earthly-git-author-args(VERSION 0.7 起启用):注入EARTHLY_GIT_AUTHOREARTHLY_GIT_CO_AUTHORS,此时EARTHLY_GIT_AUTHOR的值为作者邮箱;
  • --git-author-email-name-args(未发布功能):注入EARTHLY_GIT_AUTHOR_EMAILEARTHLY_GIT_AUTHOR_NAME,同时将EARTHLY_GIT_AUTHOR升级为Name <email>格式(见 variables/builtin.go);
  • --git-commit-author-timestamp(VERSION 0.7 起启用):注入EARTHLY_GIT_COMMIT_AUTHOR_TIMESTAMP
  • --git-refs(VERSION 0.8 起启用):注入EARTHLY_GIT_REFS

对应源码注入逻辑位于 variables/builtin.go:当gitMeta非空时依次注入 hash、短 hash、分支、tag、origin URL、脱敏后的 origin URL(EARTHLY_GIT_ORIGIN_URL_SCRUBBED,用于安全地输出到日志)、项目名与各时间戳;当gitMeta为空(未检测到 Git 目录)时,仅保证EARTHLY_SOURCE_DATE_EPOCH恒为0

EARTHLY_GIT_PROJECT_NAME的提取算法为getProjectName(见 variables/builtin.go):它剥离协议前缀(http://https://ssh://等)、剥离开头的user@、去掉.git后缀,并兼容git@github.com:bar/buz.git这类 scp 风格 URL;对应的单元测试见 variables/builtin_test.go,覆盖了 HTTP(S)、SSH、带凭据、带子目录等多种 URL 形态。

实战:如何安全使用 Git 参数

# 注意:EARTHLY_GIT_HASH 频繁变化会破坏缓存,仅用于需要唯一标识的产物 build: ARG EARTHLY_GIT_SHORT_HASH RUN echo "building commit $EARTHLY_GIT_SHORT_HASH"

测试文件 tests/empty-git.earth 展示了无 Git 上下文时的行为:EARTHLY_GIT_HASH为空字符串(test "$EARTHLY_GIT_HASH" == ""),EARTHLY_TARGET_TAG同样为空。因此涉及 Git 参数的逻辑必须对空值有兜底处理。


五、平台相关参数(Platform-related args)

这组参数描述构建运行环境与目标平台,与 Dockerfile 中的平台参数同源(TARGETOS/TARGETARCH/TARGETPLATFORM/TARGETVARIANT),并扩展出 NATIVE 与 USER 两套维度。

名称描述示例值
NATIVEARCH构建运行器的原生处理器架构。armamd64arm64
NATIVEOS构建运行器的原生操作系统。linux
NATIVEPLATFORM构建运行器的原生平台。linux/arm/v7linux/amd64darwin/arm64
NATIVEVARIANT构建运行器的原生处理器架构变体。v7
TARGETARCH目标 target 构建所面向的处理器架构。armamd64arm64
TARGETOS目标 target 构建所面向的操作系统。linux
TARGETPLATFORM目标 target 构建所面向的平台,默认取原生平台。linux/arm/v7linux/amd64linux/arm64
TARGETVARIANT目标 target 构建所面向的处理器架构变体。v7
USERARCH用户(调用earthly二进制的环境)的处理器架构。armamd64arm64
USEROS用户(调用earthly二进制的环境)的操作系统。darwin
USERPLATFORM用户(调用earthly二进制的环境)的平台。darwin/amd64linux/amd64darwin/arm64
USERVARIANT用户(调用earthly二进制的环境)的处理器架构变体。v7

三个维度的含义

  • TARGET(目标):target 实际构建运行所面向的平台,决定产物形态。非LOCALLY时,TARGETPLATFORM默认等于运行器的原生平台。
  • NATIVE(原生):BuildKit 构建运行器的实际平台。启用--new-platformNewPlatform开关,VERSION 0.7 起)后才会注入 NATIVE 系列参数。
  • USER(用户):执行earthly命令的本地环境平台,与构建运行器(可能是远程 BuildKit 或 Docker 容器)平台不一定相同。

对应的注入逻辑见 variables/builtin.go:SetPlatformArgs基于平台解析器当前平台填充 TARGET 系列;setUserPlatformArgs填充 USER 系列;setNativePlatformArgs仅在NewPlatform开关开启时填充 NATIVE 系列。所有参数名均登记在 variables/reserved/names.go。

覆盖 TARGETPLATFORM 的三种方式

TARGETPLATFORM的默认值(非 LOCALLY 时)为运行器原生平台,可通过以下方式覆盖:

1. CLI 全局--platform标志

earthly --platform linux/amd64 +my-target

这会将TARGETPLATFORM设为linux/amd64

2. Earthfile 内BUILD --platform

BUILD --platform linux/amd64 +my-target

3.FROM --platform指定基础镜像平台

FROM --platform linux/amd64 alpine:3.13

LOCALLY 下的特殊行为

LOCALLY模式下,TARGETPLATFORM始终等于用户平台(即调用earthly二进制的环境),并且不会被--platform标志覆盖

此时有一个重要的声明顺序约束:TARGETPLATFORM必须在LOCALLY命令之后声明,才能取到正确的用户平台值:

my-target: LOCALLY ARG TARGETPLATFORM RUN echo "The target platform under LOCALLY is $TARGETPLATFORM"

如果颠倒顺序、在LOCALLY之前声明,TARGETPLATFORM可能取不到用户平台值。这一约束与内置参数"构建启动时一次性注入"的实现方式相关——从源码结构看,LOCALLY命令会触发本地执行分支的状态切换,平台参数的作用域随之更新。

多平台构建实战模板

build: FROM alpine:3.18 ARG TARGETARCH ARG TARGETOS RUN echo "Building for $TARGETOS/$TARGETARCH" # 按架构下载对应二进制等 RUN wget -O /bin/app https://example.com/bin/app-$TARGETOS-$TARGETARCH SAVE ARTIFACT /bin/app AS LOCAL app-$TARGETOS-$TARGETARCH # 多平台输出:对每个目标平台分别构建 all: BUILD --platform linux/amd64 +build BUILD --platform linux/arm64 +build

结合TARGETARCH/TARGETOS,可以在单个 target 内根据目标平台差异化执行下载、编译与打包,配合BUILD --platform实现真正的多平台产物输出。


六、内置参数的完整使用要点总结

  1. 先声明后使用:所有内置参数在使用前必须用ARG显式声明,否则会报错。
  2. 不可覆盖,但可包装:内置参数值永远不可被覆盖;若需要可覆盖的默认值,声明ARG X=$BUILTIN形式的普通参数即可。
  3. 受功能开关(feature flags)控制:部分内置参数(如 Git 作者系列、EARTHLY_GIT_REFS、NATIVE 平台系列)依赖 VERSION 中的功能开关,使用前需确认 Earthfile 的VERSION声明(参考 features/features.go 中各开关的enabled_in_version)。
  4. 注意缓存影响EARTHLY_GIT_HASHEARTHLY_GIT_SHORT_HASH随提交频繁变化,会显著降低缓存命中率,仅在确实需要唯一标识时使用。
  5. 无 Git 上下文时的空值:未检测到 Git 目录时,所有 Git 相关参数为空字符串,EARTHLY_SOURCE_DATE_EPOCH0,代码中需对空值做兜底。
  6. LOCALLY 模式特例TARGETPLATFORM在 LOCALLY 下恒为用户平台且不可被--platform覆盖;平台参数声明须放在LOCALLY命令之后。

深入阅读

  • 内置参数官方参考:docs/earthfile/builtin-args.md
  • 内置参数注入实现:variables/builtin.go
  • 内置参数名登记与判定:variables/reserved/names.go
  • 功能开关定义:features/features.go
  • 规范引用(canonical form)说明:docs/guides/importing.md
  • 集成测试:tests/builtin-args.earth、tests/empty-git.earth
  • 平台参数提取单元测试:variables/builtin_test.go

【免费下载链接】earthlySuper simple build framework with fast, repeatable builds and an instantly familiar syntax – like Dockerfile and Makefile had a baby.项目地址: https://gitcode.com/gh_mirrors/ea/earthly

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

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

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

立即咨询