0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

#125 ChatGPT+Githubで自動コードレビューを実装してみる①

Posted at

初めに

先日、AWSのCodeGuruを使ってコードレビューを実装してみましたが、ChatGPTをGithubと連携させてコードレビューの自動化を実装することもできるんじゃないかと思いトライしてみたので、その実装方法について2回に分けて書いていきたいと思います。
今回はコードレビュー用のスクリプト作成し、プルリクエストに対してコードレビューコメントを残すところまでやってみました!

前提条件

GitHubアカウント
OpenAI APIキー ※ChatGPT有料プランに登録してAPIキーを取得
Node.jsがインストールされた開発環境

必要なパッケージのインストール

・openai: OpenAI APIとの通信を行うためのパッケージ。
・@octokit/rest: GitHub APIとの通信を簡単に行うためのパッケージ。
・dotenv: 環境変数を管理するためのパッケージ。
以下のコマンドで、これらのパッケージをインストールします。

Terminal
npm install openai @octokit/rest dotenv

環境変数の設定

APIキーやGitHubトークンを安全に管理するため、環境変数を使用します。プロジェクトのルートディレクトリに .env ファイルを作成し、以下の内容を記載します。

env
OPENAI_API_KEY=your_openai_api_key
GITHUB_TOKEN=your_github_token

・OPENAI_API_KEY: OpenAIから発行されたAPIキー。OpenAPIのダッシュボードから作成できる。
・GITHUB_TOKEN: GitHubのパーソナルアクセストークン(PAT)。これにより、リポジトリへのアクセスが可能になります。

コードレビュー用スクリプトの作成

review.js
import { Octokit } from '@octokit/rest';
import { OpenAI } from 'openai';
import dotenv from 'dotenv';

dotenv.config();

const octokit = new Octokit({
  auth: process.env.GITHUB_TOKEN,
});

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

// 再試行用の関数
const retryRequest = async (fn, retries = 3, delayMs = 1000) => {
  try {
    return await fn();
  } catch (error) {
    if (retries === 0 || error.code !== 'insufficient_quota') {
      throw error;
    }
    console.log(`Retrying request in ${delayMs} ms...`);
    await new Promise(resolve => setTimeout(resolve, delayMs));
    return retryRequest(fn, retries - 1, delayMs);
  }
};

async function reviewPullRequests(owner, repo) {
  try {
    // developmentブランチへのプルリクエストを取得
    const { data: pullRequests } = await octokit.pulls.list({
      owner,
      repo,
      base: 'development',
      state: 'open',
    });

    for (const pr of pullRequests) {
      console.log(`レビュー中: ${pr.title} (#${pr.number})`);

      // プルリクエスト内の変更ファイルを取得
      const { data: files } = await octokit.pulls.listFiles({
        owner,
        repo,
        pull_number: pr.number,
      });

      for (const file of files) {
        // ファイルの内容を取得
        const { data: fileContent } = await octokit.repos.getContent({
          owner,
          repo,
          path: file.filename,
          ref: pr.head.sha, // プルリクエストのHEAD SHAを使用
        });

        // Base64エンコードされたコンテンツをデコード
        const content = Buffer.from(fileContent.content, 'base64').toString('utf-8');

        // ChatGPTにコードレビューを依頼
        const response = await retryRequest(() => openai.chat.completions.create({
          model: 'gpt-3.5-turbo',
          messages: [
            { role: 'user', content: `次のコードをレビューしてください:\n\n${content}` },
          ],
          max_tokens: 500,
        }));

        const comment = response.choices[0].message.content.trim();

        // GitHubにコメントを投稿
        await octokit.issues.createComment({
          owner,
          repo,
          issue_number: pr.number,
          body: `File: ${file.filename}\n\n${comment}`,
        });

        console.log("レビュー結果をプルリクエストにコメントしました。");
      }
    }
  } catch (error) {
    console.error('Error during code review:', error);
  }
}

// 使用例
reviewPullRequests(your_github_username, 'repository_name', 1);

スクリプトの実行と動作確認

Terminal
node review.js

プルリクエストを確認しに行くと以下のようなコメントが追加されていました。
gpt-github-review-1

参考資料

・GitHub API Documentation:
https://docs.github.com/en/rest

・OpenAI API Documentation:
https://platform.openai.com/docs

・GitHub Actions Documentation:
https://docs.github.com/en/actions

おわりに

今回はコードレビュー用のスクリプト作成までやってみました。次回はGithub Actionsと連携して対象のブランチに対してプルリクエストが作成された際に、今回作成されたスクリプトが実行され自動でコードレビューをコメントが投稿されるようにしてみます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?