【Code Rabbit】自動コードレビューのチューニングをカンタンにしてみた

## はじめに
この記事はエアークローゼット Advent Calendar 2023 2日目の記事になります:christmas_tree: 

https://qiita.com/advent-calendar/2023/air-closet

## この記事のまとめ
* レビュアーの負担軽減のため、自動コードレビュー(ai-pr-reviewer)を導入してみました
* 命令文をyamlファイルから剥がすことで、複数のリポジトリに展開した後の修正を簡単にしました。

## あらまし
ケアレスミスやアンチパターンのレビューに疲弊していたある日、以下の記事を読みました

https://zenn.dev/minedia/articles/7928ef7545b393

「おもしろそう！！」と思うと同時に、「**複数リポジトリに展開**したとして、チューニングしたいとき**毎回全部のリポジトリで修正**しなきゃいけないの？めんどくさすぎる...。」という気持ちになりました。

そこで、ゴニョゴニョとツールを繋ぎ合わせることで、修正を簡単にできないかと企てました。

## 構成
Google Spread Sheetに命令文を保管し、それらをGoogle App Script経由で取得します。
各リポジトリに自動コードレビューを展開した後でチューニングしたくなった場合も、スプレッドシートを編集すれば全てのリポジトリに展開される形を目指します。
![ai-pr-reviwer.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751808/307c390b-8c49-e22d-a93a-499df0c2f03c.png)

:::note warn
手軽だったのでこの構成にしていますが、要するに **「どこかに命令文を切り出しておくと更新がカンタン」** という話なので、Googleまわりのサービスである必要はありません。
:::

## 実装
かなりの量を割愛しているため、前述の記事と合わせて読んでいただけると非常に助かります:pray:

### Google Spread Sheet
割愛します。いい感じにSpread Sheetに命令文を置いておきましょう。
(面倒な場合、GASに直接書くのもありです)

### Google App Script
```javascript:index.gs
const IMPERATIVE_STATEMENT_FILE_ID = ""; // 命令文を置いたSpread SheetのID
const IMPERATIVE_STATEMENT_FILE_SHEET_NAME = ""; // 命令文を置いたSpread Sheetのシート名

function doGet() {
  const sheet = SpreadsheetApp.openById(IMPERATIVE_STATEMENT_FILE_ID).getSheetByName(IMPERATIVE_STATEMENT_FILE_SHEET_NAME);
  const dataRange = sheet.getDataRange();
  const rawData = dataRange.getValues();

  const imperativeStatement = // ここでSpread Sheetの情報をいい感じに整形

  return ContentService.createTextOutput(JSON.stringify(imperativeStatement) ).setMimeType(ContentService.MimeType.JSON);
};
```
* `doGet`を定義し、GET methodで取得できるようにしておきます。
* Google Spread Sheetから取得したデータの整形は割愛していますが、JavaScriptでお好みの形に整形します。
* Github Actionsで使用するため、[Webアプリとしてデプロイ](https://developers.google.com/apps-script/guides/web?hl=ja)のうえ、URLをコピーしておきます。

### Github Actions
```yaml:ai-pr-reviewer.yml
jobs:
  review:
    # 一部省略
    steps:
      - id: fetch_imperative_statement
        name: Fetch imperative statement
        run: |
          command="curl -X GET -sL ${{ secrets.IMPERATIVE_STATEMENT_GAS_URL }}"
          delimiter=$(openssl rand -hex 8)
          {
            echo "IMPERATIVE_STATEMENT<<$delimiter"
            echo -e "$($command | tr -d '\"')"
            echo "$delimiter"
          } >> "$GITHUB_ENV"
        shell: bash
      - id: coderabbitai/ai-pr-reviewer@latest
        # 一部省略
　　　　　　　　　　　　　　　　system_message: |
          ${{ env.IMPERATIVE_STATEMENT }}
                
```
* CurlでGASのAPIを叩き、命令文を取得します。
* 命令文を別のstepで使うため、[複数行用の操作](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#example-of-a-multiline-string)で変数に格納しています。
* GASのURLは念の為 [Secrets](https://docs.github.com/ja/actions/security-guides/using-secrets-in-github-actions) に定義しています。

これで、 **命令文をyamlファイルから剥がす** ことができました 🎉
複数リポジトリに展開した後にカスタマイズする必要が出ても、スプレッドシートを修正すれば全てのリポジトリに自動的に展開することができます

## まとめ
最後までご覧いただきありがとうございました！

[エアークローゼット Advent Calendar 2023](https://qiita.com/advent-calendar/2023/air-closet)はまだまだ続きますので、ぜひ他のエンジニア, デザイナー, PMの記事もご覧いただければと思います

また、エアークローゼットはエンジニア採用活動も行っておりますので、興味のある方はぜひご覧ください！

https://corp.air-closet.com/recruiting/developers/

https://www.wantedly.com/companies/airCloset/projects