push するたびにドキュメントが更新される世界
エンジニアはコードを書く。pushする。それだけでドキュメントが自動的に更新され、専用のGitHubリポジトリにコミットされる——これが RepoCarta が実現したい世界です。
「ドキュメントを書こう」という意識改革では限界があります。重要なのは、ドキュメントの生成・更新を開発フローから切り離さないことです。pushするたびに自動更新されるなら、エンジニアには追加作業がゼロになります。
この記事では、その仕組みの技術的な核心——GitHub Appを使ったWebhook受信から、SQSキュー、Lambda非同期処理、Claude APIによる生成、そしてGitコミットまでのパイプラインを詳しく解説します。
GitHub Appの仕組み: インストール・Webhook・権限
GitHub Appは、個人のOAuthトークンではなくアプリとしてGitHubに登録し、ユーザーやOrganizationにインストールしてもらう仕組みです。OAuth Appとの最大の違いは、きめ細かな権限管理と、Installation単位でのアクセストークン発行ができる点です。
認証の3層構造
GitHub Appの認証は以下の3層で構成されます。
- App Authentication (JWT): App自体を認証するためのJWT。App IDとPEM形式のPrivate Keyで署名し、有効期間は最大10分。
- Installation Access Token: 特定のInstallation(ユーザーがAppをインストールした単位)への操作権限を持つトークン。JWTを使って発行し、1時間で失効。
- Webhook Secret: GitHubからのWebhookリクエストが本物かを検証するためのHMAC-SHA256署名の検証キー。
必要な権限スコープ
RepoCarta のGitHub Appが要求する権限は最小限に絞っています。
- Repository contents: Read — コードの読み取り
- Repository contents: Write — ドキュメントリポジトリへのコミット
- Metadata: Read — リポジトリのメタデータ参照(必須)
- Webhook events: push — pushイベントの受信
実装の流れ
-
1Webhookイベント受信(Receiver Lambda)
GitHubからのpushイベントをAPI Gateway経由でLambdaが受け取る。まずWebhook Secretを使ってHMAC-SHA256署名を検証し、正規のGitHubリクエストか確認する。検証後、ペイロード(コミット差分・リポジトリ情報)をSQSキューに格納し、即座に200 OKをGitHubに返す。
-
2SQSキューによるバッファリング
Receiver LambdaからSQSへのenqueueは数ミリ秒で完了する。SQSがバッファの役割を果たすことで、同時に大量のpushが来ても処理が詰まらない。Visibility Timeoutは20分に設定(Worker Lambdaの最大実行時間15分 + 余裕5分)。
-
3Worker Lambdaによる非同期処理
SQSのメッセージをトリガーにWorker Lambdaが起動。Installation Access Tokenを取得し、GitHub APIで変更ファイルの内容を取得する。変更の種類(新規ファイル / 修正 / 削除)に応じてプロンプトを組み立て、Claude APIに送信する。
-
4Claude APIによるドキュメント生成
コードの差分をClaudeに送り、変更内容を反映したMarkdownを生成する。既存のドキュメントがある場合は「現在のドキュメント」も合わせて渡し、更新箇所だけを書き換えるよう指示する。生成されたMarkdownは後処理で整形される。
-
5Gitコミット(ドキュメントリポジトリ)
生成したMarkdownをGitHub APIでドキュメント用リポジトリにコミットする。コミットメッセージには「[repocarta] Update docs for commit abc1234」のように元のコミットSHAを含め、トレーサビリティを確保する。
つまずいた点と解決策
1. GitHub App JWT認証: clock skewの罠
JWTのiats(issued at)をぴったり現在時刻にすると、GitHubのサーバーと数秒のずれがあった場合に「future-dated token」として拒否されることがありました。
iat を現在時刻 - 60秒 に設定することで、clock skew を吸収できます。
解決策は上述のコード例の通り、iat を time.time() - 60 にすることです。これは公式ドキュメントにも記載されていますが、見落としやすい箇所です。
2. SQS Visibility Timeout と Lambda の実行時間
SQSのVisibility Timeoutがデフォルト30秒だと、大きなリポジトリのドキュメント生成中(1〜5分かかることがある)に「メッセージが再配信される」問題が発生しました。同じコミットのドキュメントが二重生成される障害です。
3. Installation Access Tokenのキャッシュ
Installation Access Tokenは1時間で失効するため、Lambda呼び出しのたびに発行すると、GitHub APIのレートリミット(App当たり1時間5000リクエスト)を無駄に消費します。ElastiCacheを使ってトークンをキャッシュし、有効期限の5分前に再取得するロジックを実装しました。
4. 大量のWebhookペイロードによるSQSメッセージサイズ制限
GitHubのWebhookペイロードは、大きなdiffを含む場合に256KBを超えることがあります。SQSのメッセージサイズ制限(256KB)を超えると送信に失敗します。解決策として、ペイロードをS3に保存し、SQSにはS3のキーのみを格納するS3ポインターパターンを採用しました。
実際にどのくらいのドキュメントが生成されるか
実際に使っていただいているユーザーのデータから、いくつかの目安をお伝えします。
生成されるドキュメントの主な種類は以下です。
- README.md: プロジェクト概要・セットアップ手順・基本的な使い方
- ARCHITECTURE.md: システム全体のアーキテクチャと主要コンポーネントの説明
- API.md: APIエンドポイントの一覧・リクエスト/レスポンス形式
- modules/*.md: 主要モジュール・クラスの詳細説明
- CHANGELOG.md: コミット履歴から自動生成した変更履歴
現時点でサポートしている言語はPython、TypeScript/JavaScript、Go、Javaです。その他の言語も順次対応予定です。
まとめ
GitHub AppのWebhook連携からSQS・Lambda・Claude APIを経てGitコミットまでのパイプラインを組むことで、「pushするたびにドキュメントが更新される」仕組みが実現できました。
実装の核心は非同期処理の分離と冪等性の確保です。Webhookの受信を即時処理し、重い処理を非同期に委譲することで、GitHub側のタイムアウトを回避しながらスケーラビリティを確保しています。
GitHub Appの認証周りは最初の壁ですが、一度理解すると非常に強力な仕組みです。リポジトリへの細かい権限管理、複数Organization対応、Webhook署名検証——これらが揃ったGitHub Appは、今後のGit連携ツールの標準になると思っています。
RepoCarta を使えば、この複雑な実装を自分で行うことなく、GitHubリポジトリに接続するだけでドキュメント自動更新の恩恵を受けられます。14日Trialから試せますので、ぜひ使ってみてください。