Earthly 内置参数(Builtin Args)完全指南:通用、目标、Git 与平台参数详解
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 argsBuiltin 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.go的BuiltinArgs函数中见 variables/builtin.go该函数根据目标引用、平台解析器、Git 元数据与功能开关feature flags等输入构造出一个包含全部内置参数的变量作用域。从源码结构可以推断内置参数并非运行时魔法注入而是由 Earthly 在构建启动阶段一次性计算并放入内置作用域Earthfile 解析器随后要求使用前显式ARG声明从而保证构建配方的可读性与显式性。二、通用参数General args名称描述示例值EARTHLY_CI构建是否运行在--ci模式下。true、falseEARTHLY_BUILD_SHA构建当前运行的 Earthly 版本时所用的 Git 提交哈希。1a9eda7a83af0e2ec122720e93ff6dbe9231fc0cEARTHLY_LOCALLY当前 target 是否以LOCALLY方式执行。true、falseEARTHLY_PUSHearthly命令是否带有--push标志。true、falseEARTHLY_VERSION当前运行的 Earthly 版本号。v0.8.0这些参数在 variables/builtin.go 中的注入逻辑如下EARTHLY_PUSH仅在启用WaitBlock--wait-block功能开关时注入值为push布尔量的字符串形式EARTHLY_VERSION与EARTHLY_BUILD_SHA仅在启用EarthlyVersionArg--earthly-version-argVERSION 0.7 起默认启用时注入值来自外部传入的DefaultArgs结构体见 variables/builtin.goEARTHLY_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/workfoo名字为fooEARTHLY_TARGET_PROJECT_NO_TAG当前 target 规范引用的项目部分不含 tag。对于github.com/bar/buz/src:john/workfoo为github.com/bar/buz/srcEARTHLY_TARGET_PROJECT当前 target 规范引用的项目部分。对于github.com/bar/buz/src:john/workfoo为github.com/bar/buz/src:johnEARTHLY_TARGET_TAG_DOCKER当前 target 规范引用的 tag 部分经过净化处理保证可作为合法的 Docker tag 使用即使不存在规范形式也会保证是合法的 Docker tag此时用latest。对于github.com/bar/buz/src:john/workfoo为john_workEARTHLY_TARGET_TAG当前 target 规范引用的 tag 部分若 target 没有规范形式则为空字符串。对于github.com/bar/buz/src:john/workfoo为john/workEARTHLY_TARGET当前 target 的完整规范引用。见下以footarget 为例它存在于john/work分支、仓库位于github.com/bar/buz、子目录为src则规范引用为github.com/bar/buz/src:john/workfoo。关于规范引用的完整定义参见 导入指南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 TAGstable即可覆盖。仓库中的集成测试 tests/builtin-args.earth 验证了这些行为在无 Git 上下文的本地构建中EARTHLY_TARGET等于builtin-args-test、EARTHLY_TARGET_PROJECT为空、EARTHLY_TARGET_TAG为空字符串test -z断言这正对应无规范形式时 tag 为空的文档描述。四、Git 相关参数Git-related args这组参数从构建上下文目录中检测到的 Git 仓库提取信息若未检测到 Git 目录值为空字符串。名称描述示例值功能开关Feature FlagEARTHLY_GIT_AUTHOR构建上下文目录中检测到的 Git 作者。未检测到 Git 目录时为空字符串。当前默认只含作者邮箱启用开关后包含姓名。johnexample.com开启开关后为John Doe johnexample.com--earthly-git-author-individual-argsEARTHLY_GIT_AUTHOR_EMAIL构建上下文目录中检测到的 Git 作者邮箱。未检测到 Git 目录时为空字符串。johnexample.com--earthly-git-author-individual-argsEARTHLY_GIT_AUTHOR_NAME构建上下文目录中检测到的 Git 作者姓名。未检测到 Git 目录时为空字符串。John Doe--earthly-git-author-individual-argsEARTHLY_GIT_CO_AUTHORS构建上下文目录中检测到的 Git 共同作者以空格分隔。未检测到 Git 目录时为空字符串。Jane Doe janeexample.com Jack Smith jackexample.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。gitgithub.com:bar/buz.git或https://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 目录时为0Unix 纪元。1626881847、0—功能开关与版本演进这些参数的注入严格受功能开关控制见 features/features.go--earthly-git-author-argsVERSION 0.7 起启用注入EARTHLY_GIT_AUTHOR与EARTHLY_GIT_CO_AUTHORS此时EARTHLY_GIT_AUTHOR的值为作者邮箱--git-author-email-name-args未发布功能注入EARTHLY_GIT_AUTHOR_EMAIL与EARTHLY_GIT_AUTHOR_NAME同时将EARTHLY_GIT_AUTHOR升级为Name email格式见 variables/builtin.go--git-commit-author-timestampVERSION 0.7 起启用注入EARTHLY_GIT_COMMIT_AUTHOR_TIMESTAMP--git-refsVERSION 0.8 起启用注入EARTHLY_GIT_REFS。对应源码注入逻辑位于 variables/builtin.go当gitMeta非空时依次注入 hash、短 hash、分支、tag、origin URL、脱敏后的 origin URLEARTHLY_GIT_ORIGIN_URL_SCRUBBED用于安全地输出到日志、项目名与各时间戳当gitMeta为空未检测到 Git 目录时仅保证EARTHLY_SOURCE_DATE_EPOCH恒为0。EARTHLY_GIT_PROJECT_NAME的提取算法为getProjectName见 variables/builtin.go它剥离协议前缀http://、https://、ssh://等、剥离开头的user、去掉.git后缀并兼容gitgithub.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构建运行器的原生处理器架构。arm、amd64、arm64NATIVEOS构建运行器的原生操作系统。linuxNATIVEPLATFORM构建运行器的原生平台。linux/arm/v7、linux/amd64、darwin/arm64NATIVEVARIANT构建运行器的原生处理器架构变体。v7TARGETARCH目标 target 构建所面向的处理器架构。arm、amd64、arm64TARGETOS目标 target 构建所面向的操作系统。linuxTARGETPLATFORM目标 target 构建所面向的平台默认取原生平台。linux/arm/v7、linux/amd64、linux/arm64TARGETVARIANT目标 target 构建所面向的处理器架构变体。v7USERARCH用户调用earthly二进制的环境的处理器架构。arm、amd64、arm64USEROS用户调用earthly二进制的环境的操作系统。darwinUSERPLATFORM用户调用earthly二进制的环境的平台。darwin/amd64、linux/amd64、darwin/arm64USERVARIANT用户调用earthly二进制的环境的处理器架构变体。v7三个维度的含义TARGET目标target 实际构建运行所面向的平台决定产物形态。非LOCALLY时TARGETPLATFORM默认等于运行器的原生平台。NATIVE原生BuildKit 构建运行器的实际平台。启用--new-platformNewPlatform开关VERSION 0.7 起后才会注入 NATIVE 系列参数。USER用户执行earthly命令的本地环境平台与构建运行器可能是远程 BuildKit 或 Docker 容器平台不一定相同。对应的注入逻辑见 variables/builtin.goSetPlatformArgs基于平台解析器当前平台填充 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 --platformBUILD --platform linux/amd64 my-target3.FROM --platform指定基础镜像平台FROM --platform linux/amd64 alpine:3.13LOCALLY 下的特殊行为在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实现真正的多平台产物输出。六、内置参数的完整使用要点总结先声明后使用所有内置参数在使用前必须用ARG显式声明否则会报错。不可覆盖但可包装内置参数值永远不可被覆盖若需要可覆盖的默认值声明ARG X$BUILTIN形式的普通参数即可。受功能开关feature flags控制部分内置参数如 Git 作者系列、EARTHLY_GIT_REFS、NATIVE 平台系列依赖 VERSION 中的功能开关使用前需确认 Earthfile 的VERSION声明参考 features/features.go 中各开关的enabled_in_version。注意缓存影响EARTHLY_GIT_HASH、EARTHLY_GIT_SHORT_HASH随提交频繁变化会显著降低缓存命中率仅在确实需要唯一标识时使用。无 Git 上下文时的空值未检测到 Git 目录时所有 Git 相关参数为空字符串EARTHLY_SOURCE_DATE_EPOCH为0代码中需对空值做兜底。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),仅供参考