継続的インテグレーション(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 --noEmitStage 2: テスト実行(2〜10分)
yaml
# 単体テスト
npx jest --coverage
# 結合テスト
npx jest --config jest.integration.config.jsStage 3: ビルド(3〜10分)
yaml
# TypeScript コンパイル
npx tsc
# Docker イメージビルド
docker build -t myapp:latest .CIのフィードバックループ
CIの最大の価値は「素早いフィードバック」です。
フィードバックループ
┌─────── 数分で結果がわかる ───────┐
│ │
▼ │
[コード変更] → [push] → [CI実行] → [結果通知]
│
┌────────┴────────┐
▼ ▼
[成功] [失敗]
マージ可能 → 修正してre-push
→ 失敗箇所が明確
→ 小さな変更なので
原因特定が容易
フィードバックの通知方法
| 方法 | ツール例 | 特徴 |
|---|---|---|
| GitHub PR ステータスチェック | GitHub Actions | PRに直接結果が表示される |
| Slack 通知 | Slack Integration | チーム全体に共有 |
| メール通知 | GitHub Notifications | 個人に直接通知 |
| ダッシュボード | Grafana, DataDog | チーム全体の状態を可視化 |
CIのアンチパターン
よくある失敗パ ターンを把握しておきましょう。
| アンチパターン | 問題 | 対策 |
|---|---|---|
| 遅いCIパイプライン | フィードバックが遅く開発が停滞 | 10分以内を目標にする |
| テストが不安定(Flaky) | 同じコードで成功/失敗が変わる | 不安定なテストを特定し修正する |
| ビルド失敗の放置 | 壊れたまま新しい変更が積まれる | 「ビルド修復は最優先」ルールを徹底 |
| 大きなPR | 変更が大きくレビューもテストも困難 | 小さなPRに分割する |
| テストなしのCI | CIがあっても品質が保証されない | テストカバレッジの基準を設ける |
まとめ
| ポイント | 内容 |
|---|---|
| CIとは | コードを頻繁にマージし、自動テストで品質を担保するプラクティス |
| 核心 | 小さな変更を頻繁にマージすることでリスクを小さくする |
| フィードバック | テスト結果を数分以内に開発者に返す |
| アンチパターン | 遅いCI、Flakyテスト、ビルド失敗の放置は要注意 |
チェックリスト
- CIの5つの原則を説明できる
- CIがない場合の問題点を理解した
- CIパイプラインの典型的なステージ構成を把握した
- CIのアンチパターンを3つ以上挙げられる
次のステップへ
次のセクションでは、CI/CDの「CD」の部分 -- 継続的デリバリー/デプロイの概念を学びます。 CIで品質を担保したコードを、いかに安全に本番環境へ届けるかを理解しましょう。
推定読了時間: 20分