# You Don't Know CNB YAML 不知道是否有用疑问,当您监听的事件越来越多: * .cnb.yml 越来越长 * .cnb.yml 越来越繁琐 * 总是复制一大坨相同的内容 此时您不尽感叹道【我可不想当 YAML 工程师】。 ## .cnb.yml 代码提示和语法校验 [配置在 VSCode 和 Jetbrains 种配置 JSON Schema](https://docs.cnb.cool/zh/configuration.html) ## YAML 的复用 这里将介绍 YAML 的锚点(Anchors)和别名(Aliases),来帮助我们编写出可复用的 YAML 问题提升 YAML 的可维护性。 在阅读下面文章前,必须提前推荐两个 YAML 在线解析工具(两个工具无区别),帮助我们识别使用锚点后我们的 YAML 是否符合预期: - [https://yaml-online-parser.appspot.com/](https://yaml-online-parser.appspot.com/) ### 场景一: 一次 main push 事件分别在 amd 和 arm 中构建 优化前: ``` main: push: - name: amd runner: tags: cnb:arch:amd64 services: - docker stages: - name: uname script: uname -a - name: hello world script: echo "hello world" - name: arm runner: tags: cnb:arch:arm64:v8 services: - docker stages: - name: uname script: uname -a - name: hello world script: echo "hello world" ``` 优化 1: ``` # 锚点推荐 . 开头避免被识别成 branch 和 tag 名称 .build_script: &build_script - name: uname script: uname -a - name: hello world script: echo "hello world" main: push: - name: amd runner: tags: cnb:arch:amd64 services: - docker stages: *build_script - name: arm runner: tags: cnb:arch:arm64:v8 services: - docker stages: *build_script ``` 优化 2: ``` # 锚点推荐 . 开头避免被识别成 branch 和 tag 名称 .build_script: &build_script services: - docker stages: - name: uname script: uname -a - name: hello world script: echo "hello world" main: push: - name: amd runner: tags: cnb:arch:amd64 services: - docker <<: *build_script - name: arm runner: tags: cnb:arch:arm64:v8 <<: *build_script ``` 我们可以将优化有的 YAML 放入到 YAML 在线解析网站种进行查看确认是否符合预期。 通过对比优化 1 和优化 2 可以发现,它们使用锚点的的力度不同。同时引入的了一个新的语法符号 `<<` 合并对象。 这里我们一个使用了三个语法符号: 1. 锚点 `&` 2. 引用 `*` 3. 对象合并 `<<`(不可用于数组中) ## 场景二: main 分支和 develop 分支需要使用不同的环境变量 优化前: ``` main: push: - name: amd runner: tags: cnb:arch:amd64 services: - docker env: SSH_USERNAME: username SSH_PASSWORD: password SSH_IP: production_ip stages: - name: uname script: uname -a - name: echo ssh ip script: echo $SSH_IP develop: push: - name: amd runner: tags: cnb:arch:amd64 services: - docker env: SSH_USERNAME: username SSH_PASSWORD: password SSH_IP: test_ip stages: - name: uname script: uname -a - name: echo ssh ip script: echo $SSH_IP ``` 优化后: ``` .services_and_imports: &services_and_imports services: - docker imports: - ./xxx.yml .common_envs: &common_envs SSH_USERNAME: username SSH_PASSWORD: password SSH_IP: production_ip .develop_envs: &develop_envs DEVELOP: true .production_envs: &production_envs PRODUCTION: true .uname_script: &uname_script name: uname script: uname -a main: push: - name: amd runner: tags: cnb:arch:amd64 <<: *services_and_imports env: <<: [ *common_envs, *production_envs ] stages: - *uname_script - name: echo ssh ip script: echo $SSH_IP develop: push: - name: amd runner: tags: cnb:arch:amd64 env: <<: *common_envs <<: *develop_envs <<: *common_envs stages: - *uname_script - name: echo ssh ip script: echo $SSH_IP ```