利用复用简化配置文件

# 介绍

利用好复用,可以极大提升我们的代码质量和工作效率。 云原生构建 采用 YAML 编写配置文件,其本身支持一定程度的变量声明和复用,但不支持 跨文件的复用

当团队、项目规模大到一定程度,流水线模版、敏感数据拆分到不同文件以及触发不同项目流水线是非常必要的。 云原生构建YAML 基础上扩展实现了不同用途的跨文件复用功能:

  • 变量引用
  • 模版引用
  • 变量替换

这些功能分散在文档不同地方,这篇教程将这些不同用途的复用放在一起介绍,以期便于大家的理解,能根据实际场景灵活使用。

# 变量引用

一些 敏感数据 比如 账号密码、令牌等直接硬编码到配置文件,数据泄露的风险较大。

对于这种情况,可以将敏感数据放在另一个项目文件中,控制好权限,在变量声明文件中配置可引用该文件的 仓库白名单。流水线配置文件里通过 imports 引用变量声明文件,然后通过环境变量的形式使用。

示例:

敏感数据文件

USER_NAME: xxx
USER_EMAIL: xxx
LOGIN_USER_NAME: xxx
LOGIN_PASSWORD: xxx
# 只允许 team 团队下 project 里的仓库流水线引用
allow_slugs: team/project/*

在配置文件中引用,声明到环境变量

master:
  push:
    - stages:
        - name: set token
          imports: https://xxx.com/token.yml
          image: tencentcom/git-set-credential:latest
          settings:
            userName: ${USER_NAME}
            userEmail: ${USER_EMAIL}
            loginUserName: ${LOGIN_USER_NAME}
            loginPassword: ${LOGIN_PASSWORD}
        - name: show git operation
          script:
            - echo add file
            - echo commit file
            - echo push file

imports 类似的还有 settingsFrom,用于插件任务的参数引用。不同点在于:变量声明文件可额外配置 插件白名单

# 模版引用

一个很常见的团队 CI 场景是,定义好一些通用流水线模版,然后其他流水线直接引用。

比如一个项目里有很多同类型仓库,流水线的需求也是一样的:

那完全可以编写一个通用的流水线模版

template.yml

master:
  push:
    - stages:
        - name: install
          script: echo install
        - name: lint
          script: echo lint
        - name: test
          script: echo test
        - name: compile
          script: echo compile
        - name: upload
          script: echo upload

然后其他项目直接引用即可

include:
  - https://xxx/template.yml

当然其他项目也可以有自己的流水线

include:
  - https://xxx/template.yml

master:
  push:
    - stages:
        - name: do something
          script: echo do something

include 会将两个配置文件的流水线进行 merge 操作,也就是 master 的 push 流水线会合并为两个,会同时执行,而不是覆盖。

# 变量替换

YAML 本身支持变量复用:

defaults: &defaults
  city: sz
  size: max

development:
  env: dev
  defaults: *defaults

test:
  env: test
  <<: *defaults

等同于

defaults:
  city: sz
  size: max
development:
  env: dev
  defaults:
    city: sz
    size: max
test:
  env: test
  city: sz
  size: max

但并不支持跨文件变量复用。

如果简单将两个配置文件合并再解析,容易出现语法问题,如多个同名变量。

云原生构建 通过扩展 include 将两个配置文件各自解析,再进行 merge 合并,同时扩展 YAML 自定义标签 reference 实现跨文件变量复用。

用法示例:任务复用

模版文件templage.yml

.common-stages:
  test:
    name: test
    script: echo test

.coding-ci.yml

include:
  - template.yml

master:
  push:
    - stages:
        - name: install
          script: echo install
        - !reference [".common-stages", "test"]

等同于

master:
  push:
    - stages:
        - name: install
          script: echo install
        - name: test
          script: echo test

referenct 用法,可以像 imports 将其他文件的变量用于当前流水线,但不推荐。因为 reference 是在 编译时解析,可以在流水线日志详情页中看到解析后的配置文件内容,也就是看到了引用文件中的变量值,不利于敏感数据保密。而 imports 是在配置文件解析后,流水线运行时,进行变量替换,流水线日志详情页看不到引用文件中的变量值。

也可以像 include 那样引用流水线模板,区别是 include 引用的流水线模版和当前主配置文件的流水线是 merge 合并,二者流水线都会保留,而 reference变量替换

TIP

另外还有 applytrigger 可以触发子流水线。

从使用场景看,有些场景是抽象通用流水线模版,供其他流水线调用,类似 includereference 的流水线复用。但本质上更适合理解为代码里的功能调用。