Bazel空定义变量未正确求值问题求助
问题分析
你遇到的核心问题有两个:
- 你定义的是Bazel宏(
def),而非规则,宏本身没有ctx上下文参数,因此直接传入ctx会触发参数缺失错误。 - 宏中硬编码的
"$(BRANCH_NAME)"是字符串字面量,不会被Bazel自动解析为--define设置的构建变量——宏在解析BUILD文件阶段执行,无法直接访问构建时的动态变量。
解决方案
以下提供两种可行的解决方式,根据你的需求选择:
方案一:修改宏的调用方式(最简单)
调整宏的定义,让它接收branch_name参数,然后在BUILD文件中通过$(BRANCH_NAME)传递已展开的变量值:
修改宏定义
load("@io_bazel_rules_docker//container:container.bzl", "container_push") def branch_aware_container_push(**kwargs): tag = kwargs.pop("tag", "latest") # 从参数中获取branch_name,默认空字符串 branch_name = kwargs.pop("branch_name", "") branch_aware_tag = f"{tag}-{branch_name}" if branch_name else tag container_push( tag = branch_aware_tag, **kwargs )
在BUILD文件中调用
branch_aware_container_push( name = "push_my_image", image = ":my_image", tag = "v1.0", # 传递Bazel展开后的BRANCH_NAME变量 branch_name = "$(BRANCH_NAME)", registry = "your-registry", repository = "your-image-repo", )
当--define BRANCH_NAME=时,$(BRANCH_NAME)会被Bazel展开为空字符串,最终tag为v1.0;如果设置--define BRANCH_NAME=main,tag会自动变为v1.0-main。
方案二:将宏改为Bazel规则(适合封装复杂构建逻辑)
如果需要无需用户传递参数,直接在逻辑中获取构建变量,可以将宏改为规则——规则的实现函数可通过ctx.var访问--define设置的变量:
定义规则
load("@io_bazel_rules_docker//container:container.bzl", "container_push") def _branch_aware_container_push_impl(ctx): tag = ctx.attr.tag or "latest" # 从构建变量中获取BRANCH_NAME,默认空字符串 branch_name = ctx.var.get("BRANCH_NAME", "") final_tag = f"{tag}-{branch_name}" if branch_name else tag # 调用container_push规则并传递所有必要参数 container_push( name = ctx.attr.name, tag = final_tag, image = ctx.attr.image, registry = ctx.attr.registry, repository = ctx.attr.repository, # 传递其他支持的属性 **{k: v for k, v in ctx.attr.items() if k not in ["name", "tag", "image", "registry", "repository"]} ) branch_aware_container_push = rule( implementation = _branch_aware_container_push_impl, attrs = { "tag": attr.string(default = "latest"), "image": attr.label(mandatory = True), "registry": attr.string(mandatory = True), "repository": attr.string(mandatory = True), # 根据需求添加container_push支持的其他属性 }, )
在BUILD文件中调用
branch_aware_container_push( name = "push_my_image", image = ":my_image", tag = "v1.0", registry = "your-registry", repository = "your-image-repo", )
这种方式不需要手动传递branch_name,规则会自动从--define BRANCH_NAME中获取值并处理tag。
内容的提问来源于stack exchange,提问作者Zar Ashouri
相关产品推荐
相关产品推荐

