NestJS
イベント
該当するコンテンツが見つかりませんでした
マガジン
該当するコンテンツが見つかりませんでした
技術ブログ
本記事は、Luup Advent Calendar 2025 の7日目の記事になります。 はじめに こんにちは、Software部でiOSエンジニアをしている大坪(つぼやん)です! 今回は、部内で実施しているLT(ライトニングトーク)会についてお話しします。 技術共有の場としてLT会を開催されている会社さんも多いかと思いますが、LuupのSoftware部ではどのような目的や運用で行っているのか、その裏側をご紹介します! LT会実施までの背景 現在、Software部には20名を超えるメンバーが在籍しています。 このメンバーの役割は、LUUPのユーザーが利用するアプリやそのバック
はじめに ども!ふと振り返って、ブログを執筆しだして 3 年が経過していることにびっくりした龍ちゃんです。いろいろな開発環境を使っていますが、最近はデプロイする環境なども考えながら開発環境を整備するように至高の変化が起きていました。 今回は、Azure Functions を本番環境で運用するとき、「どうやってデプロイするか」ってお話です。 開発初期以外の手動デプロイは論外として、CI/CD パイプラインを構築するとなると: シークレットキーの管理どうする? – 有効期限切れたら手動更新? デプロイ失敗したときどうする? – 毎回 Azure Portal でログ確認? 複数の Functions どう管理する? – 全部まとめてビルド?それとも個別? 今回は GitHub Actions を使った Azure Functions のデプロイ実装 を実践的に解説します。 特に、 OIDC 認証によるパスワードレスデプロイ を採用することで、シークレットキー管理の手間をゼロにできたのが大きな収穫でした。 この記事でわかること GitHub Actions による Azure Functions デプロイの実装方法 OIDC 認証によるパスワードレスデプロイ (シークレットキー不要) パス条件トリガーによる効率的な CI/CD npm ci + キャッシュ戦略 パッケージ構造検証とトラブルシューティング 実測パフォーマンスとベストプラクティス 前提条件 この記事では、以下がセットアップ済みであることを前提としています: 必須環境 Azure CLI : バージョン 2.30 以上 インストール方法: Azure CLI 公式ドキュメント Azure サブスクリプション : Azure Functions をデプロイするため GitHub リポジトリ : Admin 権限(Secrets/Variables 設定のため) Azure Functions プロジェクト : Node.js + TypeScript Node.js 22 : この記事では Node.js 22 を使用 Programming Model v4 必須 : Node.js 22 を使用する場合、Azure Functions Programming Model v4 への移 行が必須です Azure Functions Runtime v4.25+ : Programming Model v4 をサポートするランタイムバージョン @azure/functions v4.0+ : Programming Model v4 対応パッケージ 参考記事 OIDC 認証の詳細なセットアップ手順については、以下の記事で詳しく解説しています: GitHub Actions→Azure 認証の実装手順!OIDC×Azure CLI で爆速セットアップ 2025 年版 User Assigned Managed Identity の作成 Federated Identity Credential の設定 RBAC ロールの付与 ローカル開発環境の構築については、こちらを参照してください: Azure Functions×DevContainer 環境構築| Node.js 22 + TypeScript DevContainer を使った環境構築 ローカルでの開発・デバッグ方法 GitHub Actions CI/CD フロー全体像 まずは、全体の流れを把握しましょう。 フローのポイント パス条件でトリガー – 関連ファイルが変更されたときのみ実行 npm ci でクリーンビルド – 再現性の高いインストール パッケージ構造検証 – デプロイ前に必須ファイルをチェック OIDC 認証 – シークレットキー不要のパスワードレス認証 デプロイ後検証 – 成功確認とエンドポイント表示 それでは、各ステップを詳しく見ていきましょう。 ステップ 1: パス条件トリガーの設定 なぜ必要か モノレポ環境で複数のプロジェクトを管理している場合、 フロントエンドの変更でバックエンドの CI/CD が実行される といった無駄なビルドが発生します。 これを防ぐために、 パスフィルター を設定します。 プロジェクト構成の確認 プロジェクトのディレクトリ構成は、以下のようなディレクトリ構成を想定しています。: / ├── application/ │ ├── backend/ # NestJS API Server │ ├── frontend/ # Next.js App Router │ ├── functions/ # X Scheduler Functions │ └── blog-search-mcp-functions/ # Blog Search MCP Functions ⭐ ├── .github/ │ └── workflows/ │ ├── deploy-blog-search-mcp-functions.yml # このワークフロー ⭐ │ ├── deploy-x-scheduler-functions.yml │ ├── deploy-backend.yml │ └── deploy-frontend.yml └── infrastructure/ # Azure Bicep IaC ポイント : 各プロジェクトが独立したディレクトリに配置 ワークフローファイルも各プロジェクトごとに分離 パス条件でトリガーを制御することで、 無関係なビルドを防止 実装 name: Deploy Blog Search MCP Functions on: push: branches: - main paths: - "application/blog-search-mcp-functions/**" - ".github/workflows/deploy-blog-search-mcp-functions.yml" workflow_dispatch: inputs: environment: description: "Deployment environment" required: true default: "production" type: choice options: - production - staging - dev ポイント paths フィルターで 関連ファイルの変更のみトリガー ワークフロー自体の変更もトリガー対象 に含める( .github/workflows/... ) workflow_dispatch で 手動実行を可能 にする(緊急時のロールバック等) 効果 実際にこの設定を導入した結果: 不必要なビルド: 70%削減 CI/CD コスト: 65%削減 デプロイ時間: 50%短縮 (並列実行) ステップ 2: OIDC 認証の設定 OIDC 認証とは OIDC(OpenID Connect)認証は、 短命なトークンを使った認証方式 です。 従来のシークレットキーベース認証との違いを見てみましょう。 従来の認証方式の問題点 # ❌ 非推奨:シークレットベース認証 - uses: azure/login@v2 with: creds: ${{ secrets.AZURE_CREDENTIALS }} 問題 : シークレットの有効期限管理が必要 定期的なローテーション作業 シークレット漏洩リスク OIDC 認証の実装 permissions: id-token: write # OIDC トークン取得に必要 contents: read jobs: deploy: runs-on: ubuntu-latest environment: "production" steps: - name: Azure Login (OIDC) uses: azure/login@v2 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} 必要な GitHub Secrets AZURE_CLIENT_ID: xxx-xxx-xxx (Managed IdentityのClient ID) AZURE_TENANT_ID: xxx-xxx-xxx (テナントID) AZURE_SUBSCRIPTION_ID: xxx-xxx-xxx (サブスクリプションID) 重要 : これらは すべて識別子のみ で、シークレットキーは含まれていません。つまり、 万が一漏洩しても、それだけでは Azure にアクセスできない 仕組みです。 OIDC 認証の仕組み(簡略版) GitHub Actions Job ↓ Request OIDC Token (JWT) ↓ GitHub OIDC Provider ↓ GitHub OIDC Token (5分間有効) ↓ Azure AD (トークン交換) ↓ (Verify Federated Identity Credential) User Assigned Managed Identity ↓ Azure Access Token (1-24時間有効) ↓ Azure Functions Deployment メリット シークレットキー不要 – パスワードレス認証でセキュリティリスク削減 自動ローテーション – トークンは短命で自動更新、手動ローテーション不要 漏洩リスク最小化 – 識別子のみで、シークレットが存在しない セキュリティベストプラクティス – Microsoft 公式推奨 トークンの有効期限について : GitHub OIDC トークン : 5分間(GitHub が発行する認証用 JWT) Azure アクセストークン : 1時間(Service Principal)または24時間(Managed Identity) 実際のワークフロー実行では Azure アクセストークンが使用されるため、十分な有効期限があります 詳細なセットアップ手順と OIDC 認証の仕組みについては、 こちらの記事 を参照してください。 ステップ 3: Node.js セットアップと npm ci Setup Node.js with Cache - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "22" cache: "npm" cache-dependency-path: "application/blog-search-mcp-functions/package-lock.json" ポイント Node.js 22 LTS を使用(Azure Functions v4 対応) npm キャッシュ を有効化( cache: "npm" ) cache-dependency-path でモノレポの特定パスを指定 補足 : setup-node は package-lock.json のハッシュ値を自動計算してキャッシュキーを生成します。より高度なキャッシング戦略( actions/cache + hashFiles() による明示的制御)については、 actions/setup-node 公式リポジトリ を参照してください。 npm ci vs npm install - name: Install dependencies run: | cd application/blog-search-mcp-functions npm ci # ✅ npm install ではなく npm ci npm ci の利点 : package-lock.json を厳密に尊重(再現性) node_modules/ をクリーンインストール CI/CD 環境に最適化(高速) バージョンの不一致を防ぐ 実測値 処理 初回 キャッシュヒット npm ci ~30 秒 ~5 秒 npm run build ~15 秒 ~15 秒 キャッシュ効果: ビルド時間 30-40%短縮 ステップ 4: パッケージ構造検証 なぜ必要か Azure Functions のデプロイは、 正しいファイル構成がないと失敗 します。 特に以下のファイルは必須: host.json – Functions App 設定 package.json – 依存関係定義 dist/ – ビルド成果物(TypeScript → JavaScript) デプロイ前にこれらを検証することで、 失敗を早期に検出 できます。 実装 - name: Verify package structure run: | cd application/blog-search-mcp-functions echo "=== Package root contents ===" ls -la echo "" # host.json検証 echo "=== Checking host.json ===" if [ -f "host.json" ]; then echo "✅ host.json exists" cat host.json | jq . || echo "⚠ host.json is not valid JSON" else echo "❌ host.json missing!" exit 1 fi echo "" # package.json検証 echo "=== Checking package.json ===" if [ -f "package.json" ]; then echo "✅ package.json exists" node -e "console.log('✅ package.json is valid JSON')" -p "require('./package.json')" else echo "❌ package.json missing!" exit 1 fi echo "" # dist/ ディレクトリ検証 echo "=== Checking for compiled files in dist ===" if [ -d "dist" ]; then echo "✅ dist directory exists" find dist -name "*.js" | head -10 else echo "❌ dist directory missing!" exit 1 fi echo "" echo "=== All files in package (first 50) ===" find . -type f | head -50 ポイント jq で JSON 妥当性検証 Node.js で require() テスト(構文エラー検出) 失敗時は exit 1 で即座にワークフロー停止 ログ出力を見やすくフォーマット 実際のログ出力例 === Package root contents === drwxr-xr-x dist -rw-r--r-- host.json -rw-r--r-- package.json ... === Checking host.json === ✅ host.json exists { "version": "2.0", "extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle.Experimental", "version": "[4.*, 5.0.0)" } } === Checking package.json === ✅ package.json exists ✅ package.json is valid JSON === Checking for compiled files in dist === ✅ dist directory exists dist/src/app.js dist/src/functions/searchBlogPosts.mcp.js ... この検証により、 デプロイ失敗の原因を事前に特定 できます。 ステップ 5: テスト実行 –passWithNoTests フラグ プロジェクト初期段階では、テストファイルがないことがあります。 - name: Run tests run: | cd application/blog-search-mcp-functions npm test -- --passWithNoTests なぜ必要か Jest のデフォルト動作では、 テストが見つからない場合は exit code 1 で失敗 します。 --passWithNoTests フラグを使うことで: テストファイルがなくても CI/CD が通る 将来テストを追加した際、自動的にテストが実行される 開発初期段階の CI/CD 構築に最適 推奨アプローチ プロジェクト初期(テストなし) : --passWithNoTests 使用 テスト追加開始 : フラグ維持、段階的にテスト追加 テストカバレッジ確立後 : フラグ削除(テスト必須化) ステップ 6: Azure Functions デプロイ デプロイ前の確認 - name: Check Function App status before deployment run: | echo "Checking current Function App status..." az functionapp show \ --name ${{ vars.BLOG_SEARCH_MCP_FUNCTION_APP_NAME }} \ --resource-group ${{ vars.RESOURCE_GROUP }} \ --query "{name:name, state:state, kind:kind}" \ --output table 現在の Function App の状態を確認することで、デプロイ前の異常を検出できます。 デプロイ実行 - name: Deploy to Azure Functions uses: Azure/functions-action@v1 with: app-name: ${{ vars.BLOG_SEARCH_MCP_FUNCTION_APP_NAME }} package: "application/blog-search-mcp-functions" respect-funcignore: true scm-do-build-during-deployment: false enable-oryx-build: false id: deploy デプロイを実行する際は、作成しているAzure Functionsのアプリ名のみで指定をすることができます。 デプロイ設定の詳細 respect-funcignore: true .funcignore ファイルを尊重し、不要なファイルをデプロイパッケージから除外します。 # .funcignore *.ts src/ tsconfig.json .git/ .github/ node_modules/ tests/ *.md 効果 : デプロイパッケージサイズを最小化 ビルド成果物( dist/ )のみアップロード デプロイ時間短縮 scm-do-build-during-deployment: false Azure 側でのビルドをスキップします。 理由 : GitHub Actions 側で事前ビルド済み デプロイ時間短縮 予測可能性向上 enable-oryx-build: false Oryx(Azure 自動ビルドシステム)を無効化します。 理由 : 明示的なビルドプロセス管理 トラブルシューティングが容易 設定の互換性に関する重要な注意事項 WEBSITE_RUN_FROM_PACKAGE との非互換性 以下の設定の組み合わせは 互換性がありません : WEBSITE_RUN_FROM_PACKAGE=1 + SCM_DO_BUILD_DURING_DEPLOYMENT=true (非互換) WEBSITE_RUN_FROM_PACKAGE=1 + SCM_DO_BUILD_DURING_DEPLOYMENT=false (推奨) 理由 : WEBSITE_RUN_FROM_PACKAGE は ZIP パッケージから直接実行する設定であり、デプロイ時のビルドと競合します。 リモートビルドを有効化する場合(Linux) : ネイティブモジュール(Puppeteer、Sharp等)を使用する場合は、リモートビルドが必要です: - name: Deploy to Azure Functions uses: Azure/functions-action@v1 with: app-name: ${{ vars.FUNCTION_APP_NAME }} package: "path/to/function" scm-do-build-during-deployment: true # リモートビルド有効化 enable-oryx-build: true # Oryx ビルド有効化 注意 : 両方を true に設定する必要があります(Linuxのみ)。 ステップ 7: デプロイ後検証 成功時の検証 - name: Verify deployment success if: success() run: | echo "✅ Deployment successful. Verifying MCP Server..." sleep 30 # Function App起動待機 # アプリ設定確認 az functionapp config show \ --name ${{ vars.BLOG_SEARCH_MCP_FUNCTION_APP_NAME }} \ --resource-group ${{ vars.RESOURCE_GROUP }} \ --query "{nodeVersion:nodeVersion, platform:linuxFxVersion}" \ --output table # Function App URL取得 FUNCTION_APP_URL=$(az functionapp show \ --name ${{ vars.BLOG_SEARCH_MCP_FUNCTION_APP_NAME }} \ --resource-group ${{ vars.RESOURCE_GROUP }} \ --query "defaultHostName" \ --output tsv) echo "MCP Endpoint: https://$FUNCTION_APP_URL/runtime/webhooks/mcp/sse" ポイント sleep 30 で Function App 起動待機(コールドスタート対策) Node.js バージョン確認(意図しないバージョン使用防止) エンドポイント URL を明示的に表示(手動テスト用) 失敗時のリカバリー - name: Check deployment result and restart if needed if: failure() run: | echo "❌ Deployment failed. Attempting recovery..." echo "Restarting Function App..." az functionapp restart \ --name ${{ vars.BLOG_SEARCH_MCP_FUNCTION_APP_NAME }} \ --resource-group ${{ vars.RESOURCE_GROUP }} echo "Waiting for restart to complete..." sleep 60 echo "Checking Function App logs..." az functionapp logs tail \ --name ${{ vars.BLOG_SEARCH_MCP_FUNCTION_APP_NAME }} \ --resource-group ${{ vars.RESOURCE_GROUP }} \ --timeout 60 || echo "Could not retrieve logs" 自動リカバリーの利点 デプロイ失敗後の手動介入を減らす ログ取得による問題診断の容易化 一時的な問題(ネットワークエラーなど)からの自動復旧 実装例:Blog Search MCP Functions ここまでの設定を統合した完全なワークフローファイルを見てみましょう。 完全なワークフロー name: Deploy Blog Search MCP Functions on: push: branches: - main paths: - "application/blog-search-mcp-functions/**" - ".github/workflows/deploy-blog-search-mcp-functions.yml" workflow_dispatch: permissions: id-token: write contents: read jobs: deploy: runs-on: ubuntu-latest environment: "production" steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "22" cache: "npm" cache-dependency-path: "application/blog-search-mcp-functions/package-lock.json" - name: Install dependencies run: | cd application/blog-search-mcp-functions npm ci - name: Build Functions run: | cd application/blog-search-mcp-functions npm run build - name: Verify package structure run: | cd application/blog-search-mcp-functions # ... (前述の検証スクリプト) - name: Run tests run: | cd application/blog-search-mcp-functions npm test -- --passWithNoTests - name: Azure Login (OIDC) uses: azure/login@v2 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - name: Deploy to Azure Functions uses: Azure/functions-action@v1 with: app-name: ${{ vars.BLOG_SEARCH_MCP_FUNCTION_APP_NAME }} package: "application/blog-search-mcp-functions" respect-funcignore: true scm-do-build-during-deployment: false enable-oryx-build: false - name: Verify deployment success if: success() run: | # ... (前述の検証スクリプト) プロジェクト構成 application/blog-search-mcp-functions/ ├── package.json ├── tsconfig.json ├── host.json # Experimental Bundle設定 ├── .funcignore # デプロイ除外ファイル ├── src/ │ ├── app.ts # エントリーポイント │ ├── functions/ # MCP Tool定義 │ │ ├── searchBlogPosts.mcp.ts │ │ ├── listAllCategories.mcp.ts │ │ └── listAllHashtags.mcp.ts │ └── blog-search-mcp/ # 共通モジュール │ ├── types/ │ ├── schemas/ │ └── services/ └── dist/ # ビルド成果物(TypeScript → JS) package.json { "name": "blog-search-mcp-functions", "version": "1.0.0", "scripts": { "build": "tsc", "start": "npm run build && func start", "test": "jest --passWithNoTests" }, "dependencies": { "@azure/functions": "^4.0.0", "@supabase/supabase-js": "^2.76.1", "zod": "^4.1.12" }, "devDependencies": { "@types/node": "^22.10.1", "typescript": "^5.7.2" }, "engines": { "node": ">=22.0.0" } } Environment 変数 vs Secrets GitHub Secrets と Variables の適切な使い分けも重要です。 使い分けの基準 Secrets(機密情報) : secrets: AZURE_CLIENT_ID # OIDC認証情報 AZURE_TENANT_ID AZURE_SUBSCRIPTION_ID Variables(非機密情報) : variables: APP_NAME # アプリケーション名 RESOURCE_GROUP # リソースグループ名 BLOG_SEARCH_MCP_FUNCTION_APP_NAME # Function App名 X_SCHEDULER_FUNCTION_APP_NAME # Function App名 判断基準 Secrets : 漏洩すると重大な影響(認証情報、API キー、トークン) Variables : 公開されても問題ない(リソース名、設定値) 設定方法 手動設定 GitHub リポジトリの「Settings」→「Secrets and variables」→「Actions」から設定します。 自動設定(推奨) Bicep デプロイスクリプト( deploy.sh )で自動設定することも可能です: # GitHub CLI の存在確認 if command -v gh &> /dev/null; then echo "GitHub CLIを使用してシークレットを設定中..." # Repository secrets(リポジトリ全体で共通) echo "$MANAGED_IDENTITY_CLIENT_ID" | gh secret set AZURE_CLIENT_ID --repo "$GITHUB_ORG/$GITHUB_REPO" # Environment variables(環境ごと) gh variable set BLOG_SEARCH_MCP_FUNCTION_APP_NAME \ --repo "$GITHUB_ORG/$GITHUB_REPO" \ --env production \ --body "$BLOG_SEARCH_MCP_FUNCTION_APP_NAME" fi メリット : インフラデプロイと GitHub 設定を一括実行 手動設定ミスの防止 環境構築の再現性向上 パフォーマンス実測値 実際に運用している環境での実測値を紹介します。 ビルド時間(Blog Search MCP Functions) ステップ 初回 キャッシュヒット Setup Node.js ~10 秒 ~10 秒 npm ci ~30 秒 ~5 秒 npm run build ~15 秒 ~15 秒 Deploy ~2-8 分 ~2-8 分 合計 約 3-9 分 約 2.5-8.5 分 注 : デプロイ時間は、関数のパッケージサイズ、依存関係の数、Azure リージョンの混雑状況によって大きく変動します。 小規模関数 (最小限の依存関係):約 2-3 分 中規模関数 (一般的な依存関係):約 5-8 分 大規模関数 (多数の依存関係):約 10-15 分 上記の実測値は、小規模な MCP Functions の場合です。本番環境での一般的なアプリケーションでは、 5-15 分程度を見込むことを推奨 します。 最適化効果 最適化項目 効果 パスフィルター導入 不必要なビルド 70%削減 npm キャッシュ ビルド時間 30-40%短縮 並列ワークフロー 全体デプロイ時間 50%短縮 トラブルシューティング よくあるエラーと対処法をまとめます。 エラー 1: Package deployment failed 症状 : Error: Package deployment failed 原因 : host.json がパッケージに含まれていない package.json が不正な JSON dist/ ディレクトリが空 解決策 : パッケージ構造検証ステップを追加し、 .funcignore を確認します。 - name: Verify package structure run: | # host.json, package.json, dist/ の検証 エラー 2: OIDC token exchange failed 症状 : Error: OIDC token exchange failed 原因 : Federated Identity Credential の設定ミス permissions: id-token: write の欠落 解決策 : permissions 確認 : permissions: id-token: write # 必須 contents: read Federated Credential 確認 : Azure Portal で、User Assigned Managed Identity の「Federated credentials」を確認し、subject パターンが一致しているか確認します。 repo:org/repo:environment:production 詳細は こちらの記事 を参照してください。 エラー 3: Function runtime error 症状 : デプロイは成功するが、Function App が起動しない 原因 : Node.js バージョン不一致 依存関係の欠落 解決策 : デプロイ後に Node.js バージョンを確認: az functionapp config show \ --name <app-name> \ --resource-group <rg> \ --query "nodeVersion" package.json の engines フィールドと一致しているか確認します。 { "engines": { "node": ">=22.0.0" } } エラー 4: npm ci fails 症状 : Error: npm ci can only install packages when your package.json and package-lock.json are in sync 原因 : package.json と package-lock.json の不一致 解決策 : ローカルで package-lock.json を再生成: rm package-lock.json npm install git add package-lock.json git commit -m "chore: regenerate package-lock.json" 実装のポイントまとめ カテゴリ DO(推奨) DON’T(非推奨) 認証 OIDC 認証を使用 ・パスワードレス、セキュア ・シークレット管理不要 ・自動ローテーション シークレットベース認証 ・有効期限管理の負担 ・定期的なローテーション作業 ・漏洩リスク 依存関係管理 npm ci を使用 ・ package-lock.json を厳密に尊重 ・再現性、高速性 ・CI/CD 専用の最適化 npm install 使用 ・バージョン不一致リスク ・再現性が低い ・予期しない依存関係の更新 トリガー設定 パスフィルターを設定 ・不必要なビルド 70%削減 ・CI/CD コスト 65%削減 ・デプロイ時間 50%短縮 パスフィルターなし ・すべての変更でビルド実行 ・リソース浪費 ・CI/CD コスト増大 テスト –passWithNoTests(初期段階) ・テストなしでも CI/CD 通過 ・段階的なテスト追加 ・開発速度維持 テスト必須化(初期段階) ・開発速度低下 ・CI/CD 構築の遅延 ・実装優先フェーズで障害 検証 パッケージ構造検証 ・デプロイ前の構造確認 ・失敗の早期検出 ・デバッグ時間短縮 手動検証のみ ・人的ミス防止できない ・デプロイ失敗後に気づく ・手戻りコスト増大 デプロイ設定 事前ビルド戦略 ・ scm-do-build: false ・ enable-oryx-build: false ・GitHub Actions 側で事前ビルド Azure 側ビルド ・ scm-do-build: true ・デプロイ時間が長い ・予測可能性が低い リカバリー 自動リカバリー処理 ・失敗時の自動再起動 ・ログ自動取得 ・一時的な問題から自動復旧 手動リカバリーのみ ・毎回手動介入が必要 ・復旧時間が長い ・夜間デプロイ失敗時の対応遅延 注 : 本番環境に移行する際は、 --passWithNoTests フラグを削除してテストを必須化しましょう。品質保証のため、テストカバレッジを確立した後は必ずテストが実行される状態にすることを推奨します。 まとめ この記事で実装したこと GitHub Actions による Azure Functions デプロイパイプライン OIDC 認証によるパスワードレスデプロイ パス条件トリガーで効率化 (不要なビルド 70%削減) npm ci + キャッシュで高速化 (ビルド時間 30-40%短縮) パッケージ構造検証で品質保証 自動リカバリー処理 得られる効果 セキュリティ面 : シークレットキー管理不要 自動ローテーション 漏洩リスク最小化 効率面 : デプロイ時間短縮(小規模関数で約 2-3 分、一般的には 5-15 分) CI/CD コスト削減(65%) 手動作業の削減 品質面 : デプロイ失敗の早期検出 自動検証とリカバリー 再現性の高いビルド 次のステップ さらに発展させるには: マルチ環境デプロイ – staging/production 環境の管理 Bicep 統合 – インフラと CI/CD の完全自動化 Python 版 – Python Runtime での実装 モニタリング統合 – Application Insights との連携 参考リンク 公式ドキュメント Azure Functions GitHub Actions OIDC 認証(Azure) 関連記事 GitHub Actions→Azure 認証の実装手順!OIDC×Azure CLI で爆速セットアップ 2025 年版 Azure Functions×DevContainer 環境構築| Node.js 22 + TypeScript GitHub Actions を使った Azure Functions のデプロイ、ぜひ試してみてください! OIDC 認証によるパスワードレスデプロイで、セキュリティと効率性の両方を手に入れられます。 質問や改善提案があれば、ぜひコメントで教えてください! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post GitHub Actions×Azure Functions実装ガイド|OIDC認証で実現するセキュアなCI/CD(Node.js編) first appeared on SIOS Tech. Lab .
はじめに ども!最近は Claude Code ともに開発を進めて、with AI での生活にどっぷりだったのですが 2025 年も締めということで貯まった検証を一気に記事化している龍ちゃんです。検証がたまっていたので、11 月と 12 月は大量にブログを書く羽目になりそうですね。ゴリゴリ執筆する必要がありますね! 皆さん、AI(Claude Code 等)と一緒に開発してると、こんな悩みありませんか? 「このプロジェクト、どういう構成になってるの?」と AI に毎回説明するのが面倒 ファイルが多すぎて AI が混乱して、的外れな提案をしてくる モノレポにしたけど、全部のアプリが毎回ビルドされて時間がかかる 僕も以前はこれらの課題に悩まされていました。特に、 プロジェクトが大きくなるほど、AI が全体像を把握しづらくなる という問題が深刻でした。 そこで構築したのが、 CLAUDE.md 階層構造 を核としたモノレポ環境です。この環境により、以下の成果を得られました: AI が自律的にプロジェクト構成を理解 (CLAUDE.md 階層構造) CI/CD ビルド時間 58%削減 (paths フィルタによる最適化) ドキュメントが自然に蓄積 (4 フェーズワークフロー: 計画 → 実装 → 研究記録 → 記事化) 本記事で紹介する環境は、実際に稼働中のシステムで実践している内容です。 このモノレポで開発しているシステムの詳細については、 AI チャットで話すだけ!X 予約投稿を完全自動化するシステム構築術 で解説しています(リポジトリは非公開)。 この記事では、 モノレポ構成と AI 協業開発を最適化する環境設計 について、実際のプロジェクト構成とワークフローを交えながら解説していきます。 記事の位置づけ 前提となる知識(先に読むべき記事) : 本記事で紹介する 4 フェーズワークフローは、以下の記事で解説した 3 フェーズ開発を基盤に構築されています: 3 フェーズ開発の基本を学ぶ : Claude Code 革命!3 フェーズ開発で効率的な開発:計画 → 実装 → 検証術 計画 → 実装 → 検証の 3 フェーズワークフロー /docs/ と /application/ のディレクトリ分離 小規模システムを 30 分で実装する実例 計画フェーズの詳細を学ぶ : AI 協働で仕様書アレルギー克服!開発時間を 1 週間 →2 日に短縮する実践法 CLAUDE.md による仕様書作成ルール AI との協働レビュープロセス 開発時間を 1 週間 →2 日に短縮した実践法 4 フェーズへの拡張を学ぶ : 検証 → 記事化で知見を資産化!Claude Code×RAG もどきで AI 技術ブログ執筆を効率化 フェーズ 4(記事化)の追加による知見の資産化 RAG もどきシステムでトークン数 50-60%削減 文体補正システムで一貫した記事品質を実現 記事執筆時間 50%削減、重複チェック 83%削減 技術基盤 : 型安全な API 開発を学ぶ : AI と爆速開発!Next.js×Nest.js 型定義同期の自動生成パイプライン構築術 Backend DTOs → OpenAPI → Frontend Types の自動生成 Single Source of Truth による型ズレゼロの実現 この記事で学べること この記事を読むことで、以下の知識とスキルが得られます: 主要なポイント モノレポ構成と AI 協業開発の相性 なぜモノレポが AI 協業に適しているのか、実体験をもとに解説 CLAUDE.md 階層構造によるコンテキスト管理 9 つの CLAUDE.md ファイルで AI に適切な情報を提供する設計 paths フィルタによる CI/CD 最適化 変更されたアプリのみビルドすることでビルド時間 58%削減 4 フェーズワークフローによる知見の資産化 計画 → 実装 → 研究記録 → 記事化のドキュメント駆動型開発 実践的なテクニック AI が理解しやすいディレクトリ構造と命名規則 GitHub Actions paths フィルタの活用 ドキュメント駆動型開発による知見の蓄積 前提条件 この記事は、 モノレポ構成と AI 協業開発環境の設計・アーキテクチャ に焦点を当てています。 前提知識(あると望ましい) AI 開発ツールの使用経験 Claude Code、GitHub Copilot、Cursor 等の AI 開発支援ツールを使った開発経験 AI にプロンプトを投げてコードを生成した経験 モノレポの基礎知識 複数のアプリケーションを 1 つのリポジトリで管理する概念の理解 (初めての方でも、記事を読み進めることで理解できます) 本記事で扱わないこと モノレポツール(Turborepo、Nx 等)の詳細比較 Azure 環境の詳細なセットアップ手順 各フレームワーク(NestJS、Next.js 等)の実装詳細 型安全パイプラインの実装詳細( 型安全パイプラインの記事 で解説) ※本記事は構成と設計に焦点を当てており、実装の詳細は関連記事で解説しています。 プロジェクト全体像 まずは、実際のプロジェクト構成を見ていきましょう。 モノレポ構成の 4 つのアプリケーション このプロジェクトは、 4 つの独立したアプリケーション をモノレポで管理しています。 アプリケーション 技術スタック デプロイ先 GitHub Actions Frontend Next.js 15, React 19, TypeScript 5 Azure Static Web Apps frontend-swa-deploy.yml Backend NestJS 11, Node.js 22, TypeScript 5 Azure Web Apps (Docker) backend-docker-build.yml X Scheduler Functions Azure Functions v4, Node.js 22, TypeScript Azure Functions deploy-x-scheduler-functions.yml Blog Search MCP Functions Azure Functions v4, Node.js 22, MCP Protocol Azure Functions deploy-blog-search-mcp-functions.yml ディレクトリ構造の全体像 プロジェクトルート/ ├── docs/ # 計画・設計フェーズ(実装コードなし) │ ├── CLAUDE.md # 計画フェーズガイドライン │ ├── project-core.md # インフラ全体構成 │ ├── features/ # 新機能開発計画 │ ├── bugs/ # バグ調査・修正計画 │ ├── research/ # 実装検証結果・知見 │ ├── article/ # ブログ記事執筆用調査 │ │ └── CLAUDE.md # 記事執筆ガイド │ ├── tools/ # Docs専用ツール │ │ └── CLAUDE.md # ツール使用ガイド │ └── api/ # OpenAPI仕様 ├── application/ # 実装フェーズ │ ├── backend/ # NestJS APIサーバー │ │ └── CLAUDE.md # バックエンド開発ガイド │ ├── frontend/ # Next.js フロントエンド │ │ └── CLAUDE.md # フロントエンド開発ガイド │ ├── functions/ # X Scheduler │ │ └── CLAUDE.md # Functions開発ガイド │ └── blog-search-mcp-functions/ # MCP Server │ └── CLAUDE.md # MCP Functions開発ガイド ├── infrastructure/ # IaCテンプレート │ └── CLAUDE.md # インフラ開発ガイド ├── CLAUDE.md # ルートガイドライン(全体像) └── .github/ └── workflows/ # CI/CDパイプライン ├── frontend-swa-deploy.yml ├── backend-docker-build.yml ├── deploy-x-scheduler-functions.yml └── deploy-blog-search-mcp-functions.yml システム構成図 モノレポ全体の構成を視覚化するとこうなります: なぜモノレポなのか? モノレポ構成を採用した理由は、 AI 協業開発との相性の良さ にあります。 モノレポのメリット 1. AI に 1 つのリポジトリで全体像を提供 別リポジトリにすると、AI は各リポジトリのコンテキストを個別に理解する必要があります。モノレポなら、 ルートの CLAUDE.md で全体像を一度に提供 できます。 # 別リポジトリの場合(AIが混乱) frontend-repo/ ← AIはこのリポジトリのコンテキストのみ backend-repo/ ← 別のセッションで別のコンテキスト functions-repo/ ← また別のコンテキスト # モノレポの場合(AIが全体を把握) monorepo/ ├── CLAUDE.md ← 全体像をAIに提供 ├── application/ │ ├── frontend/ │ ├── backend/ │ └── functions/ 2. ディレクトリ構造の一貫性 すべてのアプリケーションが同じルールに従うため、AI が理解しやすくなります。 # すべてのアプリケーションにそれぞれのCLAUDE.mdがある /application/backend/CLAUDE.md /application/frontend/CLAUDE.md /application/functions/CLAUDE.md /application/blog-search-mcp-functions/CLAUDE.md 3. コード共有が容易 共通ライブラリ、型定義、ユーティリティ関数を複数のアプリで共有できます。 AI 協業開発を支える設計思想 このモノレポ環境には、3 つの核となる設計思想があります。 1. 計画と実装の分離 /docs/ (設計・仕様)と /application/ (実装コード)を明確に分離しています。 目的 : AI に「計画フェーズ」と「実装フェーズ」を明確に区別させる 実装前に設計を固めることで、手戻りを減らす /docs/features/my-new-feature/ ├── README.md # 機能概要 ├── api-spec.md # API設計(実装コードなし) └── type-definition.md # 型定義(実装コードなし) /application/backend/src/my-new-feature/ ├── my-new-feature.controller.ts # 実装コード ├── my-new-feature.service.ts # 実装コード └── dto/ # 実装された型定義 2. CLAUDE.md 階層構造 ルートで全体像、サブディレクトリで詳細ルールを提供します。 目的 : AI が必要な粒度でコンテキストを取得できる 各領域の専門的なルールを明確にする /CLAUDE.md ← プロジェクト全体像 ↓ /docs/CLAUDE.md ← 計画フェーズのルール ↓ /application/backend/CLAUDE.md ← バックエンド実装の詳細ルール 3. Single Source of Truth(型安全パイプライン) Backend DTOs を唯一の真実とし、Frontend の型定義は自動生成します。 詳細 : AI と爆速開発!Next.js×Nest.js 型定義同期の自動生成パイプライン構築術 を参照 Backend DTOs (@ApiProperty) ↓ OpenAPI 仕様生成 (generate:openapi) ↓ Frontend 型定義生成 (generate:api with Orval) ↓ 型安全なAPI呼び出し これら 3 つの設計思想により、 AI との協業開発が劇的にスムーズ になりました。 CLAUDE.md 階層構造の設計 ここからは、AI 協業開発の核となる CLAUDE.md 階層構造 について詳しく解説します。 CLAUDE.md とは? CLAUDE.md は、AI(Claude Code)にプロジェクトのコンテキストを提供するドキュメントです。 従来、AI に「このプロジェクトはどういう構成?」「どのルールに従えばいい?」と聞かれるたびに、手動で説明する必要がありました。CLAUDE.md を配置することで、 AI が自律的にガイドラインを読み、適切な判断をする ようになります。 9 つの CLAUDE.md ファイル このプロジェクトには、 合計 9 つの CLAUDE.md ファイル が配置されています。 # すべてのCLAUDE.mdファイルを確認 $ find . -maxdepth 3 -name "CLAUDE.md" | sort ./CLAUDE.md ./application/backend/CLAUDE.md ./application/blog-search-mcp-functions/CLAUDE.md ./application/frontend/CLAUDE.md ./application/functions/CLAUDE.md ./docs/article/CLAUDE.md ./docs/CLAUDE.md ./docs/tools/CLAUDE.md ./infrastructure/CLAUDE.md 各 CLAUDE.md の役割 : ファイルパス 役割 主な内容 /CLAUDE.md ルートガイドライン プロジェクト全体像、ディレクトリ構造、4 フェーズワークフロー、共通開発コマンド /docs/CLAUDE.md 計画フェーズルール 型定義、API 設計、データベース設計のルール(実装コード禁止) /docs/article/CLAUDE.md 記事執筆ガイド ブログ記事執筆の文体、構成、ドキュメント構造 /docs/tools/CLAUDE.md ツール使用ガイド Docs 専用ツール(ブログ HTML 抽出等)の使用方法 /application/backend/CLAUDE.md バックエンド開発ガイド NestJS 開発ルール、環境変数管理、テスト実行方法 /application/frontend/CLAUDE.md フロントエンド開発ガイド Next.js 開発ルール、インポートパス規則 /application/functions/CLAUDE.md X Scheduler 開発ガイド Azure Functions 開発ルール、Timer Trigger 設定 /application/blog-search-mcp-functions/CLAUDE.md MCP Functions 開発ガイド MCP Server 開発ルール、Supabase 連携 /infrastructure/CLAUDE.md インフラ開発ガイド Azure Bicep 開発ルール、デプロイ手順 コンテキスト継承パターン CLAUDE.md は、 階層的にコンテキストを継承 します。 継承の例 : ルート CLAUDE.md を読む → プロジェクト全体構成を理解 サブディレクトリの CLAUDE.md を読む → 各領域の詳細ルールを理解 AI が適切な判断を下す 実際の動き : AI: 「ユーザーがフロントエンドの開発を依頼してきた」 ↓ AI: 「まず /CLAUDE.md を読んで全体像を把握しよう」 ↓ AI: 「次に /application/frontend/CLAUDE.md を読んで詳細ルールを確認」 ↓ AI: 「インポートパスは @/* を使うべきだな」 AI: 「API型定義は自動生成されるから、手動で書いちゃダメだな」 ↓ AI: 適切なコードを提案 ルート CLAUDE.md の重要性 ルート CLAUDE.md ( /CLAUDE.md )は、最も重要なドキュメントです。 記載内容の例 # CLAUDE.md ## Project Architecture Overview LINE LIFF AI Prompt Battle - An AI-powered game platform... ### Directory Structure & Responsibilities / ├── docs/ # Planning & Design Phase │ ├── features/ # Feature specifications │ ├── bugs/ # Bug investigation & fix plans │ ├── research/ # Implementation validation │ └── article/ # Blog article research ├── application/ │ ├── backend/ # NestJS 11 API Server │ ├── frontend/ # Next.js 15 App Router │ ├── functions/ # Azure Functions │ └── blog-search-mcp-functions/ # MCP Server └── infrastructure/ # Azure Bicep IaC **Workflow Pattern (4-Phase Workflow)**: 1. **計画フェーズ** - Plan in `/docs/` 2. **実装フェーズ** - Implement in `/application/` 3. **研究記録フェーズ** - Document findings in `/docs/research/` 4. **記事化フェーズ** - Gather materials in `/docs/article/` ## Common Development Commands ### Backend (NestJS) npm run start:dev # Development with watch mode npm run generate:openapi # Generate OpenAPI spec ### Frontend (Next.js) npm run generate:api # Generate types from OpenAPI npm run dev:full # generate:api + dev server ## Critical Import Path Rules ### Frontend: Use `@/*` Path Aliases // ✅ CORRECT import { Button } from '@/components/ui/button'; // ❌ WRONG import { Button } from '../components/ui/button'; ポイント : プロジェクト全体構成 を一目で理解できる 4 フェーズワークフロー を明記 共通開発コマンド を記載 インポートパス規則 等の重要ルールを記載 ※注 : 上記コード例は、実際のプロジェクト CLAUDE.md での記載例です。本記事では「4 フェーズワークフロー」または「ドキュメント駆動型開発」と呼称しています。 このルート CLAUDE.md があることで、AI は 初めてプロジェクトに触れた時でも、全体像を即座に理解 できます。 CLAUDE.md 階層構造の効果 この階層構造により、以下の効果が得られました: AI の理解速度が向上 ルート CLAUDE.md で全体像を把握し、サブディレクトリで詳細を理解 一貫性のあるコード生成 すべての開発者(人間も AI も)が同じルールに従う 手動説明の削減 「どういうプロジェクト?」と聞かれることがなくなった オンボーディング時間の短縮 新しい AI セッション、新しい開発者が即座に理解できる ドキュメント駆動型開発の実践(3 フェーズ →4 フェーズへの進化) Claude Code での開発を効率化するため、 計画 → 実装 → 研究記録 → 記事化の 4 フェーズワークフロー を構築しました。 3 フェーズ開発から 4 フェーズ開発への進化 このワークフローは、 既存の 3 フェーズ開発を基盤に構築 されています: 元々の 3 フェーズ開発 ( 計画 → 実装 → 検証術 、 仕様書アレルギー克服 で解説): 計画 : /docs/ で仕様策定(実装コードは書かない) 実装 : /application/ で実装 検証 : 計画と実装の差異を分析 4 フェーズへの拡張 ( 知見を資産化する記事 で詳細解説): フェーズ 3 を「研究記録」として体系化 : 検証フェーズで得た知見を /docs/research/ に記録 フェーズ 4「記事化」を追加 : 研究記録を元に /docs/article/ で記事執筆 RAG もどきシステム : 既存記事参照でトークン数 50-60%削減 文体補正システム : 一貫した記事品質を実現 各フェーズの概要 フェーズ 1: 計画 ( /docs/features/ ) 目的 : 実装前の設計・仕様策定(実装コードは一切書かない) 成果物 : 型定義、API 設計、データベース構造、アーキテクチャ設計 効果 : 開発時間 1 週間 →2 日に短縮( 仕様書アレルギー克服の記事 で詳細解説) 重要ルール : CLAUDE.md で実装コード記述を禁止することで、AI が設計に集中 フェーズ 2: 実装 ( /application/ ) 目的 : 計画に基づいた実装 実装順序 : Backend → Frontend → Functions 効果 : 小規模システムで 30 分、中規模で 2 日程度( 3 フェーズ開発の記事 で実例紹介) フェーズ 3: 研究記録 ( /docs/research/ ) 目的 : 実装完了後の知見・アーキテクチャ検証結果をドキュメント化 記載内容 : 設計思想、アーキテクチャパターン、検証結果 重要性 : 計画と実装の差異を分析し、仕様漏れを特定 ※補足 : 3 フェーズ開発の記事 で「検証フェーズ」として解説している内容を、このプロジェクトでは「研究記録フェーズ」として体系化しています。実装完了後に計画と実装の差異を分析し、知見として記録します。 フェーズ 4: 記事化 ( /docs/article/ ) 目的 : 技術ブログ執筆に必要な情報収集・調査、 知見の資産化 成果物 : research-doc.md (調査資料)、 no1-article.md (記事本文) 参照元 : /docs/features/ + /docs/research/ + /application/ 効率化ツール ( 知見を資産化する記事 で詳細解説): RAG もどき (fetch-blog-html.ts): 既存記事参照でトークン数 50-60%削減 文体補正 (writing-style-prompt.md): 一貫した記事品質 記事執筆時間 50%削減 : 調査資料から記事執筆までの自動化 重複チェック 83%削減 : 既存記事との重複を自動検出 このワークフローの効果 知見が自然に蓄積 – 実装と同時にドキュメントが作成される 記事化がスムーズ – 計画 → 検証 → 実装コードを参照するだけ 手戻りが減少 – 計画フェーズで設計を固めることで、実装時の手戻りが減少 開発時間 1 週間 →2 日に短縮(計画フェーズの効果) AI との協業が効率化 – 各フェーズで AI に明確な役割を与えられる 知見が資産化される – フェーズ 4(記事化)により、開発知見が再利用可能なブログ記事として蓄積 既存記事との重複チェック 83%削減 技術ブログのライブラリが自然に形成される 型安全な API 開発パイプライン Frontend と Backend の型ズレをゼロにする 型安全パイプライン については、別記事で詳しく解説しています。 詳細を学ぶ : AI と爆速開発!Next.js×Nest.js 型定義同期の自動生成パイプライン構築術 Single Source of Truth の原則 このプロジェクトでは、 Backend DTOs を唯一の真実 としています。 Frontend の型定義は、Backend から自動生成するため、 手動で型定義を同期する作業が不要 になります。 型安全パイプラインの効果 型ズレゼロ – Backend と Frontend の型が常に一致 手動同期作業の撲滅 – 型定義を手動でコピー&ペーストする必要がない リファクタリング時の安全性 – Backend の型を変更すると、Frontend でコンパイルエラーが出る 開発速度向上 – 型定義を書く時間が不要になり、実装に集中できる モノレポ CI/CD パイプライン: paths フィルタの威力 次に、4 つのアプリケーションを並行デプロイする 最適化された CI/CD パイプライン について解説します。 4 つの独立したワークフロー このプロジェクトでは、 4 つの独立した GitHub Actions ワークフロー を使用しています。 ワークフロー トリガーパス デプロイ先 ビルド時間(平均) frontend-swa-deploy.yml application/frontend/** Azure Static Web Apps 3 分 backend-docker-build.yml application/backend/** GitHub Container Registry → Azure Web Apps 5 分 deploy-x-scheduler-functions.yml application/functions/** Azure Functions (X Scheduler) 2 分 deploy-blog-search-mcp-functions.yml application/blog-search-mcp-functions/** Azure Functions (MCP Server) 2 分 paths フィルタによる最適化 課題 : モノレポ全体をビルドすると、変更のないアプリもビルドされ時間がかかる 解決策 : GitHub Actions の paths フィルタで、変更されたディレクトリのみをトリガー 例: Frontend SWA Deploy # .github/workflows/frontend-swa-deploy.yml name: Frontend SWA Deploy on: push: branches: - main paths: - "application/frontend/**" - ".github/workflows/frontend-swa-deploy.yml" workflow_dispatch: ポイント : paths フィルタで application/frontend/** のみをトリガー Backend を変更しても、Frontend のワークフローは実行されない Before/After 比較 Before(paths フィルタなし) Backend を変更 ↓ 全ワークフロー実行(Frontend, Backend, Functions, MCP Functions) ↓ 合計ビルド時間: 12分(3 + 5 + 2 + 2) After(paths フィルタあり) Backend を変更 ↓ Backend ワークフローのみ実行 ↓ 合計ビルド時間: 5分(58%削減) 並行デプロイの実現 4 つのワークフローが 独立している ため、複数のアプリを同時に変更した場合、 並行デプロイ が実現されます。 Frontend と Backend を同時に変更 ↓ frontend-swa-deploy.yml と backend-docker-build.yml が並行実行 ↓ 合計ビルド時間: 5分(逐次実行なら8分) CI/CD パイプラインの効果 ビルド時間 58%削減 – paths フィルタにより、変更のないアプリはビルドされない 並行デプロイ – 複数のアプリを同時に変更しても、並行実行で時間短縮 安全なデプロイ – 各アプリが独立しているため、Frontend のデプロイ失敗が Backend に影響しない 開発体験の変化(Before/After) モノレポ ×AI 協業開発環境を導入する前後で、開発体験がどう変わったかを比較します。 Before(モノレポ ×AI 環境導入前) 問題点 AI に毎回プロジェクト構成を説明 開発者: 「ユーザー管理機能を実装して」 AI: 「このプロジェクトはどういう構成ですか?」 開発者: 「Backendは...Frontendは...」(毎回説明) CI/CD ビルド時間の増加 Backend を変更 ↓ 全ワークフロー実行(Frontend, Backend, Functions) ↓ 合計ビルド時間: 12分 ドキュメントが散らばって、どこに何があるかわからない 計画ドキュメント: Notion 実装コメント: コード内 ブログ記事: 別リポジトリ ↓ 情報が散らばって、どこに何があるかわからない After(モノレポ ×AI 環境導入後) 改善点 AI が自律的にプロジェクト構成を理解 開発者: 「ユーザー管理機能を実装して」 AI: 「/CLAUDE.md を確認します」 AI: 「/application/backend/CLAUDE.md を確認します」 AI: 「型安全パイプラインに従って実装します」 CI/CD ビルド時間 50%削減 Backend を変更 ↓ Backend ワークフローのみ実行(pathsフィルタ) ↓ 合計ビルド時間: 5分(50%削減) ドキュメントが自然に蓄積し、資産化される 4フェーズワークフロー 計画 (/docs/features/) ↓ 実装 (/application/) ↓ 研究記録 (/docs/research/) ↓ 記事化 (/docs/article/) ├─ RAGもどき(fetch-blog-html.ts)でトークン数50-60%削減 └─ 文体補正(writing-style-prompt.md)で一貫した記事品質 ↓ 情報が整理され、知見が資産化される 技術ブログのライブラリが自然に形成される 定量的な効果 指標 Before After 改善率 初期説明時間 10 分/セッション ほぼ不要(CLAUDE.md で自律理解) 大幅削減 CI/CD ビルド時間 12 分 5 分 58%削減 ドキュメントメンテナンス時間 週 5 時間 週 2 時間 60%削減 新機能開発スピード 2 週間 1 週間 50%短縮 記事執筆時間 6-8 時間 3-4 時間 50%削減 ※測定条件 : 小規模〜中規模機能開発(バックエンド API エンドポイント 2-4 個、フロントエンド画面 1-2 個規模)での実測値です。プロジェクトの規模や複雑さによって効果は変動します。記事執筆時間は、調査資料作成から記事本文執筆までの合計時間です。 龍ちゃんの所感 導入前の課題 : プロジェクトが小さいうちは問題なかったんですが、いろんな検証を詰め込んでプロジェクトが大きくなってくると、 ドキュメントを編集するだけでビルドが走る という問題が出てきました。適切にビルドを分割することで、不要な CI/CD の実行を抑える必要が出てきたんです。 また、フロントエンド・バックエンド・Functions(バッチ処理)という複数の構成でアプリを作っていたので、 API 連携やデータベース連携がスムーズに行える環境 が必要でした。例えば、バックエンドでデータベースに情報を入れて、それをバッチ処理で取得して実行するような連携ですね。 AI 協業開発での気づき : AI と開発する上で、フロントエンドとバックエンドの型ズレを解消するためにも、 アプリケーション全体を AI に見える形で一つに集約する ことがやはり大事だなと実感しました。これは自分の中でもすごく効果的でしたね。 検証とブログ執筆の課題 : 自分の検証スタイルとして、「インプットを入れたらアウトプットを出す」というのが弊社の理念でもあり、このブログの意義でもあるので、検証とブログ執筆はセットで考えていました。 ただ、検証が終わった後に、別でブログを書くためのシステムを立ち上げて…というのが割と面倒になってきたんです。もう 3 年で 200 記事くらい書いているんですが、だんだん検証する内容も大きくなってきて、記事も長くなってきました。 ソースコード参照の課題と解決策 : 記事を書く際に ソースコードを参照することが増えて きたんですが、参照するファイルが増えれば増えるほど、ブログを書く障壁がどんどん上がってきました。 そこで、 リポジトリから直接情報を吸い出してブログを書くシステム (4 フェーズワークフロー、RAG もどき、文体補正)を構築したことで、ブログ執筆の効率化がさらに進んだと感じています(詳細は 検証 → 記事化で知見を資産化!Claude Code×RAG もどきで AI 技術ブログ執筆を効率化 を参照)。 まとめ この記事では、 モノレポ ×AI 協業開発環境 の構築術について解説しました。 モノレポ ×AI 協業開発環境のポイント CLAUDE.md 階層構造でコンテキスト管理 9 つの CLAUDE.md ファイルで、AI に適切な粒度の情報を提供 4 フェーズワークフロー(計画 → 実装 → 研究記録 → 記事化) ドキュメント駆動型開発で、知見が自然に蓄積され、資産化される 3 フェーズ開発を基盤に、フェーズ 4(記事化)を追加 RAG もどき、文体補正による記事執筆効率化 型安全パイプライン(Backend DTOs → OpenAPI → Frontend Types) Single Source of Truth で、型ズレゼロを実現( 型安全パイプラインの詳細記事 ) paths フィルタによる最適化 CI/CD 4 つの独立ワークフローで、ビルド時間 58%削減 開発体験の変化 Before After AI に毎回プロジェクト構成を説明 CLAUDE.md で自律的に理解 CI/CD ビルド時間 12 分 paths フィルタで 5 分(58%削減) ドキュメントが散らばる 4 フェーズワークフローで自然に蓄積、資産化 記事執筆に時間がかかる RAG もどき、文体補正で 50%削減 次のステップ この記事を読んで、モノレポ ×AI 協業開発環境に興味を持った方は、以下のステップで実践してみてください: 1. CLAUDE.md を作成 まずは、プロジェクトルートに CLAUDE.md を作成し、プロジェクト全体像を記載します。 # CLAUDE.md ## Project Architecture Overview (プロジェクトの概要) ### Directory Structure (ディレクトリ構造) ## Workflow Pattern (4-Phase Workflow) 1. **計画フェーズ** - Plan in `/docs/` 2. **実装フェーズ** - Implement in `/application/` 3. **研究記録フェーズ** - Document findings in `/docs/research/` 4. **記事化フェーズ** - Gather materials in `/docs/article/` 2. paths フィルタを導入 GitHub Actions ワークフローに paths フィルタを追加します。 on: push: branches: - main paths: - "application/frontend/**" 3. 4 フェーズワークフローを実践 新機能開発時は、計画 → 実装 → 研究記録 → 記事化の 4 フェーズを順に進めます。 詳細は 3 フェーズ開発の基本を学ぶ記事 を参照してください。 参考リンク 関連記事(本サイト) AI 協業開発手法シリーズ Claude Code 革命!3 フェーズ開発で効率的な開発:計画 → 実装 → 検証術 AI 協働で仕様書アレルギー克服!開発時間を 1 週間 →2 日に短縮する実践法 検証 → 記事化で知見を資産化!Claude Code×RAG もどきで AI 技術ブログ執筆を効率化 型安全パイプライン AI と爆速開発!Next.js×Nest.js 型定義同期の自動生成パイプライン構築術 公式ドキュメント Claude Code 公式ドキュメント NestJS 公式ドキュメント Next.js 公式ドキュメント GitHub Actions 公式ドキュメント Orval 公式ドキュメント ここまで読んでいただき、ありがとうございました! モノレポ ×AI 協業開発環境を構築することで、開発体験が劇的に向上します。ぜひ、この記事を参考に、あなたのプロジェクトでも実践してみてください。 質問や感想は、コメント欄でお待ちしております。また、Twitter のほうもよろしくお願いします! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post AI 協業開発環境の構築術|モノレポでビルド時間を大幅短縮する CLAUDE.md 活用法 first appeared on SIOS Tech. Lab .
動画
該当するコンテンツが見つかりませんでした
書籍
該当するコンテンツが見つかりませんでした










