Skip to content
Published on

CI/CDパイプライン上級ガイド2025:デプロイ戦略、GitOps、モノレポ、セキュリティパイプライン

Authors

はじめに

2024年(ねん)のDORA(DevOps Research and Assessment)レポートによると、エリートチームは1日(いちにち)に複数回(ふくすうかい)デプロイし、変更失敗率(へんこうしっぱいりつ)は5%未満(みまん)です。一方(いっぽう)、低(てい)パフォーマンスチームは月(つき)1回(いっかい)のデプロイで、復旧(ふっきゅう)に数週間(すうしゅうかん)かかります。この格差(かくさ)の核心(かくしん)は、CI/CDパイプラインの成熟度(せいじゅくど)にあります。

単純(たんじゅん)なビルド・テスト・デプロイを超(こ)えて、現代的(げんだいてき)なCI/CDはデプロイ戦略(せんりゃく)(Blue-Green、Canary)、GitOps、モノレポ最適化(さいてきか)、フィーチャーフラグ、セキュリティパイプラインまでカバーします。このガイドは2025年(ねん)現在(げんざい)、プロダクション環境(かんきょう)で検証(けんしょう)された上級(じょうきゅう)CI/CD戦略を体系的(たいけいてき)にまとめます。


1. デプロイ戦略(せんりゃく)

1.1 ローリングアップデート

最(もっと)も基本的(きほんてき)なデプロイ方式(ほうしき)で、インスタンスを順次(じゅんじ)入(い)れ替(か)えます。

時間 ->

インスタンス 1:  [v1] [v1] [v2] [v2] [v2]
インスタンス 2:  [v1] [v1] [v1] [v2] [v2]
インスタンス 3:  [v1] [v1] [v1] [v1] [v2]

トラフィック:    100% v1 -> 混合 -> 100% v2
# Kubernetes Rolling Update
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # 最大1つの追加Pod
      maxUnavailable: 0  # ダウンタイムゼロ
  template:
    spec:
      containers:
        - name: api
          image: myapp:v2
          readinessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 5

メリット: シンプル、追加(ついか)リソース最小(さいしょう)、段階的(だんかいてき)な入替(いれかえ) デメリット: デプロイ中(ちゅう)のv1/v2混合(こんごう)トラフィック、即座(そくざ)のロールバックが困難(こんなん)

1.2 Blue-Greenデプロイ

2つの同一(どういつ)環境(かんきょう)(Blue/Green)を維持(いじ)し、トラフィックを一度(いちど)に切(き)り替(か)えます。

┌─────────────────────────────────────────────┐
│                                             │
Load Balancer|v (切替前: Blueへトラフィック)│   ┌───────────┐     ┌───────────┐           │
│   │   Blue    │     │   Green   │           │
   (v1)   (v2)    │           │
│   │  Active   │     │  Standby  │           │
│   └───────────┘     └───────────┘           │
│                                             │
│   切替後: Greenへ100%トラフィック切替         │
│                                             │
│   ┌───────────┐     ┌───────────┐           │
│   │   Blue    │     │   Green   │           │
   (v1)   (v2)    │           │
│   │  Standby  │     │  Active   │           │
│   └───────────┘     └───────────┘           │
└─────────────────────────────────────────────┘
# AWS ALBを使ったBlue-Green (GitHub Actions)
name: Blue-Green Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build and Push Docker Image
        run: |
          docker build -t myapp:${{ github.sha }} .
          docker push myregistry/myapp:${{ github.sha }}

      - name: Deploy to Green Environment
        run: |
          aws ecs update-service \
            --cluster production \
            --service green-service \
            --task-definition myapp:${{ github.sha }}

      - name: Run Smoke Tests on Green
        run: |
          ./scripts/smoke-test.sh https://green.myapp.com

      - name: Switch Traffic to Green
        run: |
          aws elbv2 modify-listener \
            --listener-arn ${{ secrets.ALB_LISTENER_ARN }} \
            --default-actions \
              Type=forward,TargetGroupArn=${{ secrets.GREEN_TG_ARN }}

メリット: 即座(そくざ)のロールバック可能(かのう)(Blueへトラフィック切替(きりかえ))、ダウンタイムゼロ デメリット: 2倍(ばい)のインフラコスト、データベースマイグレーションが複雑(ふくざつ)

1.3 カナリアデプロイ

少数(しょうすう)のトラフィックに新(あたら)しいバージョンを先(さき)にデプロイして検証(けんしょう)します。

Phase 1: 5%トラフィックをCanary(v2)┌──────────────────────────────┐
│ v1 v1 v1 v1 v1 v1 v1 v1 v1  │ 95%
│ v2                           │  5%
└──────────────────────────────┘

Phase 2: 検証後25%に拡大
┌──────────────────────────────┐
│ v1 v1 v1 v1 v1 v1 v1        │ 75%
│ v2 v2 v2                     │ 25%
└──────────────────────────────┘

Phase 3: 安定確認後100%
┌──────────────────────────────┐
│ v2 v2 v2 v2 v2 v2 v2 v2 v2  │ 100%
└──────────────────────────────┘
# Istioを使ったCanary Deployment
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: myapp
spec:
  hosts:
    - myapp.example.com
  http:
    - route:
        - destination:
            host: myapp
            subset: stable
          weight: 95
        - destination:
            host: myapp
            subset: canary
          weight: 5
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: myapp
spec:
  host: myapp
  subsets:
    - name: stable
      labels:
        version: v1
    - name: canary
      labels:
        version: v2

メリット: リスク最小化(さいしょうか)、実際(じっさい)のトラフィックで検証(けんしょう)、段階的(だんかいてき)ロールアウト デメリット: 実装(じっそう)の複雑(ふくざつ)さ、メトリクスベースの自動化(じどうか)が必要(ひつよう)

1.4 デプロイ戦略比較(ひかく)

戦略ダウンタイムロールバック速度(そくど)コスト複雑度(ふくざつど)適(てき)したシナリオ
Rollingなし遅(おそ)い低(ひく)い低い一般(いっぱん)サービス
Blue-Greenなし即座(そくざ)高(たか)い(2倍(ばい))中程度(ちゅうていど)重要(じゅうよう)サービス
Canaryなし速(はや)い中程度高い大規模(だいきぼ)トラフィック
A/Bテストなし速い中程度非常(ひじょう)に高い機能実験(きのうじっけん)

2. GitOps

2.1 GitOpsの原則(げんそく)

┌──────────────────────────────────────────────────────┐
GitOps原則│                                                      │
1. 宣言的 (Declarative)- システム状態をコードで宣言                        │
│                                                      │
2. バージョン管理 (Versioned)- Gitが唯一の信頼源(SSOT)│                                                      │
3. 自動適用 (Automated)- 承認された変更は自動でシステムに反映              │
│                                                      │
4. 自己修復 (Self-healing)- 実際の状態と望ましい状態の差異を自動修正          │
└──────────────────────────────────────────────────────┘

2.2 ArgoCD設定(せってい)

# argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-production
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/k8s-manifests.git
    targetRevision: main
    path: apps/myapp/overlays/production
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true         # 不要なリソースを整理
      selfHeal: true      # 手動変更を自動復旧
      allowEmpty: false
    syncOptions:
      - CreateNamespace=true
      - PrunePropagationPolicy=foreground
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

2.3 ArgoCD App-of-Appsパターン

# root-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/k8s-manifests.git
    targetRevision: main
    path: apps
  destination:
    server: https://kubernetes.default.svc

# apps/ ディレクトリ構造
# apps/
#   myapp/
#     application.yaml
#   api-gateway/
#     application.yaml
#   monitoring/
#     application.yaml
#   cert-manager/
#     application.yaml

2.4 ArgoCD vs Flux 比較(ひかく)

機能(きのう)ArgoCDFlux v2
UIダッシュボード内蔵(ないぞう)Web UIWeave GitOps(別途(べっと))
マルチクラスターサポートサポート
HelmサポートネイティブHelmRelease CRD
Kustomizeサポートネイティブネイティブ
イメージ自動更新(じどうこうしん)ArgoCD Image Updater内蔵
通知(つうち)ArgoCD NotificationsNotification Controller
RBAC内蔵Kubernetes RBAC使用
アプローチPullベースPullベース
学習曲線(がくしゅうきょくせん)中程度中〜高

3. モノレポCI

3.1 モノレポ構造(こうぞう)

monorepo/
  apps/
    web/           # Next.js フロントエンド
    api/           # Express バックエンド
    mobile/        # React Native アプリ
  packages/
    ui/            # 共有UIコンポーネント
    utils/         # 共有ユーティリティ
    config/        # 共有設定
  turbo.json       # Turborepo設定
  nx.json          # またはNx設定
  package.json

3.2 Turborepo設定(せってい)

{
  "globalDependencies": ["**/.env.*local"],
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"],
      "cache": true
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": [],
      "cache": true
    },
    "lint": {
      "outputs": [],
      "cache": true
    },
    "deploy": {
      "dependsOn": ["build", "test", "lint"],
      "cache": false
    }
  }
}

3.3 Nx影響範囲(えいきょうはんい)ベースのビルド

# .github/workflows/monorepo-ci.yml
name: Monorepo CI

on:
  pull_request:
    branches: [main]

jobs:
  affected:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # 全履歴が必要

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - run: npm ci

      # 変更されたプロジェクトのみビルド/テスト
      - name: Lint affected
        run: npx nx affected --target=lint --base=origin/main

      - name: Test affected
        run: npx nx affected --target=test --base=origin/main

      - name: Build affected
        run: npx nx affected --target=build --base=origin/main

  # リモートキャッシング
  remote-cache:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - name: Build with remote cache
        run: npx turbo build --team=myteam --token=${{ secrets.TURBO_TOKEN }}
        env:
          TURBO_TEAM: myteam
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}

3.4 Turborepo vs Nx vs Bazel 比較(ひかく)

機能TurborepoNxBazel
学習曲線(がくしゅうきょくせん)低い中程度(ちゅうていど)高い
言語(げんご)サポートJS/TSJS/TS, Go, Rustなど多言語(たげんご)
変更検知(へんこうけんち)ファイルハッシュプロジェクトグラフ依存(いぞん)グラフ
リモートキャッシュVercel RCNx CloudRemote Execution
設定複雑度(せっていふくざつど)非常(ひじょう)にシンプル中程度複雑
大規模(だいきぼ)適合性(てきごうせい)中規模(ちゅうきぼ)大規模超大規模(ちょうだいきぼ)
コード生成なし内蔵GeneratorRules

4. Feature Flags(フィーチャーフラグ)

4.1 フィーチャーフラグの種類(しゅるい)

┌──────────────────────────────────────────────────┐
Feature Flagの種類├──────────────────────────────────────────────────┤
│                                                  │
1. Release Flag(リリースフラグ)- 未完成の機能を隠してデプロイ                 │
- 寿命: 短い(数日〜数週間)                   │
│                                                  │
2. Experiment Flag(実験フラグ)- A/Bテスト、機能比較                         │
- 寿命: 中程度(数週間〜数ヶ月)               │
│                                                  │
3. Ops Flag(運用フラグ)- システム動作制御(キルスイッチ)              │
- 寿命: 永続的                                │
│                                                  │
4. Permission Flag(権限フラグ)- ユーザー/組織別の機能アクセス制御             │
- 寿命: 永続的                                │
└──────────────────────────────────────────────────┘

4.2 実装(じっそう)例

// featureFlags.ts
import { UnleashClient } from 'unleash-proxy-client';

const unleash = new UnleashClient({
  url: 'https://unleash.myapp.com/api/frontend',
  clientKey: process.env.UNLEASH_CLIENT_KEY!,
  appName: 'myapp-frontend',
  refreshInterval: 15,
});

unleash.start();

// React Hook
export function useFeatureFlag(flagName: string): boolean {
  const [enabled, setEnabled] = useState(false);

  useEffect(() => {
    setEnabled(unleash.isEnabled(flagName));

    const handler = () => {
      setEnabled(unleash.isEnabled(flagName));
    };
    unleash.on('update', handler);
    return () => unleash.off('update', handler);
  }, [flagName]);

  return enabled;
}

// コンポーネントでの使用
function CheckoutPage() {
  const newCheckoutEnabled = useFeatureFlag('new-checkout-flow');

  if (newCheckoutEnabled) {
    return <NewCheckoutFlow />;
  }
  return <LegacyCheckoutFlow />;
}

4.3 Progressive Rollout(段階的(だんかいてき)ロールアウト)

// サーバーサイドフィーチャーフラグ (LaunchDarklyスタイル)
import LaunchDarkly from 'launchdarkly-node-server-sdk';

const client = LaunchDarkly.init(process.env.LD_SDK_KEY!);

async function getFeatureValue(
  flagKey: string,
  user: LDUser,
  defaultValue: boolean
): Promise<boolean> {
  await client.waitForInitialization();
  return client.variation(flagKey, user, defaultValue);
}

// 段階的ロールアウトの設定:
// Phase 1: 社内メンバーのみ (beta-testers グループ)
// Phase 2: 5%のユーザー
// Phase 3: 25%のユーザー
// Phase 4: 50%のユーザー
// Phase 5: 100%のユーザー

// キルスイッチパターン
async function processPayment(order: Order) {
  const newPaymentEnabled = await getFeatureValue(
    'new-payment-gateway',
    { key: order.userId },
    false  // デフォルト: 無効
  );

  if (newPaymentEnabled) {
    return newPaymentGateway.process(order);
  }
  return legacyPaymentGateway.process(order);
}

4.4 LaunchDarkly vs Unleash vs Flagsmith

機能LaunchDarklyUnleashFlagsmith
価格(かかく)有料(ゆうりょう)(高額(こうがく))オープンソース + エンタープライズオープンソース + クラウド
ターゲティング非常(ひじょう)に精巧(せいこう)基本的(きほんてき)精巧
A/Bテスト内蔵(ないぞう)別途(べっと)内蔵
SDKサポート25+言語15+言語15+言語
セルフホスティング不可(ふか)可能(かのう)可能
監査(かんさ)ログサポートサポートサポート

5. 環境管理(かんきょうかんり)

5.1 環境階層構造(かいそうこうぞう)

┌─────────────────────────────────────────┐
Production(プロダクション)- 実際のユーザートラフィック             │
- 最高レベルのモニタリング              │
- 変更時に承認プロセス                  │
├─────────────────────────────────────────┤
Staging(ステージング)- プロダクションと同一構成              │
- QAチームテスト                       │
- 統合テスト実行                        │
├─────────────────────────────────────────┤
Development(開発)- 最新機能の統合                        │
- mainブランチから自動デプロイ           │
├─────────────────────────────────────────┤
PR Preview(PRプレビュー)               │
- PR毎に独立環境を作成                  │
- PRクローズ時に自動削除                │
└─────────────────────────────────────────┘

5.2 エフェメラル環境(かんきょう)

# .github/workflows/preview.yml
name: PR Preview Environment

on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  deploy-preview:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Deploy Preview
        run: |
          PREVIEW_URL="pr-${{ github.event.number }}.preview.myapp.com"
          helm upgrade --install \
            pr-${{ github.event.number }} \
            ./charts/myapp \
            --namespace previews \
            --set image.tag=${{ github.sha }} \
            --set ingress.host=$PREVIEW_URL \
            --set resources.requests.memory=256Mi \
            --set resources.requests.cpu=100m

      - name: Comment PR with URL
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `Preview deployed: https://pr-${context.issue.number}.preview.myapp.com`
            })

  cleanup-preview:
    if: github.event.action == 'closed'
    runs-on: ubuntu-latest
    steps:
      - name: Delete Preview
        run: |
          helm uninstall pr-${{ github.event.number }} \
            --namespace previews

6. パイプラインセキュリティ

6.1 シークレット管理(かんり)

# GitHub Actions - OIDCを使ったAWS認証(長期シークレット不要)
name: Secure Deploy

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # OIDCベースのAWS認証
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/github-actions-role
          aws-region: ap-northeast-1

      # シークレットスキャン
      - name: Scan for secrets
        uses: trufflesecurity/trufflehog@v3
        with:
          path: ./
          extra_args: --only-verified

      # コンテナイメージスキャン
      - name: Scan container image
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: myapp:${{ github.sha }}
          severity: 'CRITICAL,HIGH'
          exit-code: '1'

6.2 SLSA(Supply-chain Levels for Software Artifacts)

# SLSA Level 3 - 署名付きビルド + 来歴証明
name: SLSA Build

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
      attestations: write
    steps:
      - uses: actions/checkout@v4

      - name: Build
        run: npm run build

      # Sigstoreを使ったアーティファクト署名
      - name: Sign artifact
        uses: sigstore/cosign-installer@v3

      - name: Sign container image
        run: |
          cosign sign \
            --yes \
            myregistry/myapp:${{ github.sha }}

      # SLSA来歴証明の生成
      - name: Generate SLSA provenance
        uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
        with:
          image: myregistry/myapp
          digest: ${{ steps.build.outputs.digest }}

6.3 セキュリティスキャンパイプライン

# .github/workflows/security.yml
name: Security Pipeline

on:
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 6 * * 1'  # 毎週月曜日 06:00

jobs:
  sast:
    name: Static Analysis
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Semgrep
        uses: semgrep/semgrep-action@v1
        with:
          config: p/owasp-top-ten

  dependency-check:
    name: Dependency Audit
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm audit --audit-level=high
      - name: Snyk Test
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

  container-scan:
    name: Container Security
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build image
        run: docker build -t myapp:scan .
      - name: Trivy scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: myapp:scan
          severity: 'CRITICAL,HIGH'
          format: 'sarif'
          output: 'trivy-results.sarif'
      - name: Upload SARIF
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: 'trivy-results.sarif'

7. ロールバック戦略(せんりゃく)

7.1 即時(そくじ)ロールバック

# Kubernetesロールバック
# 最後の成功バージョンに即時ロールバック
# kubectl rollout undo deployment/myapp

# GitHub Actions 自動ロールバック
name: Deploy with Auto-Rollback

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy new version
        id: deploy
        run: |
          kubectl set image deployment/myapp \
            myapp=myregistry/myapp:${{ github.sha }}
          kubectl rollout status deployment/myapp --timeout=300s

      - name: Run post-deploy checks
        id: healthcheck
        run: |
          for i in $(seq 1 10); do
            STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://myapp.com/health)
            if [ "$STATUS" != "200" ]; then
              echo "Health check failed: $STATUS"
              exit 1
            fi
            sleep 5
          done

      - name: Rollback on failure
        if: failure()
        run: |
          echo "Rolling back to previous version..."
          kubectl rollout undo deployment/myapp
          kubectl rollout status deployment/myapp --timeout=300s

7.2 データベース対応(たいおう)ロールバック

デプロイ過程でDBスキーマ変更がある場合:

1. Forward-Compatibleマイグレーション(安全)
   ┌─────────────────────────────────────┐
Step 1: 新カラム追加 (nullable)Step 2: アプリv2デプロイ (両方使用)Step 3: データマイグレーション       │
Step 4: 旧カラム削除               │
   └─────────────────────────────────────┘

2. Expand-Contractパターン
   Phase 1 (Expand): 新スキーマ追加、既存維持
   Phase 2 (Migrate): データ移行
   Phase 3 (Contract): 旧スキーマ削除

7.3 Forward-Fix vs ロールバック判断基準(はんだんきじゅん)

状況(じょうきょう)推奨戦略(すいしょうせんりゃく)理由(りゆう)
単純(たんじゅん)なバグ修正(しゅうせい)Forward-Fixロールバックより修正(しゅうせい)が速(はや)い
深刻(しんこく)な障害(しょうがい)即時ロールバックサービス復旧(ふっきゅう)が最優先(さいゆうせん)
DBマイグレーション含(ふく)むForward-Fixロールバック時(じ)にデータ損失(そんしつ)リスク
パフォーマンス低下(ていか)カナリアロールバック影響範囲(えいきょうはんい)把握後(はあくご)に判断(はんだん)

8. パイプラインパフォーマンス最適化(さいてきか)

8.1 キャッシング戦略

# .github/workflows/optimized-ci.yml
name: Optimized CI

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Node.js依存関係キャッシング
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      # Dockerレイヤーキャッシング
      - uses: docker/setup-buildx-action@v3
      - uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          tags: myapp:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      # Turborepoリモートキャッシング
      - name: Build with cache
        run: npx turbo build --cache-dir=.turbo
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: myteam

8.2 並列化(へいれつか)戦略

# 並列ジョブ実行
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run lint

  unit-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run test:unit

  type-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run type-check

  # すべての検証通過後にビルド
  build:
    needs: [lint, unit-test, type-check]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build

9. リリース管理(かんり)

9.1 セマンティックバージョニング

MAJOR.MINOR.PATCH(例: 2.1.3
MAJOR: 互換性のないAPI変更
MINOR: 下位互換の新機能追加
PATCH: 下位互換のバグ修正

:
  1.0.0 -> 1.0.1  (バグ修正)
  1.0.1 -> 1.1.0  (新機能追加)
  1.1.0 -> 2.0.0  (Breaking Change)

9.2 自動(じどう)リリースノート

# .github/workflows/release.yml
name: Release

on:
  push:
    tags: ['v*']

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Generate Changelog
        id: changelog
        uses: orhun/git-cliff-action@v3
        with:
          config: cliff.toml

      - name: Create Release
        uses: softprops/action-gh-release@v2
        with:
          body: ${{ steps.changelog.outputs.content }}
          draft: false
          prerelease: false

9.3 Conventional Commits

# コミットメッセージ形式
# type(scope): description

feat(auth): add OAuth2.0 login support
fix(cart): resolve quantity update race condition
docs(api): update REST API documentation
chore(deps): upgrade express to v5.0
perf(db): optimize query for order listing
refactor(payment): extract payment strategy pattern
test(checkout): add E2E tests for checkout flow

# Breaking Change表記
feat(api)!: change response format for /orders endpoint

BREAKING CHANGE: The orders endpoint now returns
paginated responses instead of a flat array.

9.4 Release Trainモデル

┌─────────────────────────────────────────────┐
Release Train(隔週リリース)│                                             │
Week 1: 機能開発 + コードフリーズ             │
Week 2: QA + バグ修正 + リリース              │
│                                             │
--+------+------+------+------+--│   v2.1   v2.2   v2.3   v2.4   v2.5│                                             │
│ ホットフィックスは別ブランチから即時デプロイ    │
└─────────────────────────────────────────────┘

10. マルチクラウドデプロイ

10.1 Terraformを使(つか)ったマルチクラウド

# main.tf - マルチクラウドプロバイダー
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    google = {
      source  = "hashicorp/google"
      version = "~> 5.0"
    }
  }
}

# AWSデプロイ
resource "aws_ecs_service" "primary" {
  name            = "myapp-primary"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.app.arn
  desired_count   = 3

  load_balancer {
    target_group_arn = aws_lb_target_group.app.arn
    container_name   = "myapp"
    container_port   = 8080
  }
}

# GCPデプロイ (DR)
resource "google_cloud_run_service" "failover" {
  name     = "myapp-failover"
  location = "asia-northeast1"

  template {
    spec {
      containers {
        image = "gcr.io/myproject/myapp:latest"
      }
    }
  }
}

11. 実践(じっせん)クイズ

Q1: Blue-Greenデプロイの最大のメリットは?

A) インフラコストが安い B) 即座にロールバックできる C) 実装が簡単 D) トラフィック分割ができる

正解(せいかい): B

Blue-Greenデプロイは2つの同一(どういつ)環境(かんきょう)を維持(いじ)するため、問題(もんだい)発生時(はっせいじ)にロードバランサーのトラフィックを以前(いぜん)の環境(Blue)に即座(そくざ)に切(き)り替(か)えてロールバックできます。ただし2倍(ばい)のインフラコストがデメリットです。

Q2: GitOpsにおけるGitリポジトリの役割は?

A) コードバックアップストレージ B) CI/CDパイプライン実行エンジン C) インフラの唯一の信頼源(SSOT) D) モニタリングダッシュボード

正解: C

GitOpsではGitリポジトリがインフラとアプリケーション状態(じょうたい)の唯一(ゆいいつ)の信頼源(しんらいげん)(Single Source of Truth)です。すべての変更(へんこう)はGitを通(とお)して行(おこな)われ、ArgoCD/Fluxなどのツールが Git状態と実際(じっさい)のクラスター状態を同期(どうき)します。

Q3: モノレポCIでの「affected」ビルドのメリットは?

A) すべてのプロジェクトを常にビルドする B) 変更されたプロジェクトと影響を受けるプロジェクトのみビルドし時間を節約する C) ビルドキャッシュを無視する D) テストをスキップする

正解: B

「affected」ビルドはGit diffを分析(ぶんせき)して、変更(へんこう)されたプロジェクトとそれに依存(いぞん)するプロジェクトのみを選択的(せんたくてき)にビルド/テストします。これにより大規模(だいきぼ)モノレポでのCI時間(じかん)を大幅(おおはば)に短縮(たんしゅく)できます。

Q4: Feature Flagの「キルスイッチ」の用途は?

A) サーバーをシャットダウンする B) 問題のある機能をコードデプロイなしで即座に無効化する C) データベースを削除する D) CIパイプラインを停止する

正解: B

キルスイッチは、プロダクションで問題(もんだい)が発生(はっせい)した際(さい)に、新(あたら)しいコードのデプロイなしでフィーチャーフラグをOFFに切(き)り替(か)えて、該当機能(がいとうきのう)を即座(そくざ)に無効化(むこうか)するパターンです。ロールバックよりはるかに速(はや)く対応(たいおう)できます。

Q5: SLSA(Supply-chain Levels for Software Artifacts)の目的は?

A) コードパフォーマンス最適化 B) ソフトウェアサプライチェーンの完全性を保証する C) データベースセキュリティ D) UIデザイン検証

正解: B

SLSAはソフトウェアサプライチェーン攻撃(こうげき)を防止(ぼうし)するためのセキュリティフレームワークです。ビルドプロセスの来歴証明(らいれきしょうめい)、アーティファクト署名(しょめい)、ビルド環境(かんきょう)の分離(ぶんり)などを通(つう)じて、ソフトウェアが改竄(かいざん)されていないことを保証(ほしょう)します。


12. CI/CD成熟度(せいじゅくど)チェックリスト

CI/CD成熟度チェックリスト:

Level 1 - 基本
[  ] 自動ビルドパイプライン
[  ] 自動テスト実行
[  ] コードレビュープロセス

Level 2 - 標準
[  ] デプロイ戦略(Rolling/Blue-Green)
[  ] 環境分離(dev/staging/prod)
[  ] シークレット管理(Vault/OIDC
Level 3 - 上級
[  ] GitOps(ArgoCD/Flux)
[  ] Feature Flags
[  ] カナリアデプロイ
[  ] PRプレビュー環境

Level 4 - エリート
[  ] パイプラインセキュリティ(SLSA[  ] 自動ロールバック
[  ] モノレポ最適化
[  ] リリース自動化

13. 参考資料(さんこうしりょう)

  1. DORA Metrics: dora.dev
  2. ArgoCD Documentation: argo-cd.readthedocs.io
  3. Flux Documentation: fluxcd.io
  4. Turborepo Documentation: turbo.build
  5. Nx Documentation: nx.dev
  6. LaunchDarkly Docs: docs.launchdarkly.com
  7. Unleash Documentation: docs.getunleash.io
  8. SLSA Framework: slsa.dev
  9. Sigstore / Cosign: sigstore.dev
  10. Semgrep: semgrep.dev
  11. Conventional Commits: conventionalcommits.org
  12. Git Cliff (Changelog): git-cliff.org
  13. GitHub Actions Docs: docs.github.com/actions
  14. Kubernetes Deployment Strategies: kubernetes.io/docs