概要
本記事では CircleCI の設定ファイルを分割する方法を紹介します。
さらに path-filtering orb を適用して対応するファイルを変更したときだけジョブが実行されるようにしています。
記事内に出てくる設定ファイルは次の repository に置いてあります。
https://github.com/algas/circleci-split-example
対象読者
- CircleCI をすでに使っている人
CircleCI 自体の基本的な使い方は本記事では説明しません。
基本的な使い方を知りたい方は公式サイトもしくは他の記事をご参照ください。
背景
CircleCI の設定ファイルが肥大化して困っていませんか?
現時点では CircleCI の設定ファイルを標準機能を使って分割することができないので、プロジェクトが大きくなるとともに設定ファイルも大きくなってしまいます。
公式の FAQ には次のように書かれています。
Is it possible to split the config.yml into different files?
Splitting config.yml into multiple files is not yet supported.
しかし、設定を工夫することで分割された設定ファイルを CircleCI に読み込ませることができます。
本記事では分割された設定ファイルを CircleCI に適用する方法を紹介します。
ファイル構成
CircleCI の設定ファイルを複数のアプリケーションもしくはライブラリごとに分割したいものとします。
ここでは foo と bar という2つの package があると考えます。
(実際にはこれより多くの package が repository に含まれることを想定しています)
- packages:
- foo: (your app1)
- bar: (your app2)
- .circleci:
- config.yml (main config)
- workflows: (splitted config files)
- _base.yml (config template)
- packages:
- foo.yml (config for package "foo")
- bar.yml (config for package "bar")
worklows/packages/
以下に各 package に対応した設定ファイルをそれぞれ置きます。
解説
CircleCI のデフォルト設定では .circleci/config.yml
が呼び出されます。
.circleci/config.yml
は次のような内容です。
version: 2.1
setup: true
orbs:
path-filtering: circleci/path-filtering@0.0.2
jobs:
setup:
docker:
- image: cimg/go:1.18.3 # yq のために golang の image を使います
steps:
- checkout
- run:
name: Install yq4 # yaml ファイルをマージするために yq4 をインストールします
command: |
go install github.com/mikefarah/yq/v4@latest
yq --version
- run:
name: Merge config files # workflows 以下の yaml ファイルをマージします
command: |
mkdir -p /tmp/workspace
yq eval-all '. as $item ireduce ({}; . * $item )' ./workflows/_base.yml ./workflows/packages/*.yml > /tmp/workspace/merged.yml
cat /tmp/workspace/merged.yml
- persist_to_workspace:
root: /tmp/workspace
paths:
- merged.yml
workflows:
filter:
jobs:
- setup
- path-filtering/filter:
requires:
- setup
pre-steps:
- attach_workspace:
at: /tmp/workspace
base-revision: main
config-path: /tmp/workspace/merged.yml
mapping: |
packages/foo/.* run-foo true
packages/bar/.* run-bar true
setup
という job では設定ファイルをマージするために yq (v4) をまずインストールします。次に、インストールした yq を使って workflows/
以下に置いてある設定ファイルを CI 実行時に動的に1つのファイル (/tmp/workspace/merged.yml
) にマージして config.yml から呼び出します。
yq eval-all
というコマンドを使って YAML をマージする方法は公式リファレンスに書かれています。
https://mikefarah.gitbook.io/yq/operators/reduce#merge-all-yaml-files-together
ここではテンプレートファイル _base.yml
に各 package の設定ファイルをマージするようにしています。
version: 2.1
parameters:
jobs:
workflows:
parameters:
run-foo:
type: boolean
default: false
jobs:
foo:
docker:
- image: cimg/base:2021.04
steps:
- checkout
- run:
name: The First Foo Step
command: |
echo 'Hello World!'
echo 'foo package'
workflows:
foo:
when: << pipeline.parameters.run-foo >>
jobs:
- foo
マージした設定ファイルは persist_to_workspace
を使って呼び出し先の job (path-filtering/filter
) でも使えるようにします。
setup
の次に path-filtering/filter
の job が実行されます。requires
に setup
を指定することで setup
の後に path-filtering/filter
が実行されるようになっています。さらに pre-steps
に attach_workspace
を設定してマージしたファイルを参照できるようにしています。
path-filtering/filter
は job を実行する条件を設定するための orb です。ここでは packages/foo
以下のファイルが変更されたときだけ workflows/packages/foo
に書いてある foo
の job が実行されるように設定しています。これは .circleci/config.yml
の path-filtering/filter
の mapping
に書いてあります。bar
も foo
と同じ設定になっています。
path-filtering orb の詳細は公式リファレンスを参照してください。
https://circleci.com/developer/orbs/orb/circleci/path-filtering
その他の設定
- 実運用するには CircleCI と (GitHub などの) Git repository を連携します
Git repository へのコードの反映に連動して CI が実行されます。連携方法自体はここには書きません。 - CircleCI で dynamic config を有効にする必要があります
"Project Settings" > "Advanced" > "Enable dynamic config using setup workflows" を ON にします。
https://circleci.com/docs/2.0/dynamic-config/#getting-started-with-dynamic-config-in-circleci
本記事に書かなかったこと
- path-filtering を使わない場合の CircleCI のファイル分割の方法
continuation orb を使えばできるはず
参考文献
まとめ
- CircleCI で設定ファイルを分割する方法を紹介しました。
- path-filtering を使って特定のファイルを変更したときだけ CI の job が実行される設定も解説しました。