LESSON 20分

継続的インテグレーション(CI)

ストーリー

木村先輩がホワイトボードに「CI」と大きく書いた。

「CI -- Continuous Integration、継続的インテグレーションだ。 これはCI/CDの土台になる考え方だから、しっかり押さえておこう」

「インテグレーション......統合ですか?」

「そうだ。開発者全員のコードを頻繁に統合(マージ)して、 その都度自動でテストを走らせる。 これだけで、うちのチームが抱えている問題の半分以上が解決する」

「半分以上......そんなに効果があるんですか?」

「マージの頻度が上がれば、コンフリクトは小さくなる。 テストが自動で走れば、バグは早期に見つかる。 地味だけど、これが開発チームの生産性を根本から変えるんだ」


CIの基本原則

CIとは

継続的インテグレーション(CI)とは、開発者がコードの変更を頻繁にメインブランチに統合し、統合のたびに自動テストを実行することで、問題を早期に検出するプラクティスです。

CIの5つの原則

原則説明
頻繁なマージ最低でも1日1回はメインブランチにマージする
自動テストマージのたびに自動でテストスイートを実行する
即座のフィードバックテスト結果を数分以内に開発者に通知する
ビルドの修復優先ビルドが壊れたら最優先で修復する
全員の責任CIの維持はチーム全員の責任である

CIがない世界 vs CIがある世界

CIがない場合:インテグレーション地獄

週1回のマージ(CI なし)

月曜          金曜
 │              │
 ├── 開発者A: 500行の変更 ──→ マージ
 ├── 開発者B: 300行の変更 ──→ マージ  ← コンフリクト大量発生!
 ├── 開発者C: 400行の変更 ──→ マージ  ← さらにコンフリクト!
 │              │
 │         結合テスト
 │         → バグ大量発見
 │         → 原因調査に時間がかかる
 │         → リリース延期......

CIがある場合:小さな変更を頻繁にマージ

1日に複数回のマージ(CI あり)

 開発者A: 50行の変更 → push → 自動テスト OK → マージ
 開発者B: 30行の変更 → push → 自動テスト OK → マージ
 開発者A: 40行の変更 → push → 自動テスト NG → 即修正 → OK → マージ
 開発者C: 20行の変更 → push → 自動テスト OK → マージ

 → コンフリクトは小さく、バグは早期発見
 → リリースは予定通り

CIパイプラインの構成

典型的なCIパイプラインは以下のステージで構成されます。

CIパイプライン

git push
  │
  ▼
┌──────────────────────────────────────────┐
│  Stage 1: コード品質チェック                  │
│  ┌────────┐  ┌──────────┐  ┌──────────┐ │
│  │ Lint    │  │ Format    │  │ Type     │ │
│  │ (ESLint)│  │ (Prettier)│  │ Check(TS)│ │
│  └────────┘  └──────────┘  └──────────┘ │
└──────────────────┬───────────────────────┘
                   │ OK
                   ▼
┌──────────────────────────────────────────┐
│  Stage 2: テスト実行                        │
│  ┌──────────┐  ┌──────────┐              │
│  │ 単体テスト  │  │ 結合テスト │              │
│  │ (Jest)     │  │ (Supertest)│              │
│  └──────────┘  └──────────┘              │
└──────────────────┬───────────────────────┘
                   │ OK
                   ▼
┌──────────────────────────────────────────┐
│  Stage 3: ビルド                            │
│  ┌──────────┐  ┌──────────┐              │
│  │ Compile   │  │ Docker    │              │
│  │ (tsc)     │  │ Build     │              │
│  └──────────┘  └──────────┘              │
└──────────────────┬───────────────────────┘
                   │ OK
                   ▼
              [ビルド成功!]
              アーティファクト保存

各ステージの詳細

Stage 1: コード品質チェック(1〜3分)

yaml
# ESLint でコードスタイルチェック
npx eslint src/ --ext .ts,.tsx

# Prettier でフォーマットチェック
npx prettier --check "src/**/*.{ts,tsx}"

# TypeScript の型チェック
npx tsc --noEmit

Stage 2: テスト実行(2〜10分)

yaml
# 単体テスト
npx jest --coverage

# 結合テスト
npx jest --config jest.integration.config.js

Stage 3: ビルド(3〜10分)

yaml
# TypeScript コンパイル
npx tsc

# Docker イメージビルド
docker build -t myapp:latest .

CIのフィードバックループ

CIの最大の価値は「素早いフィードバック」です。

フィードバックループ

  ┌─────── 数分で結果がわかる ───────┐
  │                                   │
  ▼                                   │
[コード変更] → [push] → [CI実行] → [結果通知]
                                      │
                            ┌────────┴────────┐
                            ▼                  ▼
                        [成功]              [失敗]
                     マージ可能         → 修正してre-push
                                        → 失敗箇所が明確
                                        → 小さな変更なので
                                          原因特定が容易

フィードバックの通知方法

方法ツール例特徴
GitHub PR ステータスチェックGitHub ActionsPRに直接結果が表示される
Slack 通知Slack Integrationチーム全体に共有
メール通知GitHub Notifications個人に直接通知
ダッシュボードGrafana, DataDogチーム全体の状態を可視化

CIのアンチパターン

よくある失敗パターンを把握しておきましょう。

アンチパターン問題対策
遅いCIパイプラインフィードバックが遅く開発が停滞10分以内を目標にする
テストが不安定(Flaky)同じコードで成功/失敗が変わる不安定なテストを特定し修正する
ビルド失敗の放置壊れたまま新しい変更が積まれる「ビルド修復は最優先」ルールを徹底
大きなPR変更が大きくレビューもテストも困難小さなPRに分割する
テストなしのCICIがあっても品質が保証されないテストカバレッジの基準を設ける

まとめ

ポイント内容
CIとはコードを頻繁にマージし、自動テストで品質を担保するプラクティス
核心小さな変更を頻繁にマージすることでリスクを小さくする
フィードバックテスト結果を数分以内に開発者に返す
アンチパターン遅いCI、Flakyテスト、ビルド失敗の放置は要注意

チェックリスト

  • CIの5つの原則を説明できる
  • CIがない場合の問題点を理解した
  • CIパイプラインの典型的なステージ構成を把握した
  • CIのアンチパターンを3つ以上挙げられる

次のステップへ

次のセクションでは、CI/CDの「CD」の部分 -- 継続的デリバリー/デプロイの概念を学びます。 CIで品質を担保したコードを、いかに安全に本番環境へ届けるかを理解しましょう。


推定読了時間: 20分