首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >把 CI/CD 写进 YAML:腾讯云 CNB 声明式流水线上手

把 CI/CD 写进 YAML:腾讯云 CNB 声明式流水线上手

原创
作者头像
gavin1024
发布2026-08-31 14:15:36
发布2026-08-31 14:15:36
80
举报

摘要

腾讯云 CNB 用一份 .cnb.yml 文件定义整条 CI/CD 流水线,采用 Pipeline/Stage/Job 三层结构,支持 push、PR、定时、手动等多种触发方式和 glob 分支匹配。本文从最简示例讲到 Docker 镜像构建推送,提供可直接复用的 YAML 配置。

一、声明式配置的核心:三层结构

腾讯云 CNB 的流水线通过仓库根目录下的 .cnb.yml 文件定义。配置的最外层是触发分支,指定哪些分支上的事件会触发流水线;往内则是从外到内的三层执行结构:

层级

说明

示例

Pipeline(流水线)

一次完整的构建流程,包含多个阶段

构建流程

Stage(阶段)

流水线中的一个步骤,可包含一个或多个任务

安装依赖

Job(任务)

最小的执行单元,执行具体的命令或插件

执行命令

执行流程可以理解为:某条分支(如 main)上发生了某个事件(如 push),于是触发一条或多条 Pipeline,每条 Pipeline 内的多个 Stage 依次执行,每个 Stage 里的 Job 按写法决定串行或并行。把构建流程拆成这三层,能让配置职责清晰:一条流水线负责一件完整的事,一个阶段负责一类步骤,一个任务负责一个具体动作。

二、五分钟写出第一条流水线

下面是一个能直接运行的最简配置,实现"代码推送到 main 分支时打印一行文字":

代码语言:yaml
复制
main:
  push:
    - name: hello-pipeline
      stages:
        - name: say-hello
          jobs:
            - name: echo-job
              script: echo "Hello, CNB!"

逐行解释一下:

  • main:触发分支,表示只在 main 分支上生效。
  • push:触发事件,代码推送到该分支时触发。
  • - name: hello-pipeline:一条流水线,name 可自定义,不写时默认为 pipeline
  • stagesjobsscript:阶段 → 任务 → 实际执行的命令。

把这份文件保存为仓库根目录的 .cnb.yml 并提交推送,之后每次 push 到 main,CNB 就会自动拉起构建节点执行 echo "Hello, CNB!"。你也可以用数组形式声明多条并行流水线,或用对象形式给每条流水线起名字:

代码语言:yaml
复制
main:
  push:
    - name: pipeline-1
      stages:
        - name: stage-1
          jobs:
            - name: job-1
              script: echo "in pipeline-1"
    - name: pipeline-2
      stages:
        - name: stage-1
          jobs:
            - name: job-1
              script: echo "in pipeline-2"

三、触发规则与分支匹配

CNB 支持多种触发事件,常见的 Git 操作事件包括:

事件名

触发时机

push

代码推送到分支时触发

pull_request

创建或更新 Pull Request 时触发

tag_push

推送标签时触发

branch.delete

删除分支时触发

除了 Git 事件,还支持页面手动触发(web_trigger)、API 请求触发(api_trigger)、定时任务、Issue 事件以及 NPC 事件等。下面是一个覆盖多事件的示例:

代码语言:yaml
复制
main:
  # 代码推送时执行测试
  push:
    - stages:
        - name: test
          script: npm test
  # PR 时执行代码检查
  pull_request:
    - stages:
        - name: lint
          script: npm run lint

分支匹配支持 glob 模式,可以为不同分支配置不同的构建流程:

模式

匹配范围

dev/*

dev/ 开头的分支(不含多级 /

(main\|dev)

maindev 分支

**/!(main\|dev)

maindev 外的所有分支

**

所有分支

$

兜底匹配,未被 glob 匹配的分支

glob 规则里 * 匹配任意字符但不匹配 /** 则匹配包括 / 在内的任意字符。匹配策略上,系统先用所有 glob 规则尝试匹配,未匹配的分支再走 $ 兜底;多个 glob 同时命中时,命中的流水线会并行执行。一个实用的写法是把通用流程放在 $ 下作为兜底:

代码语言:yaml
复制
feature/*:
  push:
    - stages:
        - name: feature-build
          script: echo "feature branch build"
$:
  push:
    - stages:
        - name: default-build
          script: echo "default branch build"

四、多 Stage 与多 Job 的编排

实际项目里,一条流水线往往包含多个阶段,比如先安装依赖、再构建、最后跑测试。Stage 之间是串行关系,一个阶段跑完才进入下一个阶段;同一 Stage 内的多个 Job 是串行还是并行,取决于 jobs 的写法——数组形式(多个 - name)串行执行,对象形式(多个 key:)并行执行。下面是一个典型的"安装 → 构建 → 测试"三段式流水线,其中 test 阶段用对象形式让两个 Job 并行:

代码语言:yaml
复制
main:
  push:
    - name: ci-pipeline
      stages:
        - name: install
          jobs:
            - name: install-deps
              script: npm install
        - name: build
          jobs:
            - name: compile
              script: npm run build
        - name: test
          jobs:
            unit-test:
              script: npm test
            lint-check:
              script: npm run lint

在这个例子里,installbuildtest 三个阶段依次执行;而 test 阶段内的 unit-testlint-check 因为用了对象形式,会并行跑。如果改成数组形式(- name: unit-test 下接 - name: lint-check),这两个 Job 就会串行执行。想让同一类任务在多个环境或版本下重复执行时,可以拆成多条并行的 Pipeline,一次提交触发多组任务。

五、构建 Docker 镜像并推送

CNB 基于 Docker 生态,每个 Job 都能在指定镜像里运行,也能在流水线里直接构建并推送 Docker 镜像。下面是一份完整示例:先通过 Dockerfile 构建镜像,再推送到 CNB 的制品库。

代码语言:yaml
复制
main:
  push:
    - name: docker-build-and-push
      # 凡涉及 docker build/login/push,必须声明 docker 服务(开启 dind)
      services:
        - docker
      stages:
        - name: set docker tag
          script: echo -n "${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:latest"
          exports:
            info: IMAGE_TAG
        - name: docker build
          script: docker build -t $IMAGE_TAG .
        - name: push image
          script: docker push $IMAGE_TAG

这里有两点关键:一是必须在 Pipeline 顶层声明 services: [docker],它会开启 dind 服务、自动向环境注入 docker daemon 和 cli,并自动完成到 CNB Docker 制品库的登录;二是镜像地址用内置变量 ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE} 指向当前仓库的制品库,配合平台内置的触发者凭据,无需手动 docker login 即可推送。

配套的 Dockerfile 示例(以 Node.js 项目为例):

代码语言:dockerfile
复制
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]

如果你不想自己写 Dockerfile,也可以直接用官方预置镜像作为构建环境,例如用 node:20 镜像跑构建脚本:

代码语言:yaml
复制
main:
  push:
    - name: build-in-node
      docker:
        image: node:20
      stages:
        - name: install
          script: npm install
        - name: build
          script: npm run build
        - name: test
          script: npm test

当指定 image 为字符串时,等同于指定了镜像名;如果使用 CNB 制品库的私有镜像,系统会自动注入一个具备读取权限的临时令牌用于拉取,流水线结束时令牌自动销毁。

六、环境变量、密钥、缓存与插件

环境变量与密钥:敏感信息(如镜像密码、发布 Token)不要写进 .cnb.yml,而应放到密钥仓库里,再在流水线中通过 imports 导入。例如先在密钥仓库文件中声明变量,然后在配置里引用:

代码语言:yaml
复制
main:
  push:
    - imports: https://cnb.cool/你的组织/密钥仓库/-/blob/main/secrets.yml
      stages:
        - name: deploy
          script: echo "使用 $MY_TOKEN 进行部署"

缓存:重复构建时,可以把依赖目录或构建产物声明为数据卷做缓存,加速后续构建。配合前面提到的 docker.build 把依赖预装进环境镜像,能进一步缩短安装依赖的时间。

插件:CNB 提供丰富的官方和社区插件,可扩展流水线能力。例如用 cnbcool/git-auto-tag 插件自动生成 Tag:

代码语言:yaml
复制
main:
  auto_tag:
    - stages:
        - name: auto tag
          image: cnbcool/git-auto-tag:latest
          settings:
            tagFormat: 'v${version}'
            branch: $CNB_BRANCH
            repoUrlHttps: $CNB_REPO_URL_HTTPS

除了 auto_tag,常见的还有知识库构建、企业微信通知等插件,可在需要时组合进对应事件。

七、小结

腾讯云 CNB 的声明式配置把"代码提交后该做什么"这件事浓缩进一份 .cnb.yml 里:用触发分支 + 事件决定何时运行,用 Pipeline/Stage/Job 三层结构决定怎么跑,用 dockerimportsmatrix、插件等配置项决定在哪跑、用什么跑。从打印一行文字的入门示例,到多阶段并行、Docker 镜像构建推送、密钥导入和插件扩展,整套语法都能用同一套心智模型覆盖。

想把这些示例真正跑起来,可以前往 腾讯云 CNB 新建仓库,把文中的 .cnb.yml 提交进去,结合官方语法手册按需调整,很快就能搭出适合自己团队的 CI/CD 流水线。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 摘要:
  • 一、声明式配置的核心:三层结构
  • 二、五分钟写出第一条流水线
  • 三、触发规则与分支匹配
  • 四、多 Stage 与多 Job 的编排
  • 五、构建 Docker 镜像并推送
  • 六、环境变量、密钥、缓存与插件
  • 七、小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档