Amazon CodeGuru ReviewerをGitHub Actionsから使う

2021.09.24

いわさです。

Amazon CodeGuruのコンポーネントのひとつにAmazon CodeGuru Reviewerというものがあります。
CodeGuru Reviewerを使うと、機会学習と自動推論を使ったコード品質とセキュリティ脆弱性の分析を行うことが可能です。

従来まで、CodeGuru ReviewerはサポートされているコードリポジトリをCodeGuru Reviewerと関連付けることでオンデマンドでのリポジトリ全体の分析か、プルリクエストに連動したコード分析を行うことが出来ていました。

先日、そのCodeGuru Reviewerに新たにCI/CD統合機能が提供されました。(先日といっても2021年6月ごろでしょうか)
本日時点でサポートされているCI/CDはGitHub Actionsです。

GitHub Actionsのワークフローに組み込めると、プルリクエストやプッシュ、スケジュールされた実行などコードレビュープロセスの自動化を行うことが可能です。
本日はGitHub Actionsに組み込んで試してみました。

組み込む

ソースコードを用意

分析出来る言語は現時点ではJavaとPythonです。
本日はAWSがサンプルで用意しているデモ用のJavaコード使わせてもらいましょう。
以下より取得し、GitHubリポジトリへプッシュしておきます。

分析用S3バケットを用意

GitHub Actionsではレビュー対象のソースコードを一度S3バケットにアップロードし、それを使って分析を行います。
よって、まずはS3バケットを作成する必要があります。

一点気をつける点として、S3バケットの名称ですがプレフィックスが決まっており、codeguru-reviewer-で開始する必要があります。

IAMクレデンシャルを用意

IAMのアクセスキーとシークレットが必要です。
今回はIAMユーザーでアクセストークンなどをGitHubシークレットに格納します。

こちらが使えるかは今回試していません。
今度試してみますね。

IAMユーザーには以下の権限を付与します。

  • AmazonCodeGuruReviewerFullAccess
  • codeguru-reviewer-*にアクセス出来る権限

特に後者の権限の付与忘れに注意してください。
管理ポリシーだけじゃ足りてなくて、S3のアクセス権が必要です。私はこれをちゃんとやってなくて3時間溶けました。

アクセスキーとシークレットはリポジトリのGitHubシークレットに格納して使います。

Repository secretsとEnvironment secretsがあるので注意しましょう。
Environmentを使う場合はyamlに環境情報の追記が必要です。

ワークフロー作成

ワークフロー作成します。
他のタスクと混在させたり色々と使い方は考えられそうですが、今回はシンプルにCodeGuru Reviewerタスクだけのものを用意しました。

ワークフローサンプルは以下に記載されています。

name: hogehoge codeguru review

on:
  workflow_dispatch:

jobs:
  review:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2
      with:
        fetch-depth: 0   # Required

    - name: Configure AWS Credentials
      uses: aws-actions/configure-aws-credentials@v1
      if: ${{ always() }} # This ensures that your workflow runs successfully
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ap-northeast-1

    - name: AWS CodeGuru Reviewer Scanner
      uses: aws-actions/codeguru-reviewer@v1.1
      if: ${{ always() }} 
      with:
        build_path: target # build artifact(s) directory
        s3_bucket: codeguru-reviewer-20210923-iwasa  # S3 Bucket with "codeguru-reviewer-*" prefix

    - name: Upload review result
      if: ${{ github.event_name != 'push' }}
      uses: github/codeql-action/upload-sarif@v1
      with:
        sarif_file: codeguru-results.sarif.json

クレデンシャル設定時のリージョンに注意してください。
このリージョンのCodeGuru Reviewerで関連付けが行われます。
また、S3バケットのリージョンとも一致している必要があります。私はこれで1時間溶けました。

実行

今回はオンデマンド実行します。
ワークフローのonでトリガーされれば何でも使えるので柔軟ですね。

実行後、マネジメントコンソールを確認してみましょう。
うまく成功すればワークフローが関連付けされます。

タスクが完了したら、セキュリティタブで推奨事項を確認することが出来るようになります。

ワークフローの関連付けに失敗する

ワークフローの関連付けに失敗して苦労したので、出来るようになった今となっては原因はシンプルではあるのですが...残しておきますね。

権限が足りない

2021-09-23 12:22:38,769 ERROR Exception occurred while executing
botocore.exceptions.WaiterError: Waiter RepositoryAssociationSucceeded failed: Max attempts exceeded. Previously accepted state: For expression "RepositoryAssociation.State" we matched expected path: "Associating"

先程少し触れましたが、IAMユーザーに権限が不足していると、上記のようにワークフローの関連付けに失敗するログが出力されます。
権限を見直してみましょう。

すでに関連付けされてるパターン

2021-09-23 12:47:03,141 ERROR Exception occurred while executing
botocore.errorfactory.ConflictException: An error occurred (ConflictException) when calling the AssociateRepository operation: An association for this repository already exists. If the association has failed, disassociate the repository before attempting to associate the repository again.

このログは権限不足ではなくて、すでに関連付けが存在している場合に発生します。
失敗した関連付けでも重複しているとして扱われるので、失敗した関連付けは解除するようにしましょう。

マネジメントコンソールで、対象を選択し「ワークフローの関連付けを解除する」から解除が可能です。

まとめ

単純なミスで躓きましたが、あまり情報もなくて解決に少し苦労しました。
エラーログを残しておいたのでエラー内容から同じような事象を解決出来る人が一人でも入れば嬉しいなぁなんて思います。

現状JavaとPythonのみですが、レビューの自動化はすごいですよね。近未来的な。
別のアップデートでCodeGuru Reviewerのセキュリティチェックオプションが少し増えています。
そのあたりもまた紹介したいと思います。