基于 llms-full.txt 中 .cnb.yml / CNB 流水线规则实现的 Go 本地执行器。用于在本地环境中模拟和调试 CNB CI/CD 流水线,无需依赖 CNB 平台即可验证流水线配置的正确性。
.cnb.yml 配置格式include 指令:支持字符串、对象、config 内联形式,智能合并策略
!reference 跨文件引用,最多递归 10 层<<$ fallbackstages 串行执行jobs:
retry 重试机制allowFailure 允许失败lock 本进程内锁控制failStages / endStages 流程控制exit 78 中断流水线env / imports 环境变量注入imports 支持 YAML / JSON / key=value / 证书文件$VAR / ${VAR} 变量替换exports 导出后续 Job 可见的环境变量##[set-output key=value] 输出pipeline.docker.image 全局镜像配置pipeline.docker.build Docker 构建支持
versionBy + buildArgs 计算本地缓存 tagby 控制 build context 可见文件stage.image / job.image 层级镜像覆盖settings 转为 PLUGIN_* 环境变量docker.volumes 基础映射与 copy-on-write 模式cnb:await - 等待异步任务完成cnb:resolve - 解析异步任务结果cnb:read-file - 读取文件内容cnb:destroy-token - 销毁认证令牌(本地近似实现)cnb:apply - 同仓本地递归触发cnb:trigger - 触发其他流水线(当前仓本地近似实现)docker:cache - Docker 缓存管理(noop 占位)cnbexec/ ├── cnbexec.go # 公共 API 入口 ├── cmd/cnbexec/ # CLI 命令行工具 ├── internal/ │ ├── config/ # 配置加载与解析 │ ├── engine/ # 核心执行引擎 │ ├── model/ # 数据模型定义 │ └── util/ # 工具函数 ├── templates/ # 测试模板集 └── llms-full.txt # CNB 规范文档
package main
import (
"context"
"fmt"
"cnbexec"
)
func main() {
// 创建执行器
exec, err := cnbexec.New("/path/to/repo")
if err != nil {
panic(err)
}
// 执行流水线
result, err := exec.Execute(context.Background(), cnbexec.ExecRequest{
ConfigPath: ".cnb.yml",
Branch: "main",
Event: "push",
})
if err != nil {
panic(err)
}
fmt.Printf("Build status: %s\n", result.Status)
}
// 设置默认 Docker 镜像
exec, err := cnbexec.New(workspace,
cnbexec.WithDefaultImage("alpine:3.20"),
)
// 自定义 HTTP 客户端(用于远程 include)
exec, err := cnbexec.New(workspace,
cnbexec.WithHTTPClient(httpClient),
)
// 如果配置已加载到内存,可直接执行
cfg, _ := loader.Load(" .cnb.yml")
result, err := exec.ExecuteConfig(ctx, cfg, req)
# 基础执行
go run ./cmd/cnbexec \
--config .cnb.yml \
--workspace . \
--branch main \
--event push
# 指定变更文件(用于 ifModify 判断)
go run ./cmd/cnbexec \
--config .cnb.yml \
--branch feature/new-api \
--event merge_request \
--changed package.json \
--changed src/main.go
# 注入额外环境变量
go run ./cmd/cnbexec \
--config .cnb.yml \
--branch main \
--event push \
-e FOO=bar \
-e BAZ=qux
# 设置默认镜像(当 pipeline/job 未声明 image 时使用)
CNB_EXEC_DEFAULT_IMAGE=alpine:3.20 go run ./cmd/cnbexec \
--config .cnb.yml
| 参数 | 默认值 | 说明 |
|---|---|---|
--config | .cnb.yml | CI 配置文件路径 |
--workspace | . | 工作区根目录 |
--branch | main | 触发分支 |
--event | push | 触发事件 |
--default-branch | main | 默认分支(用于新分支判断) |
--new-branch | false | 标记为新分支事件 |
--commit | - | 提交 SHA |
--before | - | 前一提交 SHA |
--changed | - | 变更文件列表(可重复) |
--default-image | CNB_EXEC_DEFAULT_IMAGE 环境变量 | 默认 Docker 镜像 |
-e | - | 额外环境变量 KEY=VALUE(可重复) |
命令行执行会输出 JSON 格式的执行结果:
{
"Status": "success",
"Pipelines": [
{
"Name": "Build and Test",
"Key": "build-and-test",
"Status": "success",
"AllowFailure": false,
"FailedStage": "",
"LastJobExports": {
"VERSION": "1.2.3"
}
}
]
}
状态码:
success - 所有流水线执行成功error - 有流水线执行失败(且不允许失败)cancel - 流水线被取消skipped - 无匹配的流水线项目提供了完整的测试模板集,位于 templates/ 目录:
| 模板 | 用途 | 覆盖功能 |
|---|---|---|
templates/minimal | 最小可运行示例 | docker.image、env、script、exports |
templates/builtin | 内置任务回归 | cnb:await、cnb:resolve、cnb:read-file、cnb:apply、cnb:trigger |
templates/control-flow | 流程控制 | if、ifModify、ifNewBranch、retry、allowFailure、failStages、endStages、lock、timeout |
templates/full-supported | 完整能力展示 | include、reference、docker.build、插件任务、内置任务、流程控制组合 |
# 运行所有回归测试
go test ./...
# 运行特定模板测试
go test ./internal/engine -run TestTemplate
minimal,验证最基本执行链路builtin,验证内置任务回归control-flow,验证条件与失败控制full-supported,验证完整能力组合当前实现为本地执行器原型,以下 CNB 平台特性尚未完全复刻或为近似实现:
CNB_TOKEN、可信/不可信事件隔离、密钥仓库 allow 校验service:docker / service:vscode 的完整平台注入行为breakIfModify / skipIfModify 还没有接真实 SCM 源分支更新检测docker run 近似,不是平台内同一长生命周期容器golang.org/x/sync - 并发控制gopkg.in/yaml.v3 - YAML 解析注意:本项目是根据 llms-full.txt 规范文档实现的本地执行器,主要用于本地开发和测试。生产环境请使用 CNB 官方平台。