こんにちは!日々のCI/CDパイプラインの構築や、巨大化していく設定ファイルとの格闘、本当にお疲れ様です。
プロジェクトが成長するにつれて、`.circleci/config.yml` が数百行、あるいは千行を超える「モンスターファイル」になっていませんか?
「フロントエンドしか変更していないのに、なぜかバックエンドの重いテストが走ってビルド枠を圧迫している……」
そんなモヤモヤを抱えているあなたに朗報です。
今回は、CircleCIの真骨頂である「Dynamic Configuration(動的設定生成)」と、その心臓部である `setup workflows` について、現場で即効性のある知見を交えて優しく解説します。
これをマスターすれば、設定ファイルが劇的に軽くなり、無駄なビルドコストをゴッソリ削ぎ落とせますよ。毎日の開発が本当に楽になります。一緒に見ていきましょう!
—
1. なぜ「設定ファイルの肥大化」と「無駄なビルド」が問題なのか?
大規模なモノレポ(単一のGitリポジトリに複数のサービスやアプリを同居させるスタイル)や、マイクロサービス群を管理していると、こんな問題に直面します。
- config.yml がカオス化する: 誰がどのジョブを触っているのか分かりにくくなり、マージコンフリクトの常連になる。
- リソースの無駄遣い(爆発的なコスト増): `README.md` を1文字直しただけなのに、全システムのテストとデプロイパイプラインがフル回転してしまう。
これに対する従来のハックは「変更されたファイルを検知して条件分岐するシェルスクリプトをゴリゴリ書く」という泥臭いものでした。しかし、CircleCIにはもっとエレガントで強力な公式の解決策があります。それが Dynamic Configuration です。
—
2. Dynamic Configuration とは何か?(ツールの役割)
一言でいうと、「最初に走る軽量な設定ファイルが、Gitの差分(変更内容)を読み取って、その場で『本当に必要なパイプラインの設定ファイル』を動的に生成して実行する仕組み」 です。
従来のCircleCIは、静的な `config.yml` をそのまま読み込んで実行していました。
しかし Dynamic Configuration を使うと、以下の2ステップで動きます。
1. Setup Workflow(第1段階): まず最小限の設定で動き、どのファイルが変更されたかをGitの差分から特定する。
2. Target Pipeline(第2段階): 特定結果に基づき、必要なジョブだけが定義された設定ファイルを動的に生成し、それにバトンタッチして実行する。
これにより、「変更のないモジュールのビルドを完全にスキップする」という、CI/CDの聖杯のような最適化が手に入ります。
—
3. 基礎セットアップ:動的生成を有効化する
まずは、CircleCI上でこの機能を使えるようにする初期設定です。と言っても、やることは非常にシンプルです。
① プロジェクトの設定で有効化する
CircleCIのWebダッシュボードから、対象プロジェクトの [Project Settings] > [Advanced Settings] に移動します。
- Dynamic Config のトグルを 「On」 にします。
これだけで、CircleCI側が動的な設定ファイルの生成を受け入れる準備完了です。
—
4. 実践!HelloWorld的な動的パイプラインの実装例
それでは、実際にコードを書いていきましょう。
今回は、「フロントエンド(`frontend/`)が変更された時だけフロントのビルドを走り、バックエンド(`backend/`)ならバックのビルドを走らせる」というケースを想定します。
ステップ1:エントリーポイントとなる設定ファイル
プロジェクトルートの `.circleci/config.yml` は、「動的設定を呼び出すためのルーター(Setup Workflow)」 として最小限の記述に絞ります。
version: 2.1
【重要】setup: true を宣言することで、このファイルをセットアップ用として扱います
setup: true
orbs:
path-filtering: circleci/path-filtering@1.1.0 # 変更パスを検知する公式オーブ
workflows:
# 第1段階:変更検知と動的設定の生成ワークフロー
generate-workflow:
jobs:
- path-filtering/filter:
name: check-changes
# デフォルトのターゲット設定ファイル(後述)を指定
config-path: .circleci/continue-config.yml
# 変更を監視するパスと、それに連動させるパラメータの定義
# パターンに一致した変更があると、パラメータに “true” が渡されます
mapping: |
frontend/. frontend-app-changed true
backend/. backend-app-changed true
ここがポイント:
`circleci/path-filtering` という公式オーブが、Gitのコミット履歴を自動解析し、「どのディレクトリが変わったか」を判定してくれます。超便利ですよね。
—
ステップ2:実際に実行される実体ファイル
次に、先ほどの `config-path` で指定した `.circleci/continue-config.yml` を作成します。これが、動的に呼び出される本命のパイプライン定義です。
version: 2.1
セットアップ時の path-filtering から受け取ったパラメータを定義
parameters:
frontend-app-changed:
type: boolean
default: false
backend-app-changed:
type: boolean
default: false
jobs:
build-frontend:
docker:
- image: cimg/node:18.0
steps:
- checkout
- run: echo “フロントエンドの変更を検知しました!ビルドを実行します。”
- run: cd frontend && npm install && npm run build
build-backend:
docker:
- image: cimg/openjdk:17.0
steps:
- checkout
- run: echo “バックエンドの変更を検知しました!テストを実行します。”
- run: cd backend && ./gradlew test
workflows:
conditional-workflow:
jobs:
# フロントエンドが変わっていた時だけ実行
- build-frontend:
filters:
branches:
only: main
# パラメータが true の場合のみこのジョブを有効化
when: << pipeline.parameters.frontend-app-changed >>
# バックエンドが変わっていた時だけ実行
- build-backend:
filters:
branches:
only: main
# パラメータが true の場合のみこのジョブを有効化
when: << pipeline.parameters.backend-app-changed >>
—
5. 動作確認:どう動くのか?
この構成をリポジトリにプッシュして、挙動を確認してみましょう。
1. ケースA: `frontend/index.js` だけを変更してプッシュ
- Setup Workflow が走る。
- Path Filtering が `frontend/` の変更を検知し、`frontend-app-changed = true`、`backend-app-changed = false` を `.circleci/continue-config.yml` に渡す。
- 結果:`build-frontend` のみが実行され、重いバックエンドのビルドは華麗にスキップされます!
2. ケースB: `README.md` だけを変更してプッシュ
- どちらの条件にもヒットしないため、両方のビルドがスキップされ、パイプラインは数秒で「Success」になります。ビルド枠の節約大成功です!
—
6. スペシャリストからの現場アドバイス(ハック)
最後に、この手法を実務の現場に導入する際の、ちょっとしたコツをお伝えします。
- ローカルでのテストには `circleci CLI` を活用する
Dynamic Configuration を含む設定は、ローカルでのバリデーション(`circleci config pack` や `validate`)でエラーが出やすい場合があります。パイプラインの文法ミスは小さく早く検知しましょう。
- パスの正規表現に慣れる
`path-filtering` オーブの `mapping` 部分の正規表現は強力です。例えば共通ライブラリ (`shared/`) が変更された時は、フロントとバックの両方のフラグを `true` にするような高度なルーティングも可能です。
—
まとめ
今回は、CircleCIの Dynamic Configuration を使って設定ファイルを軽量化し、無駄なビルドを徹底的に排除する方法を解説しました。
- `.circleci/config.yml` はルーター(Setup Workflow)として最小限に。
- 実体の処理は別ファイル(例: `continue-config.yml`)に分離。
- Path Filtering オーブで変更差分を検知し、必要なジョブだけを動的に実行。
この構成を導入するだけで、チーム全体の開発フィードバックループが劇的に高速化し、CircleCIのクレジット(コスト)も大幅に節約できます。
「設定ファイルがゴチャゴチャして手に負えない……」と悩んでいた方は、ぜひ次のスプリントで試してみてください。あなたの開発ライフが、もっと快適でエキサイティングなものになることを応援しています!