You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bazel规则开发:如何处理认证令牌TTL及强制步骤重构建?

解决Bazel中认证令牌缓存过期问题

方法一:强制每次构建重新执行令牌获取步骤

如果你不需要精确的TTL控制,只是想确保每次构建都重新获取令牌,可以通过让目标依赖一个动态变化的伪输入文件,强制Bazel重新执行该步骤。

1. 定义生成动态时间戳的规则

创建一个always_run.bzl文件,实现生成当前时间戳文件的规则:

def _always_run_impl(ctx):
    out_file = ctx.actions.declare_file(ctx.label.name)
    ctx.actions.run_shell(
        outputs = [out_file],
        command = "date +%s > %s" % (out_file.path),
    )
    return [DefaultInfo(files = depset([out_file]))]

always_run = rule(
    implementation = _always_run_impl,
    outputs = {"": "%{name}"},
)

2. 在BUILD文件中使用该规则

将时间戳文件作为令牌获取步骤的输入,确保每次构建都触发重新执行:

load("//:always_run.bzl", "always_run")

# 生成每次构建都变化的时间戳文件
always_run(name = "build_timestamp")

# 获取令牌的genrule,依赖时间戳文件
genrule(
    name = "fetch_auth_token",
    srcs = [":build_timestamp"],
    outs = ["auth_token.txt"],
    cmd = """
        # 替换为你的令牌获取逻辑
        curl -s "https://your-auth-endpoint/token" > $@
    """,
)

替代方案:使用执行要求禁用缓存

对于自定义规则,可在ctx.actions.run中设置execution_requirements直接禁用缓存:

def _fetch_token_impl(ctx):
    out_token = ctx.actions.declare_file(ctx.label.name + ".txt")
    ctx.actions.run(
        outputs = [out_token],
        executable = ctx.executable._fetch_script,
        arguments = [out_token.path],
        execution_requirements = {
            "no-cache": "true",  # 禁用本地缓存
            "no-remote-cache": "true",  # 禁用远程缓存
        },
    )
    return [DefaultInfo(files = depset([out_token]))]

fetch_token = rule(
    implementation = _fetch_token_impl,
    executable = "_fetch_script",
    attrs = {
        "_fetch_script": attr.label(
            executable = True,
            default = Label("//scripts:fetch_token.sh"),
            cfg = "exec",
        ),
    },
)

方法二:基于TTL的令牌复用(近似实现)

Bazel本身没有原生支持TTL缓存失效,但可以通过脚本逻辑结合时间戳输入,实现近似的TTL控制:

1. 编写带过期检查的令牌获取脚本

创建scripts/fetch_token.sh,在脚本中检查现有令牌是否过期,未过期则复用,过期则重新获取:

#!/bin/bash
TOKEN_FILE="$1"
EXPIRY_FILE="${TOKEN_FILE}.expiry"
TOKEN_TTL=3600  # 令牌有效期,单位:秒(示例为1小时)

# 检查现有令牌是否有效
if [ -f "$TOKEN_FILE" ] && [ -f "$EXPIRY_FILE" ]; then
    CURRENT_TIME=$(date +%s)
    EXPIRY_TIME=$(cat "$EXPIRY_FILE")
    if [ "$CURRENT_TIME" -lt "$EXPIRY_TIME" ]; then
        echo "Using existing valid token"
        exit 0
    fi
fi

# 令牌过期,重新获取
echo "Fetching new token..."
NEW_TOKEN=$(curl -s "https://your-auth-endpoint/token")
if [ -z "$NEW_TOKEN" ]; then
    echo "Failed to fetch token" >&2
    exit 1
fi

# 保存令牌和过期时间
echo "$NEW_TOKEN" > "$TOKEN_FILE"
echo $(( $(date +%s) + TOKEN_TTL )) > "$EXPIRY_FILE"

2. 在Bazel规则中使用该脚本

依赖一个按TTL频率更新的时间戳文件(比如每小时更新一次),确保在令牌过期后触发重新执行:

# 生成每小时变化的时间戳文件(匹配令牌TTL)
always_run(name = "hourly_timestamp", cmd = "date +%H > %s")

genrule(
    name = "fetch_token_with_ttl",
    srcs = [":hourly_timestamp"],
    outs = ["auth_token.txt"],
    cmd = "$(location //scripts:fetch_token.sh) $@",
    tools = ["//scripts:fetch_token.sh"],
)

针对仓库级令牌的处理(WORKSPACE中)

如果令牌是在仓库初始化阶段获取的,可使用repository_rule结合本地执行逻辑实现TTL检查:

def _token_repo_impl(ctx):
    import time
    token_path = ctx.path("auth_token.txt")
    expiry_path = ctx.path("token_expiry.txt")
    ttl = 3600  # 1小时有效期

    # 检查令牌是否有效
    if token_path.exists and expiry_path.exists:
        with open(expiry_path, "r") as f:
            expiry = int(f.read().strip())
        if time.time() < expiry:
            ctx.file("BUILD.bazel", 'exports_files(["auth_token.txt"])')
            return

    # 重新获取令牌
    result = ctx.execute(["curl", "-s", "https://your-auth-endpoint/token"])
    if result.return_code != 0:
        fail("Failed to fetch auth token")
    token = result.stdout.strip()
    expiry = int(time.time()) + ttl

    # 保存令牌和过期时间
    ctx.file("auth_token.txt", token)
    ctx.file("token_expiry.txt", str(expiry))
    ctx.file("BUILD.bazel", 'exports_files(["auth_token.txt"])')

token_repo = repository_rule(
    implementation = _token_repo_impl,
    local = True,  # 允许访问本地文件和系统时间
)

在WORKSPACE中调用:

token_repo(name = "my_auth_token")

内容的提问来源于stack exchange,提问作者Ibolit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 17:20:27