mcpField
B
buildkite-pipelines

buildkite-pipelines

github.com/buildkite云与 DevOps18250 次安装2 周前更新
代码仓库

关于 buildkite-pipelines

buildkite-pipelines 是编写、优化和排查 Buildkite 流水线 YAML 的技能,涵盖常见流水线结构及进阶执行方式,适用于维护 CI/CD 工作流的团队。

主要功能

  1. 01流水线步骤类型与依赖关系
  2. 02缓存、并行执行与矩阵构建
  3. 03注释、重试与制品
  4. 04动态生成流水线
  5. 05故障排查与常见错误

适用场景

  1. 01定义测试与部署步骤
  2. 02减少重复安装依赖
  3. 03并行运行测试任务
  4. 04根据仓库状态生成步骤

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/buildkite/skills --skill buildkite-pipelines

安装后在 Claude Code 中输入/buildkite-pipelines确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
examples/
basic-pipeline.yml
optimized-pipeline.yml
references/
advanced-patterns.md
dynamic-pipeline-patterns.md
dynamic-pipeline-troubleshooting.md
group-steps.md
retry-and-error-codes.md
step-types-reference.md

详细介绍

Buildkite 流水线

流水线 YAML 是 Buildkite CI/CD 的核心。本技能介绍如何编写、优化和排查 .buildkite/pipeline.yml——步骤类型、缓存、并行、注释、重试、动态流水线、矩阵构建、插件、通知、制品和并发。

快速开始

在仓库根目录创建 .buildkite/pipeline.yml:

steps:
  - label: ":hammer: Tests"
    command: "npm test"
    artifact_paths: "coverage/**/*"

  - wait

  - label: ":rocket: Deploy"
    command: "scripts/deploy.sh"
    branches: "main"

在 Buildkite 中将流水线的初始命令设置为上传此文件:

steps:
  - label: ":pipeline: Upload"
    command: buildkite-agent pipeline upload

Agent 会读取 .buildkite/pipeline.yml,并将步骤上传到 Buildkite 执行。

Buildkite 默认会查找 .buildkite/pipeline.yml。使用 buildkite-agent pipeline upload path/to/other.yml 可指定其他路径。

如需通过编程方式创建流水线,请参阅 buildkite-api 技能。 如需设置 Agent 和队列,请参阅队列文档。

步骤类型

类型用途最简语法
command运行 shell 命令- command: "make test"
wait等待所有先前步骤通过- wait
block暂停以等待人工批准- block: ":shipit: Release"
trigger在另一个流水线上启动构建- trigger: "deploy-pipeline"
group将步骤归为一组(可折叠)- group: "Tests",并嵌套 steps:
input继续前收集用户输入- input: "Release version",并附带 fields:

有关每种步骤类型的详细属性和高级示例,请参阅 references/step-types-reference.md。

缓存

缓存依赖项是效果最显著的优化。使用基于清单失效的缓存插件:

steps:
  - label: ":nodejs: Test"
    command: "npm ci && npm test"
    plugins:
      - cache#v1.8.1:
          paths:
            - "node_modules/"
          manifest: "package-lock.json"

缓存键根据清单文件的哈希值生成。当 package-lock.json 发生变化时,缓存会重新构建。

托管 Agent 还支持内置的 cache 键(无需插件):

steps:
  - label: ":nodejs: Test"
    command: "npm ci && npm test"
    cache:
      paths:
        - "node_modules/"
      key: "v1-deps-{{ checksum 'package-lock.json' }}"

如需了解托管 Agent 的设置和实例规格,请参阅 Buildkite 托管 Agent 文档。

快速失败和非阻塞步骤

在任何作业失败时立即取消其余作业:

steps:
  - label: ":rspec: Tests"
    command: "bundle exec rspec"
    cancel_on_build_failing: true

对于不应阻塞构建的步骤(安全扫描、代码检查、覆盖率),请使用 soft_fail:

steps:
  - label: ":shield: Security Scan"
    command: "scripts/security-scan.sh"
    soft_fail:
      - exit_status: 1

软失败的步骤会在 UI 中显示为警告,但不会导致构建失败。在 wait 步骤上搭配 continue_on_failure: true,即可让下游步骤无论如何都继续运行。

并行和依赖关系

并行执行

默认情况下,同一级别的步骤会并行运行。使用 parallelism 将单个步骤拆分执行:

steps:
  - label: ":rspec: Tests %n"
    command: "bundle exec rspec"
    parallelism: 10

这会创建 10 个并行作业。每个作业都会收到 BUILDKITE_PARALLEL_JOB(0-9)和 BUILDKITE_PARALLEL_JOB_COUNT(10)环境变量,以便拆分工作。

如需根据计时数据智能拆分测试,请参阅 buildkite-test-engine 技能。

显式依赖关系

使用 depends_on 声明步骤级依赖关系,无需使用 wait:

steps:
  - label: "Build"
    key: "build"
    command: "make build"

  - label: "Unit Tests"
    depends_on: "build"
    command: "make test-unit"

  - label: "Integration Tests"
    depends_on: "build"
    command: "make test-integration"

构建完成后,单元测试和集成测试会并行运行,无需 wait 步骤。

注释

使用 buildkite-agent annotate 在构建页面上直接显示构建结果。支持 Markdown 和 HTML。

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
        exit 1
      fi
      buildkite-agent annotate "All tests passed :white_check_mark:" --style "success" --context "test-results"
标志默认值说明
--styledefault视觉样式:default、info、warning、error、success
--contextrandom唯一 ID——重复使用同一 context 会替换注释
--appendfalse将内容追加到具有相同 context 的现有注释

在注释中链接已上传的制品:

- command: |
    buildkite-agent artifact upload "coverage/*"
    buildkite-agent annotate --style "info" 'Coverage: <a href="artifact://coverage/index.html">view report</a>'

重试

自动重试

根据退出状态重试暂时性失败:

steps:
  - label: ":hammer: Build"
    command: "make build"
    retry:
      automatic:
        - exit_status: -1    # Agent lost
          limit: 2
        - exit_status: 143   # SIGTERM (spot instance termination)
          limit: 2
        - exit_status: 255   # Timeout or SSH failure
          limit: 2
        - exit_status: "*"   # Any non-zero exit
          limit: 1
手动重试

控制是否允许手动重试:

retry:
  manual:
    allowed: false
    reason: "Deployment steps cannot be retried"

如需完整的退出代码表和重试策略建议,请参阅 references/retry-and-error-codes.md。

动态流水线

根据仓库状态在运行时生成流水线步骤。使用 buildkite-agent pipeline upload 上传生成的 YAML:

steps:
  - label: ":pipeline: Generate"
    command: |
      .buildkite/generate-pipeline.sh | buildkite-agent pipeline upload
何时使用哪种方式

流水线方案各不相同。选择能满足需求的最简单选项:

情况方案
每次构建的步骤相同,最多只需按分支筛选静态 YAML
在组织范围内强制执行流水线结构,由管理员控制(Enterprise 计划)流水线模板
在多个流水线间共享可复用且经过审核的逻辑(缓存、Docker、制品传输)固定版本的插件
特定文件未更改时跳过步骤if_changed
每个服务拥有独立流水线的单体仓库monorepo-diff 插件
通过 OR 逻辑组合 if 和 if_changed动态生成
在多个流水线间统一应用重试 / 超时 / 环境配置动态生成(共享配置)
在运行时计算测试分片、矩阵组合、parallelism × matrix动态生成(通常使用 SDK)
服务间存在传递依赖的单体仓库动态生成(自定义依赖图)
从基础设施故障中恢复(OOM → 更大的 Agent)动态生成(pre-exit 钩子)
步骤依赖前序步骤的输出(多阶段)动态生成,通常使用 --replace 或链式上传
无论前序步骤是否失败都必须运行的清理 / 拆除步骤动态生成(pre-exit 上传收尾步骤)
仅在主步骤失败时运行的回退步骤动态生成(pre-exit 检查退出状态)
流水线 YAML 已超出团队的维护能力动态生成(使用 Python / TS / Go / Ruby SDK)
不要为不合适的任务使用动态流水线

当步骤本身需要改变时,动态生成才是合适的工具。要在步骤间传递数据,有更简单的基本工具:

  • buildkite-agent meta-data set/get — 任何后续步骤都能在同一构建中读取的小型键值对(版本字符串、提交 SHA、功能标志)。
  • 制品 — 在步骤间传递的文件(buildkite-agent artifact upload/download)。
  • 触发步骤 env: — 传递给其他流水线中构建的环境变量。

如果只需要传递数据,使用元数据或制品更简单、更安全。请参阅 buildkite-agent-runtime 技能。

引导脚本

生成器脚本始终以 set -euo pipefail 开头。 如果没有 pipefail,pipeline upload 失败时会返回管道中最后一个命令的退出代码,构建步骤会报告成功,而且不会出现任何生成的步骤——这是动态流水线最常见的故障模式。

下面是一个仅对已更改服务运行测试的生成器示例:

#!/bin/bash
set -euo pipefail
CHANGED=$(git diff --name-only HEAD~1)
cat <<YAML
steps:
YAML
for dir in services/*/; do
  svc=$(basename "$dir")
  if echo "$CHANGED" | grep -q "^services/$svc/"; then
    cat <<YAML
  - label: ":test_tube: $svc"
    command: "cd services/$svc && make test"
    key: "test-$svc"
YAML
  fi
done

为每个生成的步骤设置 key:。它可启用 depends_on,使重试具备幂等性(如果上传步骤重新运行,DuplicateKeyError 会阻止静默重复),并为不同构建提供稳定的标识符。推送前,请使用 buildkite-agent pipeline upload --dry-run 在本地验证。

每次上传不超过 500 个步骤,每次构建不超过 4,000 个作业(平台默认值,可通过支持渠道申请提高)。对于规模更大的单体仓库,请使用触发步骤将任务分散到多个独立构建中。

对于需要类型检查且可进行单元测试的生成器,Buildkite SDK 支持 JavaScript/TypeScript、Python、Go 和 Ruby。生成器产生约 10 个以上的步骤后,请将相关步骤封装在分组步骤中——添加任意分组都会为构建启用 DAG 模式,而且分组不接受 concurrency 属性(请参阅 references/group-steps.md)。

生成器步骤还可以读取运行时状态(元数据、制品、git diff)并上传流水线的下一阶段——这是多阶段构建使用的处理器模式。关于此模式、扇出 / 扇入,以及通过 pre-exit 钩子实现的收尾 / 始终运行步骤,请参阅 references/dynamic-pipeline-patterns.md。关于故障模式,请参阅 references/dynamic-pipeline-troubleshooting.md。关于高级生成器模式(Python、单体仓库、多阶段),请参阅 references/advanced-patterns.md。

条件执行

步骤级条件

使用 if 根据构建状态有条件地运行步骤:

steps:
  - label: ":rocket: Deploy"
    command: "scripts/deploy.sh"
    if: build.branch == "main" && build.message !~ /\[skip deploy\]/

如需查看完整的条件表达式列表,请参阅条件表达式。

[skip ci] 注意事项: Buildkite 只会检查 HEAD 提交消息中的 [skip ci] / [ci skip]。如果这个标记位于一次多提交推送中的较早提交里,构建仍会触发。

基于目录的步骤筛选(if_changed)

如果相关文件没有更改,则跳过步骤。仅在上传流水线时由 Buildkite agent 应用。请参阅 https://buildkite.com/docs/pipelines/configure/dynamic-pipelines/if-changed.md。

steps:
  - label: ":nodejs: Frontend tests"
    command: "npm test"
    if_changed:
      - "src/frontend/**"
      - "package.json"

有关排除模式和单体仓库配置,请参阅 references/advanced-patterns.md。

对于大型单体仓库,可使用 Sparse Checkout 插件,仅为上传步骤检出 .buildkite/,从而大幅加快流水线上传速度。

有条件地运行插件

步骤级 if 不会阻止插件执行。将步骤包装在 group 中即可完全跳过插件:

steps:
  - group: ":docker: Build"
    if: build.env("DOCKER_PASSWORD") != null
    steps:
      - label: "Build image"
        command: "docker build -t myapp ."
        plugins:
          - docker-login#v2.1.0:
              username: myuser
              password-env: DOCKER_PASSWORD

矩阵构建

在多个配置下运行相同的步骤:

steps:
  - label: "Test {{matrix.ruby}} on {{matrix.os}}"
    command: "bundle exec rake test"
    matrix:
      setup:
        ruby:
          - "3.2"
          - "3.3"
        os:
          - "ubuntu"
          - "alpine"
      adjustments:
        - with:
            ruby: "3.2"
            os: "alpine"
          skip: true  # Known incompatible

每个 adjustments 条目中有效的属性:with、skip、soft_fail、env。agents: 键在 adjustments 中无效——Buildkite 会拒绝该流水线,并提示“agents is not a valid property on the matrix.adjustments configuration”。若要将矩阵组合路由到不同队列(例如,Linux 与 Windows agent),请使用单独的步骤或动态流水线生成器。

插件

通过 3 行 YAML 块添加功能。固定版本以确保可复现:

plugins:
  - docker-compose#v5.5.0:
      run: app
      config: docker-compose.ci.yml
插件用途
cache#v1.8.1基于清单失效机制的依赖缓存
docker#v5.12.0在 Docker 容器内运行步骤
docker-compose#v5.5.0使用 Docker Compose 构建和运行
artifacts#v1.9.4在步骤之间下载制品
test-collector#v2.0.0将测试结果上传到 Test Engine

始终固定插件版本(例如,使用 docker#v5.12.0,而不是 docker#v5)。如果插件发布了新的主版本,未固定版本可能会导致构建失败。

对于组织内部的私有插件,请使用完整的 Git URL——简写语法仅适用于公开插件:

plugins:
  - ssh://[email protected]/my-org/my-plugin.git#v1.0.0:
      config: value

通知和制品

在 steps: 上方添加流水线级别的 notify:,即可在构建状态发生变化时发送 Slack、电子邮件或 Webhook 通知。语法请参阅通知。

制品上传和下载

从步骤上传制品,并在后续步骤中下载:

steps:
  - label: "Build"
    command: "make build"
    artifact_paths: "dist/**/*"

  - wait

  - label: "Package"
    command: |
      buildkite-agent artifact download "dist/*" .
      make package

在 Docker 构建中使用制品时,请在开始 Docker 构建前下载制品,因为容器内无法使用 buildkite-agent:

steps:
  - label: "Docker build"
    command: |
      buildkite-agent artifact download "dist/*" .
      docker build -t myapp .

并发

限制共享资源的步骤并行执行数量。务必将 concurrency 与 concurrency_group 配对使用——如果没有组名,限制会被静默忽略。

steps:
  - label: ":rocket: Deploy"
    command: "scripts/deploy.sh"
    concurrency: 1
    concurrency_group: "deploy/production"
    concurrency_method: "eager"

对于部署等彼此独立的作业,使用 concurrency_method: "eager"(下一个可用项)。如果执行顺序很重要,则使用默认值 "ordered"(FIFO)。设置 priority(默认为 0,数值越高优先级越高)以控制接下来运行哪些排队作业。

如需查看完整的并发配置选项,请参阅控制并发。

如需了解如何从终端触发、监控和调试流水线,请参阅 buildkite-cli 技能。

常见错误

错误结果修复方法
依赖步骤之间缺少 wait步骤会并行运行,第二个步骤会因第一个步骤尚未完成而失败添加 - wait,或使用 depends_on:
所有依赖关系都只使用 wait 步骤虽然有效,但不符合惯例;wait 会阻塞所有先前的步骤,导致无法并行运行互不依赖的步骤为命名步骤设置 key:,并使用 depends_on: "key" 表达细粒度依赖;仅在需要无条件屏障时使用 wait
包安装步骤所在的流水线没有 plugins:每次构建都会从头重新安装依赖,拖慢构建并增加成本添加 cache 插件(或为托管 Agent 使用内置的 cache: 键),缓存 node_modules/、.gradle/ 等目录。请参阅上文的缓存部分
使用步骤级别的 if 跳过插件插件仍会执行(它们会在评估 if 之前运行)将步骤放入带有 if 条件的 group 中
未固定插件版本插件发布了含有破坏性更改的版本时,构建会失败始终使用完整的 semver:plugin#v1.2.3
在使用 concurrency 时忘记设置 concurrency_group未指定组名时,concurrency 会被忽略始终将 concurrency 与 concurrency_group 配合使用
artifact_paths glob 与输出不匹配工件不会上传,且不会显示任何提示,下游步骤会失败在本地测试 glob 模式;嵌套目录使用 **/*
将并行作业拆分逻辑硬编码测试分配不均,一个缓慢的作业会阻塞构建使用 parallelism: N,通过 Test Engine 按耗时拆分
在流水线 YAML 中内联机密机密会显示在构建日志和 Buildkite UI 中使用集群机密或 Agent 环境钩子
将 retry.automatic 与 exit_status: "*" 和较高的限制值配合使用真正的错误会被反复重试,浪费计算资源指定特定的退出代码;将通配符限制值保持为 1
在 matrix.adjustments 内使用 agents:流水线上传失败:"agents is not a valid property on the matrix.adjustments configuration"从 adjustments 中移除 agents:;为每个平台使用单独的步骤,或使用动态流水线生成器来按组合路由到队列
构建失败,但所有可见步骤都已通过某个触发步骤启动的子流水线失败了,或者某个步骤被取消而非解除阻塞检查被触发流水线的构建状态;检查阻塞步骤是否被取消
流水线上传失败,且没有明确错误信息YAML 语法错误或 Agent 端的问题未显示在构建日志中在本地验证 YAML;在主机上检查 Agent 日志,查找详细的上传错误;运行 buildkite-agent pipeline upload --debug
在公共流水线上启用来自分支的构建贡献者可以修改 pipeline.yml 来窃取机密对公共仓库,在流水线设置中禁用来自分支的构建;为外部 PR 使用没有机密访问权限的单独流水线
Docker Compose 步骤生成了工件,但 Agent 找不到在容器内创建的文件对主机 Agent 不可见在 docker-compose.yml 中将工作目录挂载为卷,以便容器输出可供 artifact_paths: 使用
动态流水线生成了 1000+ 个步骤UI 变慢,流水线处理性能下降将生成的流水线控制在约 500 个步骤以内;对于更大的单体仓库,使用带有触发步骤的编排流水线

其他资源

参考文件
  • references/step-types-reference.md — 所有步骤类型的详细属性表
  • references/advanced-patterns.md — 动态流水线生成器、矩阵调整、monorepo 模式、多阶段流水线
  • references/retry-and-error-codes.md — 全面的退出代码表、按故障类型划分的重试策略
  • references/group-steps.md — 分组步骤属性、DAG 模式、跨上传合并、不嵌套的变通方案、对作业数量上限的影响
  • references/dynamic-pipeline-troubleshooting.md — 静默上传失败、配额限制、环境变量插值、重试时重复、重试风暴
  • references/dynamic-pipeline-patterns.md — 扇出/扇入、SDK 生成、处理程序模式、最终处理步骤、基于触发器的扇出
示例
  • examples/basic-pipeline.yml — 最简可运行流水线(测试、等待、部署)
  • examples/optimized-pipeline.yml — 功能齐全的流水线,包含缓存、并行处理、注释、重试、工件和通知

如需从其他 CI 系统迁移流水线,请参阅 buildkite-migration 技能。

延伸阅读

评论

支持 Markdown