SonarQubeでソースコードの静的解析とレビューを自動化してみる(後編)
はじめに
サーバーレス開発部@大阪の岩田です。 前編に引き続き、SonarQubeを用いたソースコードの静的解析について見ていきます。 今回は前回の設定を発展させて、GitHubのプルリクを検知して、ソースコードの解析とレビューコメントの投稿までを自動化してみます。
こんな感じのコメントを自動で投稿するのが目標です↓
なお、前編はこちらです↓
今回構築する環境
今回は下記のような環境を構築してみます。
大まかな流れは下記の通りです。
- GitHubがプルリクエストを検知し、プルリクエストの情報をSNSに通知
- SNSをトリガーにLambdaが起動、LambdaがCodeBuildのジョブを実行
- CodeBuildのジョブがSonarScannerで変更箇所をスキャン
- スキャン結果をプルリクエストのレビューコメントとして登録
環境構築
前回構築したSonarQubeの環境をベースに早速環境を構築していきます!!
SonarQubeにGitHubプラグインを導入
SonarQubeの Developer Edition以上ではPull Request Analysisという機能が利用できるのですが、今回はCommunity Editionでのお試しなので、GitHubプラグインを利用します。
※現在GitHubプラグインはdeprecated扱いとなっています。
SonarQubeの管理者向けメニューからプラグインをインストールし、SonarQubeを再起動しておきます。
sonar.propertyの準備
スキャン用にSonarScannerの設定ファイルを用意し、スキャン対象プロジェクトの直下に配置しておきます。 今回は下記のようなファイルを用意しました。
sonar.projectKey=<プロジェクトを一意に識別するためのキーを設定> sonar.projectName=<> sonar.projectBaseDir=. sonar.sources=. sonar.exclusions=.build/** sonar.analysis.mode=preview sonar.github.repository=<GitHubのユーザー名/GitHubのリポジトリ名>
GitHubプラグインでプルリクエストをスキャンするためにはsonar.analysis.mode
にpreview
を指定する必要があるため、設定を追加します。
また、CodeBuildのジョブの中でSonnarScannerをDLするため、.buildというディレクトリ配下をスキャン対象外としています。
GitHubのトークンを発行
GitHubプラグインを使用するにはGitHubのトークンが必要になります。 GitHubの設定メニューからpublic_repoの権限を持ったトークンを発行します。 ※発行したトークンは後ほど必要になるので忘れずに控えておいて下さい。
CodeBuildのジョブを作成
ビルドプロジェクトの作成
続いてCodeBuildのジョブを作成していきます。 SonanrScannerがJavaで動くので、JDK8のコンテナをベースに使用します。
最終的な設定値は下記の通りです。
※今回はお試しなので上記のように設定しましたが、実際に利用する場合はSonnarScanner導入済みのコンテナをECR等に登録して利用する方が良いでしょう。
buildspec.ymlの準備
下記のようにbuildspec.ymlを作成し、スキャン対象プロジェクトの直下に保存しておきます。
version: 0.2 env: parameter-store: SONARQUBE_TOKEN: "SONARQUBE_TOKEN" SONARQUBE_ENDPOINT: "SONARQUBE_ENDPOINT" GITHUB_TOKEN: "GITHUB_TOKEN" phases: install: commands: - wget https://sonarsource.bintray.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.2.0.1227-linux.zip - unzip sonar-scanner-cli-3.2.0.1227-linux.zip -d .build - export PATH=$PATH:./.build/sonar-scanner-3.2.0.1227-linux/bin build: commands: - export PULL_REQUEST_ID=`echo ${CODEBUILD_SOURCE_VERSION} | sed -e 's/pr\///'` - sonar-scanner -Dsonar.login=${SONARQUBE_TOKEN} -Dsonar.github.oauth=${GITHUB_TOKEN} -Dsonar.github.pullRequest=${PULL_REQUEST_ID} -Dsonar.host.url=${SONARQUBE_ENDPOINT}
ポイントをかいつまんで説明します。
環境変数の設定
env: parameter-store: SONARQUBE_TOKEN: "SONARQUBE_TOKEN" SONARQUBE_ENDPOINT: "SONARQUBE_ENDPOINT" GITHUB_TOKEN: "GITHUB_TOKEN"
の部分でAWS Systems Manager パラメータストアからGitHubやSonarQubeのトークンを読み出して環境変数にセットしています。 AWS Systems Manager パラメータストアを使用することでソースコード上にトークンを埋め込む必要が無くなります。
プルリクエストIDの取得
- export PULL_REQUEST_ID=`echo ${CODEBUILD_SOURCE_VERSION} | sed -e 's/pr\///'` - sonar-scanner -Dsonar.login=${SONARQUBE_TOKEN} -Dsonar.github.oauth=${GITHUB_TOKEN} -Dsonar.github.pullRequest=${PULL_REQUEST_ID} -Dsonar.host.url=${SONARQUBE_ENDPOINT}
後述する設定でLambdaからジョブが起動された際に、環境変数CODEBUILD_SOURCE_VERSIONの中にpr/1
のような形式でプルリクエストのIDが設定されてくるので、sedでプルリクエストのIDを取り出し、SonnarScannerの引数に渡しています。
AWS Systems Manager パラメータストアの作成
AWS Systems Manager パラメータストアを作成し、
- SonarQubeのトークン
- SonqrQubeのエンドポイント
- GitHubのトークン
を保存します。
CodeBuildの実行ロールにAWS Systems Manager パラメータストアの読み取り権限を付与
先ほど保存した各パラメータをCodeBuildのジョブの中で利用できるように、CodeBuildの実行ロールにSSMパラメータストアの読み取り権限を付与します。
GitHubからSNSに通知するための設定
こちらのブログで紹介されてる手順に従って設定を行います。
SNS - Lambda - CodeBuildを連携させる設定
こちらのブログで紹介されてる手順に従って設定を行います。
プルリクエストを出してみる。
まずSAM CliPython3.6の雛形アプリを作成してGitHubにプッシュしておきます。 次に新規にブランチを作成し、そのブランチ上で雛形アプリに無茶苦茶な変更を加えてみます。
import json import requests def lambda_handler(event, context): """Sample pure Lambda function Arguments: event LambdaEvent -- Lambda Event received from Invoke API context LambdaContext -- Lambda Context runtime methods and attributes Returns: dict -- {'statusCode': int, 'body': dict} """ ip = requests.get('http://checkip.amazonaws.com/') try: if 1 == 1: if 2 == 2: if 3 == 3: if 4 == 4: if 5 == 5: print(1) else: pass else: pass else: pass else: pass else: pass except Exception as e: pass return { "statusCode": 200, "body": json.dumps({ 'message': 'hello world', 'location': ip.text.replace('\n', ''), }) }
変更できたらブランチをプッシュしてプルリクエストを出してみます。 その後しばらく待つと・・・
無事にジョブが実行され、正常終了しました!
GitHubのプルリクエストを確認すると、SonarScannerからコメントが入っています!
まとめ
2回に分けてSonarQubeを利用したソースコードの静的解析について見てきました。 こういった静的解析ツールをうまく活用することで
- レビュー漏れ防止による品質向上
- レビューの省力化による生産性向上
- 非推奨な書き方を学習することによるプログラマーのスキル向上
といった効果が見込めると思います。 開発プロセスの中にうまく組み込んでいきたいですね。
参考
CodeBuild で GitHub の pull request をビルドできるようになりました