CI 模板说明 #
Pulse CI 的模板配置语法参考 Gitlab CI,语法跟 .gitlab-ci.yml 类似
CI 模板通过声明式的配置,定义了流水线的执行过程
Git repo 的 CI 执行时,会读取模板的配置,然后开始 CI 的执行过程
目前仅支持通过 Gitlab Repo 统一管理所有的模板(版本控制,权限控制)
CI 模板配置关键字 #
模板配置通过 yaml 描述(运行时 parse 为 json 解析执行),模板里配置的关键字包括全局关键字和 job 级别的关键字
全局关键字如下:
| 关键字 | 含义 |
|---|---|
| default | job 关键字的全局默认值 |
| stages | 流水线的执行阶段 |
| variables | 流水线级别的变量配置,所有 job 共享 |
| workflow | 控制流水线的行为 |
job 关键字如下:
| 关键字 | 含义 |
|---|---|
| artifacts | job 执行成功后的产物 |
| cache | job 的缓存 |
| extends | job 继承的 job 配置 |
| rules | 控制 job 是否进入当前流水线 |
| script | job 运行时执行的 shell 脚本 |
| stage | job 运行在哪个阶段 |
| when | job 的执行时机 |
全局关键字 #
default #
为某些 job 关键字 提供全局默认配置,现阶段支持配置的 job 关键字如下
- image
workflow #
用于控制 Pipeline 的行为
workflow.rules #
用于控制 pipeline 是否会被创建,当所有 rules 都非 true 时,pipeline 不会被创建
variables #
流水线级别的变量配置,所有 job 共享,分为普通变量和系统变量两种类型
普通变量主要用于控制 job 的执行行为,由模板配置者定义并在 job 块里使用。系统变量由 Pulse CI 读取,用于控制 CI 系统的行为
系统变量主要有以下几个:
deploy_window #
允许执行 CI 的时间窗口, 当前 CI 触发的服务器时间,必需在当前变量配置的时间窗口范围内
no_deploy_window #
不允许执行 CI 的时间窗口,当前 CI 触发的服务器时间,必需在当前变量配置的时间窗口范围外
当跟 deploy_window 同时存在时,以 deploy_window 为准
envs #
当前模板支持发布到的环境,在流水线创建时,可选取这里预设的环境,选取后通过 $PULSE_CI_DEPLOY_ENV 变量,注入到当前流水线的执行环境中
可根据这个变量值,用于控制 job 的执行环境,配置示例:
envs:
- test1
- test4
- name: integration
need_approval: "yes"
- name: pre
need_approval: "yes"
- name: prod
# 是否需要审批,如果有 manual job 只限制 manual job,否则限制当前流水线所有 job
need_approval: "yes"
# 是否受发布时间窗口限制,如果有 manual job 只限制 manual job,否则限制当前流水线所有 job
deploy_window_limit: "yes"
单个环境可额外配置 need_approval, deploy_window_limit 属性,作用如配置示例所示
stages #
流水线的执行要经过哪些阶段,每阶段按序执行,一个阶段可以有多个 Job,每个 Job 并发执行
配置示例:
stages:
- prepare # 注意,用户定义的模板里不要有这个 stage
- instalal
- build
- deploy
注意,prepare 为保留 stage,用于统计拉代码,拉镜像的时间,用户定义的模板里不要有这个 stage
Job 关键字 #
artifacts #
Job 的构建产物
在 Job 的 script 和 cache 逻辑执行完后,将 artifacts 压缩并上传到 api server
cache #
Job 的缓存
配置示例
cache-job:
stage: final
script:
- echo "This job builds a cache."
- yarn
cache:
key:
files:
- yarn.lock
- package.json
skip_scripts_if_found: "yes"
paths:
- node_modules
# 上传缓存
policy: push
cache.key.files #
cache.policy #
值可为 pull, push, 或 pull-push
当 cache.policy 的值为 pull 时
- 根据 cache.key.files 配置的文件,计算 sha 值, 从 api server 获取当前 sha 值对应的文件,并下载到当前执行环境中
- 如果缓存下载到了本地,且 cache.skip_scripts_if_found 的配置为 ‘yes’,则跳过 script 的执行
当 cache.policy 的值为 push 时
- 先执行 script 的内容
- script 执行成功后,将 paths 里声明的文件路径压缩,并根据 key 的配置计算 sha 值,上传到 manager
当 cache.policy 的值为 pull-push 时
- 根据 cache.key.files 配置的文件,计算 sha 值, 从 manager 获取当前 sha 值对应的文件,并下载到当前执行环境中
- 如果缓存下载到了本地,且 cache.skip_scripts_if_found 的配置为 ‘yes’,则跳过 script 的执行,否则执行 script
- script 执行成功后,并根据 key.files 的配置计算 sha 值,并将当前 sha 值跟 manager 校验,决定是否上传缓存,如果 sha 值已存在则不执行缓存逻辑
rules #
控制 Job 是否进入到当前 Pipeline
Job 默认都是会进到 pipeline,仅当有一条 rule.if 的 shell 执行 exitCode 非 0 时,Job 不会进到 pipeline
示例:
job:
script: echo "Hello, Rules!"
# 没有 rules,默认进入 pipeline
rules:
# 有 rules,任意一个 if 为 false, 则不会进入到 pipeline;
# 换言之,所有 if 都得满足条件才会进入到 pipeline
- if: $PULSE_CI_DEPLOY_ENV == "prod"
- if: $PULSE_CI_PIPELINE_SOURCE == "merge_request_event"
- if: $PULSE_CI_DEPLOY_BRANCH == "main'
script #
Job 执行的 Shell 命令,控制 Job 执行时的行为
stage #
控制 Job 在哪个 Stage 执行
when #
控制 Job 进入 Pipeline 后的执行条件
变量设置 #
流水线的静态行为通过模板默认配置控制,动态行为由变量控制,变量分三个级别: 模板变量 项目变量 流水线变量
变量配置后,运行时会被注入到 CI 的运行环境中,可在 job 的 script , rules 块里读取,
变量优先级 流水线变量 > 项目变量 > 模板变量,优先级由高到低
模板变量 #
在 CI 模板里配,变量对当前模板生效,所有用到这个模板的 repo 在 CI 执行时都可在运行环境中读到该变量
项目变量 #
在项目设置里配,仅对当前项目生效,变量同 key 会覆盖模板级别变量
流水线变量 #
创建流水线时指定,优先级最高
CI 模板类型定义 #
如下使用 typescript 描述 CI 模板的类型
type foo: string
CI 模板完整示例 #
# 全局默认配置
default:
# 提供当前 pipeline 所有 job 的 scripts 执行的运行环境
image: node:14
# 全局环境变量定义,所有 job 都可以读取
variables:
var_foo: foo
# 允许发布的时间窗口
deploy_window:
- 14:00 ~ 17:00
- 10:00 ~ 12:00
# 不允许发布的时间窗口,跟上面这个不能同时存在,同时存在以 deploy_window 为准
no_deploy_window:
- 9:00 ~ 17:00
# 提供流水线的发布环境选项
envs:
- test1
- test4
- name: integration
need_approval: "yes"
- name: pre
need_approval: "yes"
- name: prod
# 是否需要审批,如果有 manual job 只限制 manual job,否则限制当前流水线所有 job
need_approval: "yes"
# 是否受发布时间窗口限制,如果有 manual job 只限制 manual job,否则限制当前流水线所有 job
deploy_window_limit: "yes"
# 当前 pipeline 所需的 stage,按序从上至下执行
stages:
- lint
- test
- build
- deploy
- final
prepare_dependencies:
stage: prepare
cache:
key: yarn.lock
paths:
- node_modules
# 下载缓存
policy: pull
# 如果有 cache 跳过脚本
skip_scripts_if_found: "yes"
script:
- echo "This job only downloads cache"
- echo "Downloading dependencies..."
- yarn
# 单个 job
lint_code:
# job 属于哪个 stage
stage: lint
# job 运行时执行的 shell 脚本
script: npm run lint
test_node_12:
# job 执行依赖的 docker image,覆盖全局默认的 image
image: node:12
stage: test
# 可以有多行 script,按序从上至下执行,
# 任一 script 执行后 exitCode 非 0,则终止 job 的执行,job failed
script:
- uname -a
- echo 'hello'
test_node_14:
image: node:14
stage: test
script: echo 'node 14'
build_code:
stage: build
script: npm run build
# job 进入 pipeline 需满足的条件
rules:
- if $PULSE_CI_DEPLOY_ENV != "prod"
# job 执行后的产物
artifacts:
# 产物的路径
paths:
- dist/
build_code_prod:
stage: build
script: npm run build:prod
rules:
- if $PULSE_CI_DEPLOY_ENV == "prod"
artifacts:
paths:
- dist/
deploy_to_test:
stage: deploy
image: deploy_scp_image
script: echo "deploy to test"
rules:
- if $CI_TRIGGER_ENV != prod
cache-job:
stage: final
script:
- echo "This job builds a cache."
cache:
key: yarn.lock
paths:
- node_modules
# 上传缓存
policy: push
deploy_to_prod:
stage: deploy
image: deploy_oss_image
script: echo "deploy to prod"
rules:
- if $CI_TRIGGER_ENV == prod
# job 不会自动执行,需要手动触发
when: manual