流水线语法

基本概念

1main: # 触发分支
2  push: # 触发事件,对应一个构建,可以包含多条 Pipeline。即可以是数组,也可以是对象。
3    - name: pipeline-1 # Pipeline 结构体
4      stages:
5        - name: stage-1 # Stage 结构体
6          jobs:
7            - name: job-1 # Job 结构体
8              script: echo
1main: # 触发分支
2  push: # 触发事件,对应一个构建,通过对象指定流水线
3    pipeline-key:
4      stages:
5        - name: stage-1 # Stage 结构体
6          jobs:
7            - name: job-1 # Job 结构体
8              script: echo

Pipeline

Pipeline 表示一个流水线,包含一个或者多个阶段 Stage,每个 Stage 依次执行。

一个 Pipeline 的基本配置如下:

 1name: 流水线名字
 2docker:
 3  image: node
 4  build: dev/Dockerfile
 5  volumes:
 6    - /root/.npm:copy-on-write
 7git:
 8  enable: true
 9  submodules: true
10  lfs: true
11services:
12  - docker
13env:
14  TEST_KEY: TEST_VALUE
15imports:
16  - https://cnb.cool/<your-repo-slug>/-/blob/main/xxx/envs.yml
17  - ./env.txt
18label:
19  type: MASTER
20  class: MAIN
21stages:
22  - name: stage 1
23    script: echo "stage 1"
24  - name: stage 2
25    script: echo "stage 2"
26  - name: stage 3
27    script: echo "stage 3"
28failStages:
29  - name: fail stage 1
30    script: echo "fail stage 1"
31  - name: fail stage 2
32    script: echo "fail stage 2"
33endStages:
34  - name: end stage 1
35    script: echo "end stage 1"
36  - name: end stage 2
37    script: echo "end stage 2"
38ifModify:
39  - a.txt
40  - "src/**/*"
41retry: 3
42allowFailure: false

name

指定流水线名,默认为 pipeline。当有多条并行流水线时, 默认流水线名为 pipelinepipeline-1pipeline-2 依此类推, 可定义 name 指定流水线名来区分不同流水线。

runner

指定构建节点相关参数。

tags

指定使用具备哪些标签的构建节点。详见构建节点

示例:

1main:
2  push:
3    - runner:
4        tags: cnb:arch:amd64
5      stages:
6        - name: uname
7          script: uname -a

cpus

指定构建需使用的最大 cpu 核数(memory = cpu 核数 * 2 G), 其中 cpu 和 memory 不超过 runner 机器实际大小。

未配置,则最大可用 cpu 核数由分配到的 runner 机器配置来指定。

示例:

1# cpus = 1,memory = 2G
2main:
3  push:
4    - runner:
5        cpus: 1
6      stages:
7        - name: echo
8          script: echo "hello world"

docker

指定 docker 相关的参数。详情见构建环境

image

指定当前 Pipeline 的环境镜像,在当前 Pipeline 下的所有任务都将在这个镜像环境中执行,支持引用环境变量。

如果指定 image 为字符串,则等同于指定了 image.name

示例一,使用公开镜像:

1main:
2  push:
3    - docker:
4        # 取 docker 官方镜像仓库中的 node:20 镜像作为构建容器
5        image: node:20
6      stages:
7        - name: show version
8          script: node -v

示例二,使用 CNB 制品库私有镜像:

 1main:
 2  push:
 3    - docker:
 4        # 取非公开镜像作为构建容器,需传入 docker 用户名和密码
 5        image:
 6          name: docker.cnb.cool/images/pipeline-env:1.0
 7          # 使用 CI 构建时默认注入的环境变量
 8          dockerUser: $CNB_TOKEN_USER_NAME
 9          dockerPassword: $CNB_TOKEN
10      stages:
11        - name: echo
12          script: echo "hello world"

示例三,使用 docker 官方镜像源私有镜像:

 1main:
 2  push:
 3    - imports: https://cnb.cool/<your-repo-slug>/-/blob/main/xxx/docker.yml
 4      docker:
 5        # 取非公开镜像作为构建容器,需传入 docker 用户名和密码
 6        image:
 7          name: images/pipeline-env:1.0
 8          # docker.yml 中导入的环境变量
 9          dockerUser: $DOCKER_USER
10          dockerPassword: $DOCKER_PASSWORD
11      stages:
12        - name: echo
13          script: echo "hello world"

docker.yml

1DOCKER_USER: user
2DOCKER_PASSWORD: password

build

指定一个 Dockerfile,构建一个临时镜像,做为 image 的值使用,支持引用环境变量。

使用 build 声明构建环境的完整示例可参考docker-build-with-by

以下是 build 下各参数的说明:

如果指定build为字符串,则等同于指定了build.dockerfile

Dockerfile 用法:

1main:
2  push:
3    - docker:
4        # 通过 Dockerfile 指定构建环境
5        build: ./image/Dockerfile
6      stages:
7        - stage1
8        - stage2
9        - stage3
 1main:
 2  push:
 3    - docker:
 4        # 通过 Dockerfile 指定构建环境
 5        build:
 6          dockerfile: ./image/Dockerfile
 7          dockerImageName: cnb.cool/project/images/pipeline-env
 8          dockerUser: $DOCKER_USER
 9          dockerPassword: $DOCKER_PASSWORD
10      stages:
11        - stage1
12        - stage2
13        - stage3
 1main:
 2  push:
 3    - docker:
 4        # 通过 Dockerfile 指定构建环境
 5        build:
 6          dockerfile: ./image/Dockerfile
 7          # 只构建 builder,而不是整个Dockerfile
 8          target: builder
 9      stages:
10        - stage1
11        - stage2
12        - stage3

Dockerfile versionBy 用法:

示例:将 pnpm 缓存到环境镜像中,加速后续pnpm i过程

 1main:
 2  push:
 3    # 通过 Dockerfile 指定构建环境
 4    - docker:
 5        build:
 6          dockerfile: ./Dockerfile
 7          versionBy:
 8            - package-lock.json
 9      stages:
10        - name: pnpm i
11          script: pnpm i
12        - stage1
13        - stage2
14        - stage3
 1FROM node:20
 2
 3#替换真实的源
 4RUN npm config set registry https://xxx.com/npm/ \
 5  && npm i -g pnpm \
 6  && pnpm config set store-dir /lib/pnpm
 7
 8WORKDIR /data/orange-ci/workspace
 9
10COPY package.json package-lock.json ./
11
12RUN pnpm i
 1[pnpm i] Progress: resolved 445, reused 444, downloaded 0, added 100
 2[pnpm i] Progress: resolved 445, reused 444, downloaded 0, added 141
 3[pnpm i] Progress: resolved 445, reused 444, downloaded 0, added 272
 4[pnpm i] Progress: resolved 445, reused 444, downloaded 0, added 444, done
 5[pnpm i]
 6[pnpm i] dependencies:
 7[pnpm i] + mocha 8.4.0 (10.0.0 is available)
 8[pnpm i]
 9[pnpm i] devDependencies:
10[pnpm i] + babel-eslint 9.0.0 (10.1.0 is available)
11[pnpm i] + eslint 5.16.0 (8.23.0 is available)
12[pnpm i] + jest 27.5.1 (29.0.2 is available)
13[pnpm i]
14[pnpm i]
15[pnpm i] Job finished, duration: 6.8s

volumes

声明数据卷,多个数据卷可用通过数组或者用,号做分割符传入,可引用环境变量,支持的格式有:

  1. <group>:<path>:<type>
  2. <path>:<type>
  3. <path>

各项含义:

copy-on-write

用于缓存场景,支持并发

copy-on-write 技术允许系统在需要修改数据之前共享相同的数据副本,从而实现高效的缓存复制。 在并发环境中,这种方法避免了缓存的读写冲突,因为只有在实际需要修改数据时,才会创建数据的私有副本。 这样,只有写操作会导致数据复制,而读操作可以安全地并行进行,无需担心数据一致性问题。 这种机制显著提高了性能,尤其是在读多写少的缓存场景中。

data

用于共享数据,将容器中的指定目录,共享给其他容器中使用。

通过创建数据卷,然后 mount 到各容器中。 与直接将构建节点上目录 mount 到容器中方式不同的是:当指定的目录在容器中已经存在, 会先把容器中内容自动复制到数据卷,而不是将数据卷内容直接覆盖容器中目录。

volumes 示例

示例1 : 挂载构建节点上目录到容器中,实现本地缓存效果

 1main:
 2  push:
 3    - docker:
 4        image: node:20
 5        # 声明数据卷
 6        volumes:
 7          - /data/config:read-only
 8          - /data/mydata:read-write
 9
10          # 使用缓存,同时更新
11          - /root/.npm
12
13          # 使用 main 缓存,同时更新
14          - main:/root/.gradle:copy-on-write
15
16      stages:
17        - stage1
18        - stage2
19        - stage3
20  pull_request:
21    - docker:
22        image: node:20
23
24        # 声明数据卷
25        volumes:
26          - /data/config:read-only
27          - /data/mydata:read-write
28
29          # 使用 copy-on-write 缓存
30          - /root/.npm
31          - node_modules
32
33          # pr 使用 main 缓存,但不更新
34          - main:/root/.gradle:copy-on-write-read-only
35
36      stages:
37        - stage1
38        - stage2
39        - stage3

示例2:将打包在容器中的文件,共享到其他容器中使用

 1# .cnb.yml
 2main:
 3  push:
 4    - docker:
 5        image: go-app-cli # 假设有个go应用在镜像的/go-app/cli路径下
 6        # 声明数据卷
 7        volumes:
 8          # 此路径在go-app-cli镜像存在,所以执行环境镜像时,会将此路径内容复制到临时数据卷中,可共享给其他任务容器里使用
 9          - /go-app
10      stages:
11        - name: show /go-app-cli in job container
12          image: alpine
13          script: ls /go-app

git

提供 Git 仓库相关配置。

git.enable

指定是否拉取代码。

branch.delete 事件,默认值为 false。其他事件,默认值为 true

git.submodules

指定是否要拉取子项目(submodules)。

当值为 Boolean 类型时,相当于指定 git.submodules.enablegit.submodules 的值,git.submodules.remote 为默认值 false

git.submodules.enable

是否指定是否要拉取子项目 submodules

git.submodules.remote

执行 git submodule update 时是否添加 --remote 参数,用于每次拉取 submodule 最新的代码

基本用法:

 1main:
 2  push:
 3    - git:
 4        enable: true
 5        submodules: true
 6      stages:
 7        - name: echo
 8          script: echo "hello world"
 9    - git:
10        enable: true
11        submodules:
12          enable: true
13          remote: true
14      stages:
15        - name: echo
16          script: echo "hello world"

git.lfs

指定是否要拉取 LFS 文件。

支持 Object 形式指定具体参数,字段缺省时,默认值为:

1{
2  "enable": true
3}

基本用法:

 1main:
 2  push:
 3    - git:
 4        enable: true
 5        lfs: true
 6      stages:
 7        - name: echo
 8          script: echo "hello world"
 9    - git:
10        enable: true
11        lfs:
12          enable: true
13      stages:
14        - name: echo
15          script: echo "hello world"
git.lfs.enable

是否指定是否要拉取 LFS 文件。

services

用于声明构建时需要的服务,格式:name:[version], version 是可选的。

目前支持的服务有:

service:docker

用于开启 dind 服务,

当构建过程中需要使用 docker builddocker login 等操作时声明, 会自动在环境注入 docker daemondocker cli

示例:

 1main:
 2  push:
 3    - services:
 4        - docker
 5      docker:
 6        image: alpine
 7      stages:
 8        - name: docker info
 9          script:
10            - docker info
11            - docker ps

该服务会自动 docker login 到 CNB Docker 制品库的镜像源(docker.cnb.cool), 在后续任务中可直接 docker push 到当前仓库 Docker 制品库。

示例:

 1main:
 2  push:
 3    - services:
 4        - docker
 5      stages:
 6        - name: build and push
 7          script: |
 8            # 根目录存在 Dockerfile 文件
 9            docker build -t ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:latest .
10            docker push ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:latest

service:vscode

需要远程开发时声明。

示例:

 1$:
 2  vscode:
 3    - services:
 4        - vscode
 5        - docker
 6      docker:
 7        image: alpine
 8      stages:
 9        - name: uname
10          script: uname -a

env

指定环境变量。可以定义一组环境变量,在任务执行中使用。对当前 Pipeline 内的非插件任务均有效。

imports

指定 CNB Git 仓库文件路径(文件相对路径或 http 地址),可以读取此文件作为环境变量来源。

本地相对路径如 ./env.yml 会被拼接成远端 http 文件地址进行加载。

云原生构建 现支持密钥仓库,安全性更高,支持文件引用审计, 一般使用一个密钥仓库来存放诸如 npmdocker 等账号密码。

示例:

1#env.yml
2DOCKER_USER: "username"
3DOCKER_TOKEN: "token"
4DOCKER_REGISTRY: "https://xxx/xxx"
 1#.cnb.yml
 2main:
 3  push:
 4    - services:
 5        - docker
 6      imports:
 7        - https://cnb.cool/<your-repo-slug>/-/blob/main/xxx/env.yml
 8      stages:
 9        - name: docker push
10          script: |
11            docker login -u ${DOCKER_USER} -p "${DOCKER_TOKEN}" ${CNB_DOCKER_REGISTRY}
12            docker build -t ${DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:latest .
13            docker push ${DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:latest

注意:对插件任务无效

支持的文件格式列表:

同名 key 优先级:

变量赋值

imports 文件路径可读取环境变量。若是数组,下面的文件路径可读取上面文件中的变量。

1// env.json
2{
3  FILE: "https://cnb.cool/<your-repo-slug>/-/blob/main/xxx/env2.yml";
4}
1# env2.yml
2TEST_TOKEN: some token
1main:
2  push:
3    - imports:
4        - ./env1.json
5        - $FILE
6      stages:
7        - name: echo
8          script: echo $TEST_TOKEN

被引用文件可声明可被访问范围,参考 配置文件引用鉴权

示例:

team_name/project_name/*,匹配一个项目下面的所有仓库:

1key: value
2
3allow_slugs:
4  - team_name/project_name/*

允许被所有仓库引用

1key: value
2
3allow_slugs:
4  - "**"

大部份场景配置文件是简单的单层对象,比如:

1// env.json
2{
3  "token": "private token",
4  "password": "private password"
5}

为了应对复杂的配置文件和场景,imports 支持对象嵌套!若引入的文件解析后的对象包含深层属性(第一层不能为数组),会平铺成单层对象,规则是:

  1. 属性名保留,属性值会转成字符串
  2. 属性值若为对象(包括数组),则会递归平铺,属性路径以 _ 连接
 1// env.json
 2{
 3  "key1": [
 4    "value1",
 5    "value2"
 6  ],
 7  "key2": {
 8    "subkey1": [
 9      "value3",
10      "value4"
11    ],
12    "subkey2": "value5"
13  },
14  "key3": [
15    "value6",
16    {
17      "subsubkey1": "value7"
18    }
19  ],
20  "key4": "value8"
21}

会平铺成

 1{
 2      // 原属性值转成字符串
 3      "key1": "value1,value2",
 4      // 属性值若为对象,则额外进行递归平铺操作增加属性
 5      "key1_0": "value1",
 6      "key1_1": "value2",
 7      "key2": "[object Object]",
 8      "key2_subkey1": "value3,value4",
 9      "key2_subkey1_0": "value3",
10      "key2_subkey1_1": "value4",
11      "key2_subkey2": "value5",
12      "key3": "value6,[object Object]",
13      "key3_0": "value6",
14      "key3_1": "[object Object]",
15      "key3_1_subsubkey1": "value7",
16      "key4": "value8"
17    }
1main:
2  push:
3    - imports:
4        - ./env.json
5      stages:
6        - name: echo
7          script: echo $key3_1_subsubkey1

label

为流水线指定标签。每个标签的值可以是一个字符串,也可以是一个字符串数组。该标签可用于后续流水线记录筛选等功能。

这里举一种工作流的例子:main 分支合并即发布预发布环境,打 tag 后发布正式环境

 1main:
 2  push:
 3    - label:
 4        # Master 分支的常规流水线
 5        type:
 6          - MASTER
 7          - PREVIEW
 8      stages:
 9        - name: install
10          script: npm install
11        - name: CCK-lint
12          script: npm run lint
13        - name: BVT-build
14          script: npm run build
15        - name: UT-test
16          script: npm run test
17        - name: pre release
18          script: ./pre-release.sh
19
20$:
21  tag_push:
22    - label:
23        # 产品发布分支的常规流水线
24        type: RELEASE
25      stages:
26        - name: install
27          script: npm install
28        - name: build
29          script: npm run build
30        - name: DELIVERY-release
31          script: ./release.sh

stages

定义一组阶段任务,每个阶段串行运行。

failStages

定义一组失败阶段任务。当正常流程失败,会依次执行此阶段任务。

endStages

定义流水线结束阶段执行的一组任务。当流水线 stages/failStages 执行完,流水线结束前,会依次执行此阶段任务。

当流水线 prepare 阶段成功,无论 stages 是否成功,endStages 都将执行。 且 endStages 是否成功不影响流水线状态(即 endStages 失败,流水线状态也可能是成功)。

ifNewBranch

true 表示当前分支属于新分支(即 CNB_IS_NEW_BRANCHtrue)时,才执行此 Pipeline

当同时存在 ifNewBranch / ifModify 时,其中有一个条件满足,此 Pipeline 就会执行。

ifModify

指定只有相应文件变动时,才执行此 Pipeline。 是一个 glob 表达式字符串或字符串数组。

示例1:

当修改文件列表中包含 a.js 或者 b.js,会执行此 Pipeline

1ifModify:
2  - a.js
3  - b.js

示例2:

当修改文件列表中包含有 js 后缀的文件时,会执行此 Pipeline。 其中 **/*.js 表示匹配所有子目录中的 js 后缀文件,*.js 表示所有根目录中的 js 后缀文件。

1ifModify:
2  - "**/*.js"
3  - "*.js"

示例3:

反向匹配,排除目录 legacy 和排除所有 Markdown 文件,有其他文件变更时触发

1ifModify:
2  - "**"
3  - "!(legacy/**)"
4  - "!(**/*.md)"
5  - "!*.md"

示例4:

反向匹配,src 目录并且除目录 src/legacy 以外有变更时触发

1ifModify:
2  - "src/**"
3  - "!(src/legacy/**)"

支持事件

因为文件变更可能非常多,变更文件的统计限制为最多300个。

breakIfModify

Job 执行前,如果源分支已更新,则终止构建。

retry

失败重试次数, 0 表示不重试。

allowFailure

是否允许当前流水线 失败。

当此参数设置为 true 时,流水线的失败的状态不会上报到 CNB 上。

lock

pipeline 设置锁,pipeline 执行完后自动释放锁,锁不能跨仓库使用。

表现: 流水线 A 获取到锁后,流水线 B 再申请锁,可以终止A或等待A执行完释放锁后,获取到锁再继续执行任务。

lock 为 true,则 keyexpirestimeoutcancel-in-progresswaitcancel-in-wait为各自默认值。

例1: lock 是 Boolean 格式

1main:
2  push:
3    - lock: true
4      stages:
5        - name: stage1
6          script: echo "stage1"

例2: lock 是 Object 格式

 1main:
 2  push:
 3    - lock:
 4        key: key
 5        expires: 600 # 10分钟
 6        wait: true
 7        timeout: 60 # 最多等待 1分钟
 8      stages:
 9        - name: stage1
10          script: echo "stage1"

例3: 停止 pull_request 下上一条正在进行的流水线

1main:
2  pull_request:
3    - lock:
4        key: pr
5        cancel-in-progress: true
6      stages:
7        - name: echo hello
8          script: echo "stage1"

Stage

Stage 表示一个构建阶段,可以由一个或者多个 Job 组成,见 Job 介绍

单个 Job

如果一个 Stage 只有一个 Job,那么可以省掉 Stage 直接书写这个 Job

1stages:
2  - name: stage1
3    jobs:
4      - name: job A
5        script: echo hello

可以简化为以下写法:

1- stages:
2    - name: job A
3      script: echo hello

Job 为字符串时,可以视作脚本任务,name 和 script 取该字符串,可以继续简化为:

1- stages:
2    - echo hello

串行 Job

当值为数组(有序)时,那么这组 Job 会串行执行。

1# 串行
2stages:
3  - name: install
4    jobs:
5      - name: job1
6        script: echo "job1"
7      - name: job2
8        script: echo "job2"

并行 Job

当值为对象(无序)时,那么这组 Job 会并行执行。

1# 并行
2stages:
3  - name: install
4    jobs:
5      job1:
6        script: echo "job1"
7      job2:
8        script: echo "job2"

多个 Job 串行、并行可灵活组织。 先串行后并行的示例:

 1main:
 2  push:
 3    - stages:
 4        - name: serial first
 5          script: echo "serial"
 6        - name: parallel
 7          jobs:
 8            parallel job 1:
 9              script: echo "1"
10            parallel job 2:
11              script: echo "2"
12        - name: serial next
13          script: echo "serial next"

name

Stage 名称。

ifNewBranch

true 表示只有当前分支属于新分支(即 CNB_IS_NEW_BRANCHtrue)时,才执行此 Stage

当同时存在 ifNewBranch / ifModify / if 有一个条件满足,此 Stage 就会执行

ifModify

指定只有相应文件变动时,才执行此 Stage。 是一个 glob 匹配表达式字符串或字符串数组。

if

一个或者多个 Shell 脚本,根据脚本执行的退出程序码(exit code)来判断是否执行此 Stage。 当退出程序码为 0 时,表示需要执行本步骤。

示例1:判断某个变量的值

shell表达式语法

 1main:
 2  push:
 3    - env:
 4        IS_NEW: true
 5      stages:
 6        - name: is new
 7          if: |
 8            [ "$IS_NEW" = "true" ]
 9          script: echo is new
10        - name: is not new
11          if: |
12            [ "$IS_NEW" != "true" ]
13          script: echo not new

示例2: 判断任务执行的输出

 1main:
 2  push:
 3    - stages:
 4        - name: make info
 5          script: echo 'haha'
 6          exports:
 7            info: RESULT
 8        - name: run if RESULT is haha
 9          if: |
10            [ "$RESULT" = "haha" ]
11          script: echo $RESULT

env

Pipeline env,只对当前 Stage 生效。

Stage env 优先级比 Pipeline env 高。

imports

Pipeline imports,只对当前 Stage 生效1。

retry

失败重试次数,0 表示不重试。

lock

Stage 设置锁,Stage 执行完后自动释放锁,锁不能跨仓库使用。

表现: 任务 A 获取到锁后,任务 B 再申请锁,将等待锁释放后,才能获取到锁继续执行任务。

锁过期时间,过期后自动释放锁,单位“秒”。

锁被占用是否等待。

指定等待锁的超时时间,单位“秒”。

lock 为 true,则 keyexpirestimeoutcancel-in-progresswaitcancel-in-wait为各自默认值。

例1: lockBoolean 格式

1main:
2  push:
3    - stages:
4        - name: stage1
5          lock: true
6          jobs:
7            - name: job1
8              script: echo "job1"

例2: lockObject 格式

 1main:
 2  push:
 3    - stages:
 4        - name: stage1
 5          lock:
 6            key: key
 7            expires: 600 # 10分钟
 8            wait: true
 9            timeout: 60 # 最多等待 1分钟
10          jobs:
11            - name: job1
12              script: echo "job1"

image

指定当前 Stage 的环境镜像,在当前 Stage 下的所有任务默认都将在这个镜像环境中执行。

如果指定 image 为字符串,则等同于指定了 image.name

jobs

定义一组任务,每个任务串行/并行运行。

Job

Job 是最基本的任务执行单元,可以分为三类:

内置任务

options 中同名字段优先级高于 optionsFrom

引用配置文件权限控制参考 配置文件引用鉴权

示例:

1name: install
2type: INTERNAL_JOB_NAME
3optionsFrom: ./options.json
4options:
5  key1: value1
6  key2: value2
1// ./options.json
2{
3  "key1": "value1",
4  "key2": "value2"
5}

脚本任务

1- name: install
2  script: npm install

示例:

1- name: install
2  image: node:20
3  script: npm install

脚本任务可以简化为字符串,此时 script 取该字符串,name 取该字符串第一行:

1- echo hello

相当于:

1- name: echo hello
2  script: echo hello

插件任务

插件即 Docker 镜像,也可称为镜像任务。

不同于以上两类任务,插件任务 具有执行环境更自由的特点。 而且更易在团队、公司内外分享,甚至可以跨 CI 复用。

插件任务 通过向 ENTRYPOINT 传递环境变量的方式,来达到隐藏内部实现的目的。

注意:通过 imports、env 等参数设置的自定义环境变量不会传递给插件,但可以用在 settings、args中的变量替换。CNB 系统环境变量依然会传递给插件

引用配置文件权限控制参考 配置文件引用鉴权

示例:

同时限制 imagesslugs

1allow_slugs:
2  - a/b
3allow_images:
4  - a/b

仅限制 images,不限制 slug

1allow_images:
2  - a/b

settingsFrom 可以写在 Dockerfile 中:

1FROM node:20
2
3LABEL cnb.cool/settings-from="https://cnb.cool/<your-repo-slug>/-/blob/main/xxx/settings.json"

示例

with imports:

1- name: npm publish
2  image: plugins/npm
3  imports: https://cnb.cool/<your-repo-slug>/-/blob/main/xxx/npm.json
4  settings:
5    username: $NPM_USER
6    password: $NPM_PASS
7    email: $NPM_EMAIL
8    registry: https://mirrors.xxx.com/npm/
9    folder: ./
1{
2  "username": "xxx",
3  "password": "xxx",
4  "email": "xxx@emai.com",
5  "allow_slugs": ["cnb/**/**"],
6  "allow_images": ["plugins/npm"]
7}

with settingsFrom:

1- name: npm publish
2  image: plugins/npm
3  settingsFrom: https://cnb.cool/<your-repo-slug>/-/blob/main/xxx/npm-settings.json
4  settings:
5    # username: $NPM_USER
6    # password: $NPM_PASS
7    # email: $NPM_EMAIL
8    registry: https://mirrors.xxx.com/npm/
9    folder: ./
1{
2  "username": "xxx",
3  "password": "xxx",
4  "email": "xxx@emai.com",
5  "allow_slugs": ["cnb/cnb"],
6  "allow_images": ["plugins/npm"]
7}

name

指定 Job 名称。

ifModify

Stage ifModify。只对当前 Job 生效。

ifNewBranch

Stage ifNewBranch。只对当前 Job 生效。

if

Stage if。只对当前 Job 生效。

breakIfModify

Pipeline breakIfModify。不同点在于只对当前 Job 生效。

skipIfModify

Job 执行前,如果源分支已更新,则跳过当前 Job

env

Stage env,只对当前 Job 生效。

Job env 优先级比 Pipeline envStage env 高。

imports

Stage imports,只对当前 Job 生效。

exports

Job 执行结束后,有一个 result 对象,可通过 exportsresult 中的属性导出到环境变量,生命周期为当前 Pipeline

详情请见 环境变量

timeout

设置单个任务的超时时间,默认为 1 小时,最大不能超过 12 小时。

script-jobimage-job 有效。

同时支持以下单位:

1name: timeout job
2script: sleep 1d
3timeout: 100s #任务将在100秒后超时退出

详见 超时策略

allowFailure

true 表示本步骤如果失败,也不会影响接下来流程的执行,并且不会影响最后的结果。

值为 String 类型时可以读取环境变量

lock

Job 设置锁,Job 执行完后自动释放锁,锁不能跨仓库使用。

表现: 任务 A 获取到锁后,任务 B 再申请锁,将等待锁释放后,才能获取到锁继续执行任务。

自定义锁名,默认为 分支名-流水线名-stage下标-job名

锁过期时间,过期后自动释放锁,单位“秒”。

锁被占用是否等待。

指定等待锁的超时时间,单位“秒”。

lock 为 true,则 keyexpirestimeoutcancel-in-progresswaitcancel-in-wait为各自默认值。

例1: lock 是 Boolean 格式

1name: 
2lock: true
3script: echo 'job 锁'

例2: lock 是 Object 格式

1name: 
2lock:
3  key: key
4  expires: 10
5  wait: true
6script: echo 'job 锁'

retry

失败重试次数,0 表示不重试。

type

指定该步骤所要执行的 内置任务

options

指定内置任务参数。

optionsFrom

指定本地或 Git 仓库文件路径,加载为内置任务参数。与 imports 参数类似,配置 optionsFrom 为数组时,如遇到参数重复的情况,后面的配置会覆盖前面的。

options 同名字段优先级高于 optionsFrom

script

指定任务要执行的脚本。为数组时会自动使用 && 拼接。执行脚本的进程退出码会作为这个 Job 的退出码。

注意: 流水线使用的基础镜像的默认命令行解释器是 sh,指定不同的 image 作为执行环境,命令行解释器可能有所不同

commands

作用同 script 参数, 优先级比 script 高。主要为了兼容 Drone CI 语法。

image

指定用哪个 Image 作为当前 Job 执行环境, 用于 docker image as envdocker image as plugins

如果指定 image 为字符串,则等同于指定了 image.name

settings

指定该插件任务执行所需的参数。详细插件任务介绍

settingsFrom

指定本地或 Git 仓库文件路径,加载为插件任务参数。与 imports 参数类似,配置 settingsFrom 为数组时,如遇到参数重复的情况,后面的配置会覆盖前面的。

详细插件任务介绍

args

指定执行镜像时传递的参数,内容将会追加到 ENTRYPOINT 中,仅支持数组。

1- name: npm publish
2  image: plugins/npm
3  args:
4    - ls

将执行

1docker run plugins/npm ls

任务退出码