【AWS】Amazon CodeGuru に触れてみる -  CodeGuru Reviewer

## はじめに

この記事では AWSのコードレビューサービスであるAWS CodeGuruについて解説した記事です。
記事の途中ではハンズオンがあります。

想定している読者としては`AWSのアカウントを既に持っており、Codeシリーズに興味がある人`を対象にしています。

注意事項

- AWS初学者向けかと問われると若干怪しいところがあります
  - AWSのアソシエイトレベルはクリアできる/クリアできる見込みのある人であれば、概ねできるように書いています
    - 上記に該当する人で難しいと感じてしまったのであれば、ごめんなさい

- 記事の内容につきましてはある程度が時間が経過しても読めるように努力します
  - `できる限り`というベストエフォートな対応になりますのでご了承下さい
  - 最新の情報はAWSの公式ドキュメントを見ていただくようにお願いできればと思います

- 本記事のハンズオンで発生した料金については一切責任を負いません
  - 利用しないサービスについては作成後に必ず削除することをお勧めします。

## Amazon CodeGuru とは

まず最初に Amazon CodeGuru Reviewerの機能を提供しているAmazon CodeGuruについて見ていきましょう。
Amazon CodeGuruについてはAWSのドキュメントに以下のように説明があります。

> ML を活用した推奨事項を使用して、コードレビューを自動化し、アプリケーションのパフォーマンスを最適化

簡単に言うと人間の代わりに機械学習でソースコードを改善しようというサービスです。
Amazon CodeGuru には2つの機能があります。

- CodeGuru Reviewer
  - 機械学習を利用したコードレビューのサービス
- CodeGuru Profiler
  - アプリケーションのパフォーマンスを分析するサービス

各機能について見ていきましょう。

## CodeGuru Reviewerとは

端的に言えば、ML(機械学習)を利用したコードレビューのサービスです。
AWSのドキュメントに以下のように説明があります。

> 機械学習および自動推論を使用して、アプリケーション開発中に重大な問題、セキュリティの脆弱性、見つけにくいバグを特定し、推奨事項を提供することで、コードの品質を向上します。

アプリケーションの問題やアプリケーションの脆弱性、バグを見つける作業をMLによる自動推論で解決するというものです。
分析の対象はAWSに連携されたリポジトリサービスであり、CodeCommitやGitHubのリポジトリを連携することによって利用できます。

ただし、人によるレビューと同じく、レビューを開始するにはプルリクエストを発行する必要があります。

### CodeGuru Reviewerの料金体系

スキャンされた行数に応じて料金が発生します。スキャンにはフルリポジトリスキャンと増分スキャンの2つがあります。
お試しの利用で最初の90日間は無料です。以降はリポジトリサイズ(コードの行数)で決まります。

2023年05月03日現在では10万行で10USD(東京リージョン)であり、以降に追加されたコードに対しては10万行単位で料金が発生します。
また、リポジトリごとに 2 回を超えるフルリポジトリスキャンについては10万行単位で料金が発生します。

## CodeGuru Profilerとは

CodeGuru Reviewerがソースコードのレビュアーをしくれるサービスであることに対してCodeGuru Profilerはアプリケーションのパフォーマンスを分析するサービスです。
AWSのドキュメントに以下のように説明があります。

> CodeGuru Profiler は、実稼働しているアプリケーションのパフォーマンスを最適化、および最もコストが高いコード行を特定します。アプリケーションのパフォーマンスの最適化を常に模索しており、CPU 使用率を削減し、計算コストを低減し、アプリケーションのパフォーマンスを向上させるための修正方法を推奨します。

つまり、人間の目では測定できないマシンスペックに依存するようなところ(CPU使用率など)を分析してアプリケーションパフォーマンスを測定するサービスです。

補足になりますが、アプリケーションのプロファイリングを実行するサービスとして`AWS X-Ray`というサービスがありますが、`AWS X-Ray`はサービス間のレイテンシを測定するなどリクエスト周りの測定を実行するサービスであり、マシンスペックに依存するようなところは分析しません。

### CodeGuru Profilerの料金体系

お試しの利用で最初の90日間は無料です。以降はサンプリング時間数に基づいた料金がかかります。

サンプリングはプロファイリンググループという単位で実行します。また、プロファイリングを実行するAWSサービス毎に料金の計算方法が異なります。

- Amazon EC2 インスタンス、Amazon ECS、EKS、AWS Fargate Containers 上のアプリケーションのプロファイリングの場合

> プロファイリンググループごとに最初の 36,000 サンプリング時間まで、1 サンプリング時間あたり 0.005 USD/月。プロファイリンググループごとに 1 か月あたり 36,000 サンプリング時間を超える分については、追加料金は発生しません。

- AWS Lambda でのアプリケーションプロファイリング

> 支払いアカウントごとに、最初の 500 サンプリング時間は無料です。その後、プロファイリンググループごとに最初の 36,000 サンプリング時間まで、1 サンプリング時間あたり 0.005 USD/月。プロファイリンググループごとに 1 か月あたり 36,000 サンプリング時間を超える分については、追加料金は発生しません。

概ね組織のプロダクション環境で利用する場合は注意が必要ですが、個人で少しだけ触ってみる分には無料枠の範囲で対応できます。

## 実際に CodeGuru Reviewerを使ってみよう

### CodeCommitでリポジトリを作成する

[こちらの記事を参照](https://zenn.dev/ymd65536/articles/code_commit_handson)

### ブランチを切る

CodeGuru Reviewerはプルリクエストを起点に動作する為、ブランチを切ります。
ブランチ名は`test`とします。

```sh
cd ~/Desktop/cicd_handson
git checkout -b test
git push -u origin test
```

### Codeを追加

新しくファイルを作成します。今回は`app.py`というファイルを作成して以下のコードを追記します。

```py
# クソコードを書く

if __name__ == '__main__':
    for cnt in range(1, 9):
        print(f"test{cnt}")

```

### CodeをPush

変更をコミット後、testブランチをpushします。

```sh
git add .
git commit -m "app.pyを追加"
git push -u
```

### 利用開始

AWSマネジメントコンソールからCodeGuruの画面に移動します。

![CodeGuru_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/d5b7f200-b85d-5aee-5060-6efbcac30e61.png)

プルダウンメニューをクリックします。

![CodeGuru_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/4b09da88-2818-0c6e-920a-0b5cdd207c37.png)

プルダウンメニューから`CodeGuru Reviewer`を選択します。

![CodeGuru_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/601ef64b-bb36-1aca-189a-ed7ef78d8793.png)


`ご利用開始にあたって`をクリックします。

![CodeGuru_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/b768425d-4b75-03f1-38fd-bff9ff898330.png)

### リポジトリを関連付ける

`AWS CodeCommit`を選択、リポジトリを`cicd_handson`に指定します。暗号化設定はカスタマイズしません。

![CodeGuru_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/8884e479-8b2d-3186-dbdf-cf269be9f3e6.png)

分析するブランチを指定します。今回は事前に切っておいたtestブランチを指定します。

![CodeGuru_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/cc81d87e-b4a3-3098-4082-ec7480b144b9.png)

最後にKeyとValueを設定して`リポジトリを関連づけて実行`をクリックします。

![CodeGuru_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/764d561b-a956-1d0b-d995-d99acae335f8.png)

時間がかかりますが、しばらくすると指定のブランチの解析が終わり、ステータスが`pending`から`Completed`に変わります。

![CodeGuru_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/75c1a41f-5d94-28ae-95e5-ec05475a5c73.png)

初めてリポジトリの関連付けを実行した場合は`フルリポジトリ分析`が実行されます。

### プルリクエストをイベントソースにしてCodeGuru Reviewerを動かす

`CodeGuru Reviewer`はプルリクエストをイベントソースとして実行することができます。
実際に試してみましょう。まずは新規にブランチを切ります。

```sh
git checkout -b pull_request
```

pushするソースコードを修正します。

```py
# コードを修正する

if __name__ == '__main__':
    for cnt in range(1, 10):
        print(f"test{cnt}")

```

変更をブランチに追加してブランチをリモートに追加します。

```sh
git add .
git commit -m "forを書き換え"
git push -u origin pull_request
```

### CodeCommitでプルリクエストを作成

CodeCommitのリポジトリ画面からプルリクエストを作成します。
まずは対象のリポジトリをクリックします。

![CodeGuru_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/39dc18f2-e59e-897e-ca5b-1af69f7e3798.png)

`プルリクエストの作成`をクリックします。
![CodeGuru_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/25a5fe57-2130-a310-0f23-ec66face94b4.png)

ターゲットとソースをそれぞれ選択します。
![CodeGuru_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/20f91d20-09c6-19fc-c1c4-fcf25aac2c12.png)

ターゲットを`test`、ソースを`pull_request`に変更します。
![CodeGuru_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/88c570b1-23e6-31d3-87de-1b0ca4083cc4.png)

比較をクリックします。Mergeble と表示されたらマージができます。
![CodeGuru_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/9853beb4-b66c-be2f-adb9-add2380441cb.png)

タイトルと説明を入れます。
タイトルは`pull_request`、説明は`CodeGuruのテストです。`と入力します。
![CodeGuru_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/ce9d9a82-01ae-802b-debd-8dfe137f24c8.png)

`プルリクエストの作成`をクリックします。
![CodeGuru_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/6ebd6a2e-f353-f63c-2cdc-71952f9c9925.png)

`成功`と表示されれば、問題なくプルリクエストが作成できています。
![CodeGuru_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/2c4f777f-26f6-71ac-b567-21a52679055b.png)

### CodeGuru の画面に戻る

CodeGuru の画面に戻って増分コードレビューが動いているか確認してみましょう。
プルリクエスト作成直後は`pending`という状態になっています。

![CodeGuru_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/cbdde6f3-6107-8e0c-c0d1-29d8bcf300ef.png)

しばらくすると`Completed`に変わります。

![CodeGuru_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/2f25361d-c0e0-c93a-2b2c-18a0201938d0.png)


## まとめ

- CodeGuruには2つの機能がある
  - CodeGuru Reviewer
  - CodeGuru Profiler
- 今回はCodeGuru Reviewerをハンズオン
  - 初めてのリポジトリ連携ではフルリポジトリ分析が実行される
  - プルリクエストによる分析は増分コードレビューが実行される

## おまけ

いろんな調査をしていく中で`CodeGuru Reviewer`がやってくれないことがいくつか明らかになりました。
また、今回は指摘事項がなかったのでしっかりレビューをしてくれたのか分かりにくいところもあり、「コードレビューさせていたつもりがレビューできていませんでした」というインシデントが起きそうです。間違いだけでなくグッドな部分についても評価してくれたら褒めて伸びるタイプの人は嬉しいかもしれません。
今後のアップデートに期待したいです。

## おわり