关于 buildkite-agent-runtime
这是一份在 Buildkite 作业步骤中使用 `buildkite-agent` 二进制文件的技能指南,面向编写流水线自动化的开发者,涵盖构建注释、产物、作业间状态共享及运行时流水线管理。
主要功能
- 01创建构建注释
- 02上传、下载和搜索构建产物
- 03通过构建元数据共享状态
- 04生成并上传动态流水线步骤
- 05请求 OIDC 令牌并获取密钥
- 06管理步骤、锁和作业环境
适用场景
- 01在构建页面标注测试失败
- 02在同一构建的作业间传递值
- 03在运行时生成流水线步骤
- 04无需静态凭据即可向外部服务认证
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ buildkite/ skills --skill buildkite-agent-runtime安装后在 Claude Code 中输入/buildkite-agent-runtime确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/flag-reference.mdpatterns-and-recipes.md详细介绍
Buildkite Agent 运行时
buildkite-agent 二进制文件提供了一组子命令,可在运行中的作业步骤内与 Buildkite 交互,包括创建注释、上传构建产物、在作业之间共享状态、生成动态流水线、请求 OIDC 令牌等。本技能涵盖了所有作业内子命令的语法、标志和用法模式。
快速开始
一个步骤执行测试、为失败添加注释、上传覆盖率报告,并存储一个供下游作业读取的结果标记:
steps:
- label: ":test_tube: Tests"
command: |
if ! make test 2>&1 | tee test-output.txt; then
buildkite-agent annotate --style "error" --context "test-failures" < test-output.txt
buildkite-agent meta-data set "tests-passed" "false"
exit 1
fi
buildkite-agent annotate "All tests passed :white_check_mark:" --style "success" --context "test-results"
buildkite-agent artifact upload "coverage/**/*"
buildkite-agent meta-data set "tests-passed" "true"
下游步骤读取该状态:
- label: ":rocket: Deploy"
command: |
PASSED=$(buildkite-agent meta-data get "tests-passed")
if [[ "$PASSED" != "true" ]]; then
echo "Tests did not pass, skipping deploy"
exit 0
fi
scripts/deploy.sh
depends_on: "test-step"
注释
直接在构建页面上展示构建结果。注释支持 Markdown 和 HTML。
创建注释
# Simple text annotation
buildkite-agent annotate "Deploy completed successfully" --style "success" --context "deploy"
# Pipe from a file
buildkite-agent annotate --style "error" --context "test-failures" < test-output.md
关键标志
| 标志 | 短标志 | 默认值 | 说明 |
|---|---|---|---|
--style | -s | default | 视觉样式:default、info、warning、error、success |
--context | -c | random UUID | 唯一 ID——重复使用 context 会替换注释 |
--append | — | false | 追加到具有相同 context 的现有注释,而不是替换 |
--priority | — | 3 | 显示优先级(1-10)。数值越大,显示越靠前 |
--job | — | current job | 要添加注释的作业 ID(很少需要) |
替换与追加
- 使用相同的
--context且不加--append会替换注释;加上--append则会将内容追加到现有内容下方。 - 始终使用稳定的
--context值,以便重新运行时更新同一条注释,而不是创建重复项。
有关流水线级别的
notify:配置,请参阅 buildkite-pipelines 技能。
构建产物
将文件上传为构建产物,在后续步骤或其他构建中下载,并通过 glob 搜索。
上传
# Upload a single file
buildkite-agent artifact upload "pkg/release.tar.gz"
# Upload with glob pattern
buildkite-agent artifact upload "dist/**/*"
下载
# Download to current directory
buildkite-agent artifact download "pkg/release.tar.gz" .
# Download from a specific step
buildkite-agent artifact download "dist/*" . --step "build-step"
搜索
# List matching artifacts
buildkite-agent artifact search "pkg/*.tar.gz" --build "$BUILDKITE_BUILD_ID"
完整的标志表请参阅 references/flag-reference.md。
有关声明式
artifact_paths:YAML 键,请参阅 buildkite-pipelines 技能。有关bk artifactCLI 命令,请参阅 buildkite-cli 技能。
元数据
用于在作业之间共享状态的构建级键值存储。在一个作业中设置值,即可在同一构建中的其他任意作业中读取。
设置
buildkite-agent meta-data set "release-version" "1.4.2"
获取
VERSION=$(buildkite-agent meta-data get "release-version")
使用 --default 可在键缺失时返回回退值,而不是以非零状态退出:buildkite-agent meta-data get "deploy-env" --default "staging"。
检查是否存在
# Returns exit code 0 if exists, 100 if not
if buildkite-agent meta-data exists "release-version"; then
echo "Version already set"
fi
常见用法模式
Block 步骤字段值会自动存储为元数据。通过字段键获取:
# After a block step with fields: [{key: "release-name", text: "Release Name"}]
RELEASE_NAME=$(buildkite-agent meta-data get "release-name")
原始 webhook 负载可在由 webhook 触发的构建中使用,且会一直缓存到 webhook 数据过期。当自动化需要获取未提升为一等环境变量的字段(例如原始拉取请求评论正文)时,可读取特殊键 buildkite:webhook。
WEBHOOK="$(buildkite-agent meta-data get "buildkite:webhook")"
COMMENT_BODY="$(jq -r '.comment.body' <<< "$WEBHOOK")"
流水线上传
向正在运行的构建动态添加步骤。这是动态流水线的核心机制——在运行时生成 YAML 并上传。
基本用法
# Upload a specific file
buildkite-agent pipeline upload .buildkite/deploy-steps.yml
# Pipe generated YAML from stdin
./scripts/generate-pipeline.sh | buildkite-agent pipeline upload
替换模式
默认情况下,上传的步骤会追加到当前步骤之后。使用 --replace 可替换剩余的整个流水线:
# Replace all remaining steps with the uploaded ones
buildkite-agent pipeline upload --replace .buildkite/new-pipeline.yml
关键标志
| 标志 | 默认值 | 说明 |
|---|---|---|
--replace | false | 替换剩余的流水线步骤,而不是追加 |
--no-interpolation | false | 跳过上传的 YAML 中的环境变量插值 |
--dry-run | false | 验证并输出流水线,但不上传 |
有关流水线 YAML 语法和步骤类型,请参阅 buildkite-pipelines 技能。
OIDC 令牌
在作业步骤中请求短期 OpenID Connect 令牌,以便在不使用静态凭据的情况下向外部服务(云服务提供商、软件包注册表)进行身份验证。
基本令牌请求
# Request a token for a specific audience
TOKEN=$(buildkite-agent oidc request-token --audience "https://packages.buildkite.com/my-org/my-registry")
云服务提供商身份验证
# AWS — request token with STS audience
TOKEN=$(buildkite-agent oidc request-token --audience "sts.amazonaws.com")
关键标志
| 标志 | 默认值 | 描述 |
|---|---|---|
--audience | Buildkite endpoint | 目标服务 URL——必须与 OIDC 提供方的受众配置一致 |
--lifetime | 0(API 默认值) | 令牌有效期(秒)。为 0 或省略时,API 会选择默认有效期 |
--claim | — | 要包含的可选声明(例如 organization_id,pipeline_id)。可重复指定 |
--aws-session-tag | — | 要映射为 AWS 会话标签的声明。可重复指定 |
有关端到端 OIDC 身份验证流程、云提供商设置和令牌声明详情,请参阅 buildkite-secure-delivery 技能。
步骤管理
在运行时读取或修改步骤属性。适用于步骤中的条件逻辑和构建自动化。
获取步骤属性
# Get a step's label (--step is required)
LABEL=$(buildkite-agent step get "label" --step "$BUILDKITE_STEP_KEY")
# Get another step's state
STATE=$(buildkite-agent step get "state" --step "deploy-step")
# Get the entire step as JSON
buildkite-agent step get --step "test-step" --format json
更新步骤属性
# Update a step's label dynamically
buildkite-agent step update "label" ":rocket: Deploying v${VERSION}" --step "$BUILDKITE_STEP_KEY"
# Append to an existing label
buildkite-agent step update "label" " (retried)" --step "build-step" --append
取消步骤
# Cancel all unfinished jobs for a step
buildkite-agent step cancel --step "optional-step"
# Force-cancel a running step
buildkite-agent step cancel --step "stuck-step" --force
关键标志
| 标志 | 默认值 | 描述 |
|---|---|---|
--step | — | 要操作的步骤键或 UUID(必需——若已设置 $BUILDKITE_STEP_ID 环境变量,则使用该变量) |
--build | 当前构建 | 构建 UUID(用于跨构建操作) |
--format | — | get 的输出格式(复杂属性请使用 json) |
--append | false | 追加到现有值,而非替换(仅适用于 step update) |
--force | false | 即使步骤正在运行也强制取消(仅适用于 step cancel) |
分布式锁
使用分布式互斥锁协调构建中的并行作业。在多个作业访问共享资源时防止竞态条件。
获取 / 释放模式
#!/bin/bash
set -euo pipefail
# Acquire lock — blocks until available, returns a token
token=$(buildkite-agent lock acquire "database-migration")
trap 'buildkite-agent lock release "database-migration" "${token}"' EXIT
# Critical section — only one job runs this at a time
bundle exec rails db:migrate
do / done 模式(一次性设置)
在所有并行作业中恰好运行一次设置任务:
#!/bin/bash
echo "+++ Setting up shared test environment"
if [[ $(buildkite-agent lock do "test-env-setup") == "do" ]]; then
echo "Downloading test assets..."
curl -o /tmp/test-data.zip https://releases.example.com/data.zip
unzip /tmp/test-data.zip -d /tmp/shared-test-files/
buildkite-agent lock done "test-env-setup"
else
echo "Assets already prepared by another job"
fi
# All jobs continue here
run-tests.sh
关键标志
| 子命令 | 标志 | 描述 |
|---|---|---|
lock acquire <name> | --lock-wait-timeout | 最大等待时长(例如 30s、5m)。默认:无限等待 |
lock release <name> <token> | — | 使用 acquire 返回的令牌释放锁 |
lock do <name> | — | 如果获取了锁,则返回 do;如果已完成,则返回 done |
lock done <name> | — | 将 do 锁标记为已完成 |
环境
检查和修改作业的环境变量。主要用于调试生命周期钩子,以及了解钩子对环境所做的更改。
# Dump all environment variables as JSON
buildkite-agent env dump | jq .
# Get a specific variable
buildkite-agent env get "BUILDKITE_BRANCH"
# Set variables for subsequent hooks and the command (KEY=value format)
buildkite-agent env set DEPLOY_TARGET=production "APP_NAME=My App"
关键标志
| 子命令 | 描述 |
|---|---|
env dump | 转储所有环境变量(默认采用 JSON 格式) |
env get <keys...> | 获取一个或多个指定变量。使用 --format 设置输出格式(plain、json、json-pretty) |
env set KEY=value [...] | 为后续阶段设置变量。可接受多个 KEY=value 对 |
env unset <key> | 从后续阶段移除变量 |
调试钩子
env dump 命令特别适用于在生命周期钩子中查看之前的钩子做了哪些更改:
#!/bin/bash
# .buildkite/hooks/pre-command
echo "--- Environment after environment hook:"
buildkite-agent env dump | jq 'keys'
有关 Agent 生命周期钩子和
buildkite-agent.cfg配置,请参阅 Agent 钩子和 Agent 配置文档。
密钥
在作业步骤中运行时从集群获取密钥。通过此方式获取的密钥会自动添加到日志脱敏器中。
基本用法
# Get a secret value
SECRET_VAR=$(buildkite-agent secret get "deploy-key")
# Pass directly to a tool
cli-tool --token "$(buildkite-agent secret get "api-token")"
关键标志
| 标志 | 默认值 | 描述 |
|---|---|---|
--format | default | 输出格式:default(单个密钥时打印值,多个密钥时打印 JSON)、json 或 env(KEY="value" 键值对) |
--skip-redaction | false | 不将密钥值添加到日志脱敏器中 |
--job | 当前作业 | 作业 ID 上下文 |
可一次请求多个密钥:buildkite-agent secret get KEY1 KEY2 KEY3。
默认情况下,secret get 会自动将检索到的值注册到日志脱敏器中,在后续输出中将其屏蔽为 [REDACTED]。
有关设置集群密钥的信息,请参阅 Buildkite Secrets 文档。有关声明式的
secrets:流水线 YAML 键,请参阅 buildkite-pipelines 技能。
日志脱敏
在运行时将值添加到构建日志脱敏器中,以便在所有后续输出中屏蔽这些值。对于通过 secrets: 或 buildkite-agent secret get 未声明的动态检索密钥,请使用此功能。
基本用法
# Fetch a token from an external source
DYNAMIC_TOKEN=$(curl -s https://vault.example.com/token)
# Register it with the redactor before using it
echo "$DYNAMIC_TOKEN" | buildkite-agent redactor add
# Now any log output containing the token value shows [REDACTED]
echo "Using token: $DYNAMIC_TOKEN"
# Output: Using token: [REDACTED]
多个值
# Redact multiple values
echo "$SECRET1" | buildkite-agent redactor add
echo "$SECRET2" | buildkite-agent redactor add
何时使用脱敏器,何时使用 secret get
| 场景 | 使用方式 |
|---|---|
| 密钥存储在 Buildkite 集群密钥中 | buildkite-agent secret get(自动脱敏) |
| 密钥来自外部保险库(HashiCorp Vault、AWS SSM 等) | 从外部获取,然后运行 buildkite-agent redactor add |
| 计算得出的敏感值(临时令牌、派生密钥) | buildkite-agent redactor add |
工具签名
对流水线 YAML 进行签名,以便 Agent 在执行步骤前验证其完整性。tool sign 命令接收流水线文件(而非单个步骤),并为其添加签名。
对文件中的流水线进行签名
# Sign a pipeline YAML file using a local JWKS key
buildkite-agent tool sign pipeline.yml \
--jwks-file /path/to/private-key.json \
--repo "[email protected]:org/repo.git"
通过 GraphQL API 签名
# Retrieve, sign, and update a pipeline via the Buildkite GraphQL API
buildkite-agent tool sign \
--graphql-token "$BUILDKITE_GRAPHQL_TOKEN" \
--organization-slug my-org \
--pipeline-slug my-pipeline \
--jwks-file /path/to/private-key.json \
--update
生成签名密钥对
# Generate a new JWS key pair (private + public JWKS files)
buildkite-agent tool keygen
关键标志
| 命令 | 标志 | 描述 |
|---|---|---|
tool sign | --jwks-file | 用于签名的 JWKS 私钥文件路径 |
tool sign | --jwks-key-id | 要从 JWKS 文件中使用的密钥 ID |
tool sign | --repo | 仓库 URL(从文件进行签名时必需) |
tool sign | --signing-aws-kms-key | 用于签名的 AWS KMS 密钥 ID(JWKS 的替代方案) |
tool sign | --signing-gcp-kms-key | 用于签名的 GCP KMS 密钥 ID(JWKS 的替代方案) |
tool sign | --graphql-token | 通过 GraphQL API 检索或更新流水线的令牌 |
tool sign | --update | 签名后在 Buildkite 中更新流水线(需要 --graphql-token) |
tool keygen | --alg | JWS 签名算法(默认值:EdDSA) |
tool keygen | --key-id | 生成的密钥对的密钥 ID(默认值:随机) |
注意: 没有
tool verify命令。Agent 收到作业时会在内部处理签名验证。
有关流水线签名配置和推出策略,请参阅 buildkite-secure-delivery 技能。
常见错误
| 错误 | 结果 | 修复方法 |
|---|---|---|
在 annotate 中缺少 --context | 每次调用都会创建新的注释,而不是更新现有注释 | 始终传入 --context,并使用稳定的标识符 |
使用 --append 时未匹配 --context | 追加无效——会创建新的注释 | 确保 --context 与要追加内容的注释相匹配 |
| 忘记为制品 glob 模式加引号 | Shell 会在 buildkite-agent 读取前展开 glob | 始终加引号:"dist/**/*",而不是 dist/**/* |
在写入任务完成前读取 meta-data get | 键不存在,命令会以非零状态码退出 | 使用 depends_on 或 wait 强制执行顺序,或使用 --default |
无意中使用 pipeline upload --replace | 会移除构建中剩余的所有步骤 | 仅在有意重建整个流水线时使用 --replace |
| 脚本失败时未释放锁 | 锁会一直被持有,阻止其他任务运行 | 使用 trap ... EXIT,确保在任何退出时释放锁 |
传入的 --audience 与 OIDC 提供商配置不匹配 | 目标服务会拒绝令牌 | Audience 必须与提供商配置的 audience URL 完全一致 |
使用 --skip-redaction 处理实际机密 | 机密值会以明文形式出现在构建日志中 | 仅对非敏感配置值使用 --skip-redaction |
调用 env set 并期望它影响当前 Shell | 变量只会对后续钩子或阶段生效,不会影响当前脚本 | 当前脚本的变量使用 export VAR=value;跨阶段变量使用 env set |
| 通过环境变量传递大型值 | 操作系统级别的环境变量大小限制会导致静默截断或任务失败 | 对于大于几 KB 的负载,改用基于文件的方式(制品、包含文件的 meta-data) |
在关闭 --no-interpolation 的模式下上传含有未转义 $ 的流水线 YAML | 变量会被意外插值,导致 YAML 格式错误 | 当 YAML 包含字面量 $ 字符时,使用 --no-interpolation |
其他资源
参考文件
references/flag-reference.md— 所有子命令的完整标志表,包括 upload、download、search、shasum、annotate、meta-data、pipeline upload、oidc、step、lock、env、secret、redactor 和 toolreferences/patterns-and-recipes.md— 高级多子命令模式:测试失败注释流水线、跨任务状态机、经过 OIDC 身份验证的 Docker 推送、使用锁协调并行任务、环境调试