ストーリー
木村先輩が、過去のプロジェクトの失敗談を話し始めた。
パイプライン設計のベストプラクティス
1. 高速なフィードバック
CIパイプラインは10分以内を目標にしましょう。
graph TD
PUSH["push"] --> S1["Stage 1 (1分)<br/>Lint + 型チェック"]
S1 -->|"失敗"| N1["即通知<br/>コード修正を指示"]
S1 -->|"OK"| S2["Stage 2 (3分)<br/>単体テスト"]
S2 -->|"失敗"| N2["即通知<br/>テスト修正を指示"]
S2 -->|"OK"| S3["Stage 3 (5分)<br/>結合テスト + ビルド"]
S3 -->|"失敗"| N3["即通知"]
S3 -->|"OK"| S4["Stage 4 (並列)<br/>E2E + セキュリティスキャン"]
S4 --> N4["まとめて通知"]
classDef stage fill:#cce5ff,stroke:#004085,color:#000
classDef fail fill:#f8d7da,stroke:#dc3545,color:#000
classDef ok fill:#d4edda,stroke:#28a745,color:#000
class S1,S2,S3,S4 stage
class N1,N2,N3 fail
class N4 ok
合計: 約10分以内。最も速いチェックを最初に実行するフェイルファスト戦略。
2. パイプラインをコードとして管理
パイプラインの定義もバージョン管理の対象です。
| やること | やらないこと |
|---|---|
| YAMLファイルをGitで管理 | GUIだけで設定する |
| PRでパイプライン変更をレビュー | 直接本番のパイプラインを編集 |
| 環境ごとの差分を最小化 | 環境ごとに全く別のパイプラインを作る |
3. テストピラミッドを意識する
graph TD
E2E["E2Eテスト<br/>少数・遅い・高コスト<br/>10%"]
INT["結合テスト<br/>中程度の数<br/>20%"]
UNIT["単体テスト<br/>多数・速い・低コスト<br/>70%"]
E2E --> INT --> UNIT
classDef e2e fill:#f8d7da,stroke:#dc3545,color:#000
classDef int fill:#fff3cd,stroke:#856404,color:#000
classDef unit fill:#d4edda,stroke:#28a745,color:#000
class E2E e2e
class INT int
class UNIT unit
CIで実行するテスト配分:
- 単体テスト: 70%(高速、毎pushで実行)
- 結合テスト: 20%(中速、PRマージ時に実行)
- E2Eテスト: 10%(低速、デプロイ前に実行)
ブランチ戦略とCI/CD
トランクベース開発
CI/CDと最も相性が良いブランチ戦略です。
gitGraph
commit id: "main"
branch feature/a
commit id: "a-1"
commit id: "a-2"
checkout main
merge feature/a id: "merge-a"
branch feature/b
commit id: "b-1"
commit id: "b-2"
checkout main
merge feature/b id: "merge-b"
commit id: "main-2"
branch feature/c
commit id: "c-1"
commit id: "c-2"
checkout main
merge feature/c id: "merge-c"
特徴:
- 短命なフィーチャーブランチ(1~2日以内)
- mainに頻繁にマージ
- 全てのマージでCIが走る
GitHub Flow
GitHub Actionsとの組み合わせで広く使われています。
gitGraph
commit id: "main"
branch feature/login
commit id: "push→CI"
commit id: "push→CI "
commit id: "push→CI→PR作成"
checkout main
merge feature/login id: "マージ→CD"
commit id: "main-2"
毎pushでCI実行。PR作成 -> レビュー -> マージ -> CDの流れ。
セキュリティのベストプラクティス
シークレット管理
| やること | やらないこと |
|---|---|
| 専用のシークレットストアを使う | コードにAPIキーをハードコード |
| 環境変数で注入する | ログにシークレットを出力 |
| 定期的にローテーションする | 全環境で同じシークレットを使う |
| 最小権限の原則を適用する | 管理者権限のトークンを共有 |
サプライチェーンセキュリティ
graph LR
A["自分のコード"] --> B["依存パッケージ"]
B --> C["CI/CDツール"]
C --> D["デプロイ先"]
B -.- B1["脆弱性の混入<br/>バージョン固定で対策"]
C -.- C1["アクション乗っ取り<br/>SHA固定で対策"]
classDef risk fill:#f8d7da,stroke:#dc3545,color:#000
class B1,C1 risk
| 対策 | 説明 |
|---|---|
| 依存パッケージのバージョン固定 | package-lock.json を必ずコミット |
| アクションのSHA固定 | uses: actions/checkout@v4 より @sha256:... |
| 依存関係の自動更新 | Dependabot / Renovateで脆弱性を検知 |
| 最小権限のGITHUB_TOKEN | permissions を明示的に指定 |
チーム文化のベストプラクティス
ビルドが壊れたら最優先で直す
graph TD
A["ビルド失敗通知"] --> B{"誰がコミットした?"}
B -->|"自分"| C["即座に修正開始"]
B -->|"他の人"| D["声をかけて支援<br/>(放置しない)"]
classDef alert fill:#f8d7da,stroke:#dc3545,color:#000
classDef action fill:#d4edda,stroke:#28a745,color:#000
class A alert
class C,D action
ルール:
- ビルドが壊れている間は新しいマージをしない
- 15分で直せないなら revert する
- ビルド状態はチームの共有責任
メトリクスを可視化する
| メトリクス | 目標値 | 可視化方法 |
|---|---|---|
| CIパイプライン実行時間 | 10分以内 | ダッシュボード |
| ビルド成功率 | 95%以上 | 週次レポート |
| デプロイ頻度 | 1日1回以上 | カレンダー表示 |
| 平均修復時間(MTTR) | 1時間以内 | アラート集計 |
| テストカバレッジ | 80%以上 | CIレポート |
アンチパターンと対策
| アンチパターン | 症状 | 対策 |
|---|---|---|
| 巨大なモノリスCI | 1回のCIに30分以上 | ステージ分割、並列化 |
| テスト不安定(Flaky) | ランダムに失敗 | 根本原因を特定し修正 |
| 手動ステップの残存 | 「このステップだけ手動で」 | 全て自動化する |
| ブランチの長寿命化 | 数週間マージされないPR | 小さなPRに分割 |
| シークレットの平文管理 | .env ファイルをコミット | シークレットストア使用 |
まとめ
| ポイント | 内容 |
|---|---|
| 高速フィードバック | CIは10分以内、フェイルファスト戦略 |
| テストピラミッド | 単体70%、結合20%、E2E 10%の配分 |
| セキュリティ | シークレット管理とサプライチェーン保護 |
| チーム文化 | ビルド修復最優先、メトリクス可視化 |
チェックリスト
- フェイルファスト戦略を説明できる
- テストピラミッドの概念を理解した
- シークレット管理のベストプラクティスを把握した
- CI/CDにおけるチーム文化の重要性を理解した
次のステップへ
Step 1の内容を理解度チェッククイズで確認しましょう。 CI/CDの基本概念が固まったら、いよいよStep 2でGitHub Actionsの実践に入ります。
推定読了時間: 20分