零弐壱蜂

[GitHub Actions] `actions/ai-inference`を利用したPR自動要約の実装

背景

GitHub 公式が公開した actions/ai-inference アクションにより、ワークフロー内での AI モデルの利用が簡単にできるようになった。これを利用して、PR の変更内容を要約するワークフローを実装してみる。

方法

ワークフロー定義

actions/ai-inference アクションを利用して、PR の変更内容を要約する GitHub Actions のワークフロー定義は以下である。

# .github/workflows/ai-summary.yml
name: Summarize PR

on:
  pull_request:
    types: [labeled] # 'labeled' イベントをトリガーとする

jobs:
  summary:
    # 'ai-summary' ラベルが付与された場合のみ実行
    if: github.event.label.name == 'ai-summary'
    runs-on: ubuntu-latest
    # 必要な権限を設定
    permissions:
      pull-requests: write # PR へのコメント書き込み
      models: read # AI モデルへのアクセス
      contents: read # リポジトリコンテンツの読み取り

    steps:
      # リポジトリのコードをチェックアウト
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # 全履歴を取得して diff を正確に計算

      # PR の差分を取得
      - name: Fetch PR diff
        id: fetch_diff
        run: |
          # ベースブランチとヘッドコミットの参照を取得
          BASE_REF="origin/${{ github.event.pull_request.base.ref }}"
          HEAD_SHA="${{ github.event.pull_request.head.sha }}"

          echo "Base ref: ${BASE_REF}"
          echo "Head SHA: ${HEAD_SHA}"

          # ベースブランチとヘッドブランチの情報をフェッチ
          git fetch origin ${{ github.event.pull_request.base.ref }}
          git fetch origin ${{ github.event.pull_request.head.ref }}

          # git diff コマンドで変更ファイルリストとステータスを取得
          echo "Running git diff --name-status..."
          CHANGED_FILES=$(git diff --name-status ${BASE_REF}...${HEAD_SHA})
          if [ $? -ne 0 ]; then
            echo "Error: git diff command failed."
            exit 1
          fi

          echo "${CHANGED_FILES}"

          # 取得した差分情報をステップ出力 'files' として設定
          echo "Setting files output..."
          EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
          echo "files<<$EOF" >> $GITHUB_OUTPUT
          echo "${CHANGED_FILES}" >> $GITHUB_OUTPUT
          echo "$EOF" >> $GITHUB_OUTPUT
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GitHub API アクセス用トークン

      # AI 推論を実行
      - name: Run AI inference
        id: inference
        uses: actions/ai-inference@v1
        with:
          max-tokens: 500 # 生成する最大トークン数 (後述の考察を参照)
          prompt: |
            PRの差分を分析し、**必ず下記の指定フォーマットに従い概要を日本語で生成してください。**
            **全体で300トークンを目安に、各項目は最も重要な点に絞って簡潔に記述してください。**

            ```フォーマット
            ## PRレビュー概要

            ### 主な目的
            {diffから推測される、この変更の**最も重要な目的やゴール**を1〜2文で記述}

            ### 範囲
            {変更が加えられた**主要なファイル種別や機能領域**を簡潔に列挙}

            ### 影響範囲
            {この変更によって特に注意すべき**影響(システム動作、UX、他機能等)**を1〜2点で記述}
            ```

            ```分析対象のPR Diff
            ${{ steps.fetch_diff.outputs.files }} # 前のステップで取得した差分情報を埋め込む
            ```

      # PR にコメントを投稿
      - name: Comment
        uses: marocchino/sticky-pull-request-comment@v2
        with:
          header: ai-summary-comment # コメントを識別するためのヘッダー
          message: ${{ steps.inference.outputs.response }} # AI が生成した要約

ワークフロー解説

トリガ (on)

PR へのラベル付与 (pull_request イベントの labeled タイプ) をトリガとする。

 note

トリガを labeled イベントに限定することで、不要な AI 実行とトークン消費を抑制できる。開発者が必要と判断したタイミングで ai-summary ラベルを付与する運用が効率的である。

ジョブ (jobs.summary)

summary ジョブは、ai-summary ラベルが付与された場合のみ実行される (if: github.event.label.name == 'ai-summary')。 実行に必要な権限(permissions)として以下を設定しておく。

  • pull-requests: write: PR へのコメント書き込み権限
  • models: read: AI モデルへのアクセス権限
  • contents: read: リポジトリのコンテンツ(コード)読み取り権限

ステップ (steps)

  1. Checkout repository:
    actions/checkout@v4 でリポジトリをチェックアウト。fetch-depth: 0 を指定することで、全履歴を取得し、後続の git diff コマンドが正確な差分を計算できるようにする。

  2. Fetch PR diff:
    git diff --name-status コマンドを実行し、PR のベースブランチとヘッドコミットの間の差分情報を取得する。

    • --name-status オプションにより、具体的にどのファイルが追加(A)変更(M)削除(D)されたかという情報のみを取得する。
    • 取得した差分情報(ファイルリストとステータス)は、ステップ出力 files に設定され、後続の AI 推論ステップで利用される。
     important

    理想的には PR の完全なコード差分(Unified Diff 形式など)を AI に与えたいところだが、差分量が大きい場合に actions/ai-inference アクションが「予期せぬエラー」を発生させる。あくまで「要約」を得るという目的から、現状ではファイル名と変更ステータスのみを入力情報として渡す実装としている。

    このステップで取得され、後続の AI 推論ステップのプロンプトに渡される情報の例は以下のようになる。

    A	.github/workflows/ci-build.yml
    D	docs/old-feature-guide.md
    D	src/legacy/utils.js
    M	package-lock.json
    M	package.json
    M	src/components/UserProfile.jsx
    M	src/styles/variables.css
    
  3. Run AI inference:
    actions/ai-inference@v1 アクションを使用して AI が推論し、PR の要約を生成する。

     caution

    このアクションは内部的に GitHub Models を利用するが、GitHub Models は現在、学習・実験・概念実証(PoC)向けの提供である (Responsible use of GitHub Models 参照)。本番環境での利用には注意が必要である。

    サンプルコードでは生成される応答の最大トークン数を max-tokens: 500 で指定している。この値は、プロンプト内で指示した目安(300トークン)に対して十分な余裕を持たせるための値である。

サンプルコード

実行例

上記ワークフローによって PR に投稿されるコメントの例を以下に示す。これは、ファイル削除、設定変更、スタイル改善、ワークフロー追加を含む PR に対して生成された要約コメントである。

## PRレビュー概要

### 主な目的

この変更の主な目的は、リポジトリ内の不要ファイルを整理し、依存関係や設定ファイルを更新することで、プロジェクト全体の構成を改善することです。

### 範囲

- **ファイル削除**: 不要となったドキュメントファイルや古いコンポーネントファイルが削除されました。
- **設定変更**: パッケージ管理ファイル (`package.json`, `lockファイル`) やビルド設定が更新されました。
- **コード改善**: UIコンポーネントのスタイルや関連するカスタムフックが修正・改善されました。
- **新規ファイル**: CI/CDプロセスに関連する新しいワークフロー定義ファイル (`.github/workflows/`) が追加されました。

### 影響範囲

- **UI/UX**: スタイルやコンポーネントの変更により、一部画面の表示や挙動が変わる可能性があります。
- **開発プロセス**: 新しいワークフローの追加により、ビルドやデプロイのプロセスに影響が出る可能性があります。
 tip

要約コメントはレビュアーが PR の概要を素早く把握するのに役立つ。特に大規模な変更を含む PR の場合、どこに注目すべきかの指針となる。

まとめ

actions/ai-inference を用いることで、GitHub Actions ワークフロー内で AI モデルを利用した PR 要約機能を比較的簡単に構築できた。ai-summary ラベルを付与するだけで要約が自動生成されるため、レビュアーの負担軽減やレビュープロセスの効率化が期待できる。

余談

Copilot コード レビューもPRに概要(Overview)をコメントで残してくれる。今回作成したactions/ai-inferenceを利用したPR要約機能と比較しておく。

Copilotactions/ai-inference