config.yml
を分割できる Orb を作ったよー
Split Config Orb という Orb を作った
こないだからちょこちょこ試してたやつを Orb にしたのだ。この Orb を使うと config.yml
を分割できる。Orb にしたから簡単に使えるよー!
config.yml
が大きいから分割したいー!って場合や、モノレポで複数サービスを入れてるから各サービスごとに config.yml
を書きたい!って場合に使えるかなぁって思ってる
もしちょっとでも興味があったら、実際に使ってみてフィードバックをいただけると嬉しいです。フィードバックを元にして機能をブラッシュアップできるといいなと思ってます!GitHub の Issue でも Twitter でメンションくれても OK です!
- GitHub Issue: Issues · bufferings/orb-split-config · GitHub
- Twitter: Mitsuyuki Shiiba (@bufferings) / Twitter
じゃ、さっそく使ってみようー!
簡単に使えるよー
こんな風に config.yml
を書いておくだけ!
version: 2.1 setup: true orbs: split-config: bufferings/split-config@0.1.0 workflows: generate-config: jobs: - split-config/generate-config: find-config-regex: .*/\.circleci/config\.yml
これで CircleCI が起動したときに、ここに書いてある正規表現にマッチする設定ファイルをかき集めてきて、ひとつにマージしてから、パイプラインを実行するのだ!
あ、その前に、いっこだけやっとくことがあるんだった!
ダイナミックコンフィグを有効化してね
マージした設定ファイルを使ってパイプラインを起動するのに ダイナミックコンフィグ という機能を使ってるのだけど、デフォルトではオフになってるので この手順にしたがって オンにしといてください!
おわりー!これだけー!以下は、他にこんなことができるよーとかの紹介
集めてくるファイルの指定方法
ファイルを集めてくるのには、↑の例みたいに正規表現で指定することもできるし、「そんなに変更されるわけじゃないから固定リストで指定したいなぁ」って人は↓こんな感じでも大丈夫
version: 2.1 setup: true orbs: # Please specify the latest version split-config: bufferings/split-config@1.2.3 workflows: generate-config: jobs: - split-config/generate-config: fixed-config-paths: | ./common/.circleci/config.yml ./service1/.circleci/config.yml ./service2/.circleci/config.yml ./service3/.circleci/config.yml
path-filtering Orb との組み合わせ
path-filtering という Orb を使うと、例えば、モノレポで複数のサービスがひとつのリポジトリに入ってて「変更があったサービスのワークフローだけ実行したいのだ!」みたいなことが実現できる。この path-filtering と組み合わせて使う場合はこんな感じ
version: 2.1 setup: true orbs: # Please specify the latest version split-config: bufferings/split-config@1.2.3 path-filtering: circleci/path-filtering@1.2.3 workflows: generate-config: jobs: - split-config/generate-config: find-config-regex: .*/\.circleci/.*\.yml generated-config-path: /tmp/generated_config.yml continuation: false post-steps: - persist_to_workspace: root: /tmp paths: - generated_config.yml - path-filtering/filter: workspace_path: /tmp config-path: /tmp/generated_config.yml mapping: | service1/.* build-service1 true service2/.* build-service2 true requires: - split-config/generate-config
やってるのは、マージした設定ファイルを path-filtering Orb に渡すってこと。ジョブ間の受け渡しになるので ワークスペース を使って渡してる
どうやってマージしてるの?
マージには CUE (https://cuelang.org/) を使ってる
CUE は設定用の言語みたいな感じで、型の定義だったり、モジュール化だったりと、色んなことができるんだけど、その中のほんとに一部の機能を利用してマージしてるのだ。使ってる機能は
というもの。これで、複数の YAML を取り込んでマージされた YAML を出力してる
例えば、こんな YAML と
version: 2.1 jobs: service1-say-hello: docker: - image: cimg/base:stable steps: - checkout - run: name: "Say hello" command: "echo Hello, World!1" workflows: service1-say-hello-workflow: jobs: - service1-say-hello
こんな YAML を
version: 2.1 jobs: service2-say-hello: docker: - image: cimg/base:stable steps: - checkout - run: name: "Say hello" command: "echo Hello, World!1" workflows: service2-say-hello-workflow: jobs: - service2-say-hello
マージすると、こうなる↓かしこいー!
❯ cue export service1.yml service2.yml --out yaml version: 2.1 jobs: service1-say-hello: docker: - image: cimg/base:stable steps: - checkout - run: name: Say hello command: echo Hello, World!1 service2-say-hello: docker: - image: cimg/base:stable steps: - checkout - run: name: Say hello command: echo Hello, World!1 workflows: service1-say-hello-workflow: jobs: - service1-say-hello service2-say-hello-workflow: jobs: - service2-say-hello
この CUE のマージの機能がかなり面白いので、興味ある方は、ぜひ CUE のドキュメントをチェックしてみてください!僕も、この辺りはもう少し細かく見ていきたいなって思ってる
制約
この Orb には、その仕組みに起因する制約があるので、注意してほしい
制約1: Workflow や Job の名前がかぶらないようにしないといけない
最終的には1つの YAML ファイルとして書き出す仕組みなので、名前が重複しちゃだめって制約がある
制約2: YAML のアンカーとエイリアスは、ひとつの YAML ファイル内で完結してる必要がある
CUE が YAML を読み込むときにアンカーとエイリアスを解析してしまうので、複数ファイルにまたがったアンカー・エイリアスは利用できない なので、あるファイルでアンカーを定義しておいて、別のファイルでエイリアスを使う、みたいなことはできない
興味がある人向け
この Orb は裏側で CUE を使ってはいるんだけど「使う人はできるだけ YAML のことしか考えなくていいようにしたい!」って思いながら作った
なので、YAML のことだけを考えてもらったら大丈夫なんだけど、実は CUE ファイルを渡しても読み込んでくれて、最終的には YAML で出力される。だから、実は CircleCI の設定を CUE で定義することもできてしまうのだー。こんなふうに↓
package config version: "2.1" jobs: { "service1-say-hello": { docker: [ {image: "cimg/base:stable"}, ] steps: [ "checkout", { run: { name: "Say hello" command: "echo Hello, World!1" } }, ] } } workflows: { "service1-say-hello-workflow": { jobs: [ "common-say-hello", "service1-say-hello", ] } }
で、config.yml
で cue
ファイルを読み込むようにしてあげれば OK
version: 2.1 setup: true orbs: # Please specify the latest version path-filtering: circleci/path-filtering@1.2.3 workflows: generate-config: jobs: - split-config/generate-config: find-config-regex: .*/\.circleci/config\.cue
CUE の機能を使って何か面白いことできないかなぁ?ってのにちょっとだけ興味あるから、これも遊んでみようかなぁって思ってる
Working Example
って、ここまで書いたようなことを、GitHub の README に書いてるからよかったらチェックしてみてくださいー
で、それぞれの例のところに、実際にそれを使った Example Project へのリンクがあるから、どんな感じか見てみたい方はどうぞ!
使ってみてー!
使ってみてくれたら嬉しいー!フィードバックくれたらもっと嬉しいー!
大阪のミートアップで喋りますー
来週の 7/27(水) に大阪でオフラインミートアップを開催する予定なんですけど、そこで、この Orb の紹介をしようと思いますー!よかったら来てください!(ただ、いま COVID-19 の感染者がどんどん増えている状況なので、中の人とよく相談して考えたいと思ってます