開発環境
> yq --version yq (https://github.com/mikefarah/yq/) version 4.25.2
モチベーション
CircleCIで複数YAMLを扱う場合はDynamic Configurationを利用し、その際に複数YAMLを1つのYAMLに統合する必要がある。今回はyqを使って2つのYAMLを統合してみる。
使用するYAML
android.yml
version: 2.1 jobs: android-job: docker: - image: cimg/base:stable steps: - checkout - run: "echo Android!" workflows: android-workflow: jobs: - android-job
ios.yml
version: 2.1 parameters: ios-manual: type: boolean default: false jobs: ios-job: docker: - image: cimg/base:stable steps: - checkout - run: "echo iOS!" workflows: ios-workflow: when: << pipeline.parameters.ios-manual >> jobs: - ios-job
ゴール
version
の記載を1行のみ追加する- ios.yml の
parameter
をコピーする jobs
配下に両ファイルのjobs
をコピーするworkflows
配下に両ファイルのworkflows
をコピーする
単純な統合
> yq android.yml ios.yml > merged.yml
version: 2.1 jobs: android-job: docker: - image: cimg/base:stable steps: - checkout - run: "echo Android!" workflows: android-workflow: jobs: - android-job --- version: 2.1 parameters: ios-manual: type: boolean default: false jobs: ios-job: docker: - image: cimg/base:stable steps: - checkout - run: "echo iOS!" workflows: ios-workflow: when: << pipeline.parameters.ios-manual >> jobs: - ios-job
yq を使った最もシンプルなYAML結合。version
や jobs
などが重複していたり、仕切り線(---
) があって消したい。
eval-all と reduce を組み合わせる
直前の問題は表題を使えば解決できた。
> yq eval-all '. as $item ireduce ({}; . * $item)' android.yml ios.yml > merged.yml
version: 2.1 jobs: android-job: docker: - image: cimg/base:stable steps: - checkout - run: "echo Android!" ios-job: docker: - image: cimg/base:stable steps: - checkout - run: "echo iOS!" workflows: android-workflow: jobs: - android-job ios-workflow: when: << pipeline.parameters.ios-manual >> jobs: - ios-job parameters: ios-manual: type: boolean default: false
- eval-all: YAMLの読み込み処理を逐次ではなく、一度にすべてのYAMLを読み込んでから実行する
- reduce: eval-all と組み合わせて使うと同じkey名のvalueを集約できる
- reduceではなくてireduceと記述する理由: https://mikefarah.gitbook.io/yq/operators/reduce#yq-vs-jq-syntax
ゴールが満たせていい感じに結合ができた。
一点だけ、同じkeyでもvalueが異なる場合(version
が2.1だったり2.2だったりする場合)は後続の評価が優先されるところは注意する必要がありそう。