CI/CD
テストとデプロイを自動化し、変更を小さく速く届け続ける開発の仕組み。
概要
CI/CDは、コードの変更がユーザーに届くまでの道のりを自動化する仕組みの総称です。CI(Continuous Integration: 継続的インテグレーション)は、開発者が変更をGitにpushするたびに自動でビルドとテストを走らせ、壊れた変更を即座に検出する実践。CD(Continuous Delivery/Deployment: 継続的デリバリー/デプロイ)は、検証を通過した変更を自動で本番環境まで届ける実践です。
この一連の自動化された流れを「パイプライン」と呼びます。GitHub Actions、GitLab CI、CircleCIなどのサービスで構築するのが現在の主流で、「pushしたら数分後には本番に反映されている」という開発体験は、規模を問わず現代のチームの標準装備になっています。
なぜ生まれたか
かつてのソフトウェア開発では、各開発者が数週間〜数か月分の変更を抱え込み、リリース前にまとめて統合(インテグレーション)していました。すると大量の変更が一斉に衝突し、「統合地獄」と呼ばれる修羅場が発生します。どの変更が原因でビルドが壊れたのか分からず、リリース前の数週間が火消しに費やされる — この苦痛への反省から、「統合が痛いなら、毎日・毎コミットやって痛みを小さくしよう」という逆転の発想が生まれました。これがCIです。
デプロイも同様でした。手順書を見ながら深夜に手作業でファイルを配置するリリース作業は、ミスが起きやすく、怖いからこそ頻度が下がり、頻度が下がるから1回あたりの変更が膨らんでさらに怖くなる、という悪循環に陥ります。デプロイを自動化・日常化して変更を小さく保てば、バグの原因特定は容易になり、問題があってもすぐ戻せる。「リリースは怖い儀式」から「1日に何度でも行う日常」への転換がCDの本質です。
詳細
パイプラインの流れ
典型的なパイプラインは、Gitへのpushやプルリクエストをトリガーに起動します。まずコードを取得してビルドし、静的解析(lint)と自動テストを実行。すべて通過したらデプロイ可能な成果物 — 近年はコンテナイメージが主流 — を作成し、レジストリに登録します。そこからステージング環境への配備、必要なら承認を挟んで、本番へのデプロイへと進みます。どこか1段でも失敗すればパイプラインは止まり、開発者に即座に通知されます。「壊れたものは決して先へ進まない」という関所の連なりがパイプラインの本質です。
DeliveryとDeploymentの違い
CDには2つの流儀があります。継続的デリバリーは「いつでも本番に出せる状態を常に維持する」ところまでを自動化し、最後の本番反映だけは人間がボタンを押す方式。継続的デプロイメントは、その最後の判断も自動化し、テストを通過した変更が人手を介さず本番まで流れる方式です。どちらを選ぶかはビジネスの性質次第で、リリースのタイミングを制御したい場合はデリバリー、変更の流量を最大化したい場合はデプロイメントが向きます。重要なのはどちらも「本番に出せない期間を作らない」ことを目指している点です。
安全に届けるためのデプロイ戦略
自動でどんどん本番に流すからこそ、失敗時の被害を抑える工夫が発達しました。新旧2系統の環境を用意して切り替えるブルーグリーンデプロイ、一部のユーザーにだけ新版を当てて様子を見るカナリアリリース、ロードバランサの背後のサーバを少しずつ入れ替えるローリングアップデートなどです。またデプロイ後の異常を素早く検知するには監視との連携が不可欠で、エラー率の急増を検知して自動でロールバックする構成まで組めば、パイプラインは「届ける」だけでなく「守る」仕組みになります。
実務での勘所と落とし穴
CI/CDの価値はテストの質に大きく依存します。テストが薄ければ「壊れたコードが高速で本番に届くだけの装置」になりかねません。逆にテストが遅すぎるとパイプラインが渋滞し、開発のリズムを壊します。10分以内に結果が返ることを目安に、テストの粒度と並列化を設計するのが定石です。
また、パイプラインの設定ファイル(GitHub Actionsなら .github/workflows/ のYAML)もコードとしてリポジトリで管理されるため、レビューや履歴管理の対象になります。この「手順をコード化して自動実行する」という思想はインフラ構成に適用するとIaCになり、両者を組み合わせれば「アプリもインフラもpush一発で更新される」という現代的な開発基盤が完成します。秘密情報(デプロイ用の認証情報など)をパイプラインにどう安全に渡すか、本番デプロイの権限を誰に与えるかといったセキュリティ設計も、実運用では避けて通れない論点です。