こんにちは!普段のフロントエンド開発やバックエンド開発で、「テストやデプロイをもっと自動化して、楽をしたいな」と思ったことはありませんか?
そんなあなたの強い味方になるのが、世界中で愛されているCI/CDサービス「CircleCI(サークルシーアイ)」です。
CI/CD(継続的インテグレーション/継続的デリバリー)は、今やモダンな開発現場では欠かせない技術です。しかし、いざ導入してみると「特定のブランチのときだけデプロイしたい」「複数のNode.jsバージョンでテストしたいけれど、設定ファイル(`config.yml`)がコピペだらけでパンクしそう…」という壁にぶつかりがちです。
でも、安心してください。
この記事では、CircleCIの強力な機能である`when`(条件分岐)、`unless`(否定の条件分岐)、そして設定ファイルのコピペを撲滅する`matrix`(マトリクス実行)を徹底解説します。
これらをマスターすれば、あなたのパイプラインは驚くほどスマートになり、毎日の開発作業が劇的に楽になりますよ。先輩エンジニアと一緒に、一歩ずつ進めていきましょう!
—
1. CircleCIの役割と、最初の一歩(基礎セットアップ)
CircleCIとは?
CircleCIは、コードの変更(Gitへのプッシュなど)を検知して、自動で「ビルド」「テスト」「デプロイ」を実行してくれるクラウドサービスです。
手動でテストを実行する手間や、「ローカル環境では動いたのに本番環境で動かない!」といった事故を未然に防いでくれます。
最初のセットアップ:HelloWorldを動かそう!
まずは、CircleCIを動かすための最もシンプルな設定ファイルを作ってみましょう。
ステップ1: アカウント作成とリポジトリ連携
1. [CircleCIの公式サイト](https://circleci.com/)にアクセスし、GitHubやGitLabのアカウントでサインアップします。
2. CircleCIにログイン後、対象のプロジェクト(Gitリポジトリ)を選択し、「Set Up Project」をクリックします。
ステップ2: 設定ファイルの作成
プロジェクトのルートディレクトリに `.circleci` というフォルダを作成し、その中に `config.yml` という名前のファイルを作成します。これがCircleCIのすべての設計図になります。
まずは、最もシンプルな「Hello World」の設定を書いてみましょう。
.circleci/config.yml
version: 2.1 # CircleCIのバージョンを指定(現在は2.1が標準です)
ジョブ(個々の実行単位)を定義します
jobs:
say-hello:
docker:
# 実行環境として軽量なDockerイメージ(Node.js)を指定
- image: cimg/node:18.16.0
steps:
# コードをチェックアウト(取得)します
- checkout
# コマンドを実行します
- run:
name: 挨拶を叫ぶ
command: echo “Hello, CircleCI! これからよろしくね!”
ワークフロー(ジョブをどういう順番で動かすか)を定義します
workflows:
welcome-workflow:
jobs:
- say-hello
ステップ3: 動作確認
このファイルをGitでコミットし、GitHubなどのリモートリポジトリにプッシュしてください。CircleCIのダッシュボードを開くと、自動的にパイプラインが動き出し、緑色の「Success」マークが表示されるはずです!
これがすべての自動化の第一歩です。
—
2. 条件分岐の極意:`when` と `unless` で無駄な実行をスキップする
基本が動いたら、次は「スマートな制御」に挑戦しましょう。
現場ではよく、「テストは毎回実行したいけれど、本番環境へのデプロイは `main` ブランチにマージされたときだけ実行したい」という要望があります。これを実現するのが `when` と `unless` です。
パラメータと `when` を使った条件分岐
CircleCIでは、ワークフローやジョブに「パラメータ(引数)」を渡すことができます。その値によって実行するかどうかを制御します。
以下の例では、`deploy-job` というジョブを定義し、「`deploy-trigger` というパラメータが `true` の時だけ実行する」という制御をしています。
version: 2.1
jobs:
test-job:
docker:
- image: cimg/node:18.16.0
steps:
- checkout
- run: npm test
deploy-job:
docker:
- image: cimg/node:18.16.0
steps:
- checkout
- run:
name: 本番環境へのデプロイ
command: echo “本番環境へデプロイ中…”
workflows:
build-and-deploy:
jobs:
- test-job
# deploy-jobを呼び出しますが、条件(when)を指定します
- deploy-job:
# when句を使い、特定の条件が満たされたときだけ実行します
# ここでは「ブランチが main のときだけ」というフィルタリングをしています
filters:
branches:
only: main
ステップ内での `when` と `unless`
ジョブ全体をスキップするだけでなく、「ジョブの中の、特定のステップ(コマンド)だけを条件に応じて実行する」ことも可能です。
- `when`: 条件が 真(true) のときに実行
- `unless`: 条件が 偽(false) のときに実行(〜でない限り実行)
version: 2.1
自分でカスタマイズしたコマンドを定義します
commands:
conditional-welcome:
parameters:
is-admin:
type: boolean
default: false
steps:
# is-admin パラメータが true のときだけ実行
- when:
condition: << parameters:is-admin >>
steps:
- run: echo “管理者モードで実行中…”
# is-admin パラメータが false のときだけ実行(unless = 〜でなければ)
- unless:
condition: << parameters:is-admin >>
steps:
- run: echo “一般ユーザーモードで実行中…”
jobs:
job-with-conditions:
docker:
- image: cimg/node:18.16.0
steps:
# 管理者フラグを true にしてカスタムコマンドを呼び出す
- conditional-welcome:
is-admin: true
workflows:
conditional-flow:
jobs:
- job-with-conditions
これで、「開発中(ローカル風)は余計な通知を送らないけれど、本番ビルドのときだけSlack通知を送る」といった制御がスマートに書けるようになります。
—
3. DRYの極み:`matrix`(マトリクス機能)でコピペを撲滅する
プログラミングの大原則に DRY(Don’t Repeat Yourself:同じことを繰り返すな) があります。これはCI/CDの設定ファイルでも全く同じです。
例えば、開発しているライブラリが、Node.jsのバージョン `16`, `18`, `20` のすべてで正しく動作するかテストしたいとします。
もし `matrix` を知らなければ、以下のように同じようなジョブを3回もコピペして書く羽目になります。
⚠️ これはバッドパターン(コピペが多く、メンテナンスが地獄になります)
workflows:
bad-workflow:
jobs:
- test-node16
- test-node18
- test-node20
これでは、設定ファイルがどんどん肥大化してしまいますね。
そこで登場するのが `matrix` です!
Matrix(マトリクス)を使ったスマートなパラメータ化
Matrixを使うと、一つのジョブに対して複数の変数を掛け合わせて、自動的に複数のジョブを並列で生成・実行してくれます。
version: 2.1
jobs:
# パラメータを受け取る汎用的なテストジョブを定義します
test-on-version:
parameters:
node-version:
type: string
docker:
# パラメータで指定されたバージョンのNode.jsイメージを動的に使用します
- image: cimg/node:<< parameters:node-version >>
steps:
- checkout
- run:
name: 起動中のNode.jsバージョンを確認
command: node -v
- run:
name: テスト実行
command: npm test
workflows:
multi-version-test:
jobs:
# 1つのジョブに対して、matrix(マトリクス)を適用します
- test-on-version:
matrix:
parameters:
# ここに検証したいバージョンをリストアップするだけ!
# CircleCIが自動的に3つのジョブ(16.x, 18.x, 20.x)を並列で立ち上げてくれます
node-version: [“16.10.0”, “18.16.0”, “20.2.0”]
いかがでしょうか?
この `matrix` を使うだけで、記述量は最小限に抑えられ、後から「Node.js 22 も追加したいな」となった時も、リストに `”22.0.0″` を1行追加するだけで対応完了です。非常にエレガントですよね。
—
4. 現場で勝つための実践応用:条件分岐とMatrixの融合
最後に、ここまでに学んだ知識をすべて詰め込んだ、「現場でそのまま使える実践テンプレート」をご紹介します。
このテンプレートでは、以下の高度な制御を行っています。
1. Node.jsの複数バージョンで並列テストを実行(`matrix`)
2. テストが失敗した時だけ、デバッグ情報を出力する(ステップの `when: on_fail`)
3. テストがすべて成功し、かつ `main` ブランチの時だけデプロイを実行(`requires` と `filters`)
version: 2.1
jobs:
test:
parameters:
node-version:
type: string
docker:
- image: cimg/node:<< parameters:node-version >>
steps:
- checkout
- run:
name: 依存パッケージのインストール
command: npm install
- run:
name: テストの実行
command: npm test
# 💡 特殊なwhen: テストが「失敗したときだけ」システムログを保存する賢いステップ
- run:
name: 失敗時のデバッグ情報収集
command: |
echo “⚠️ テストが失敗しました。デバッグ情報を出力します。”
npm run debug-log || true
when: on_fail # 正常終了時はスキップされ、失敗時のみ動きます
deploy:
docker:
- image: cimg/node:18.16.0
steps:
- checkout
- run:
name: 本番デプロイ
command: echo “🚀 本番環境へのデプロイが完了しました!”
workflows:
pipeline:
jobs:
# 1. 複数バージョンでのテストを並列実行
- test:
matrix:
parameters:
node-version: [“18.16.0”, “20.2.0”]
# 2. テストが「すべて成功」し、かつ「mainブランチ」のときのみデプロイ
- deploy:
requires:
- test # testジョブ(マトリクスすべて)が成功することを必須条件にします
filters:
branches:
only: main # mainブランチのみで実行
—
まとめ:スマートなパイプラインは開発者を幸せにする
お疲れ様でした!
今回学んだテクニックをおさらいしましょう。
- `when` / `unless`: 状況に応じて、ジョブやステップの実行を賢くコントロールする。
- `matrix`: パラメータを掛け合わせることで、設定ファイルのコピペを撲滅し、DRYに保つ。
- `when: on_fail`: 失敗したときだけの特別処理をスマートに挟み込む。
これらを駆使することで、CircleCIの実行時間(ビルド時間)を節約し、無料枠の範囲内でも最大限のパフォーマンスを引き出すことができます。何より、シンプルで美しい設定ファイルは、チームメンバー全員のメンテナンス負荷を劇的に下げてくれます。
まずは小さなプロジェクトから、このスマートな条件分岐を取り入れてみてください。あなたの開発ライフが、これまで以上に快適になることを祈っています!