こんにちは、テクマトリックスの酒井です。

2023年5月に弊社より高速ソースコード解析ツール「Understand 6.3」日本語版(以下、Understand)がリリースされました。そこで今回は Understand の新機能を利用して、 GitHub のプルリクエストに C/C++ 言語の関数の変更内容が分かる制御フローグラフを表示して、コードレビューを効率的に実施できるようにしてみます。

Understand をどのように使うか?

Understand 6.3 では、 Git リビジョンを指定した比較プロジェクトを作成して、追加・削除・変更された処理の流れの差分を色分け表示することが可能になりました。これを利用して、プルリクエストによって変更される関数ごとに変更内容を色分け表示した制御フローグラフを生成します。グラフはプルリクエストのコメントを通してレビュアーが確認します。プルリクエストのコメントのイメージは次のとおりです。

関数の色分け表示された制御フローグラフ付きのコメント

どのように実装するか?

プルリクエストが作成されたときに GitHub Actions のワークフローを実行します。ワークフローの中で Understand を実行して制御フローグラフを生成します。そして、生成したグラフを参照するコメントをプルリクエストに追加します。

Understand で変更を分析するには、プルリクエストの解析結果を保存したデータベース、および、ベースブランチ(変更が適用されるブランチ)の解析結果を保存したデータベースが必要です。前者はもちろんプルリクエストが作成されたときに作成しますが、後者については、プルリクエストのときにベースブランチを解析するのではなく、ブランチにプッシュされたときにこのデータベースを作成して保存しておき、プルリクエストが作成されたときに取得するようにします。これによりフィードバックの時間を節約します。

ベースブランチの解析結果のデータベース、および、生成したグラフ(画像ファイル)は Amazon S3 に保存することにします。 GitHub のプルリクエストに添付しなかった理由は後述します。

最後に、Understand はオンプレミス環境にあるサーバーで実行することとします。

実装してみる

システム構成

試行錯誤した結果、最終的なシステム構成は次のようになりました。

システム構成図

ワークフロー

GitHub Actions ワークフローはリポジトリ内のファイルで定義します。まずソースコードのサンプルとして cgit のコードをリポジトリに追加します。そして同じリポジトリに、ワークフローの定義ファイルおよびワークフローで実行するスクリプトを追加します。

ワークフローの実行のために追加したファイル(橙色の枠内)

追加した 2 つのワークフロー定義ファイルの内容を以下に記します。

ブランチにプッシュされたときのワークフロー

understand-analyze.yml ファイルでは、main ブランチにプッシュされたとき、 Understand でソースコードを解析してデータベースをアップロードするワークフローを定義します。このファイルの内容は次のとおりです。

name: Code-Analysis-By-Understand
run-name: Understandによるコード解析
on:
  push:
    branches:
      - "main"
env:
  GIT_COMMIT: ${{ github.sha }}
jobs:
  Code-Analysis:
    name: コード解析
    runs-on: [self-hosted, Linux, Understand]
    steps:
      - name: チェックアウト
        uses: actions/checkout@v3
        with:
          fetch-depth: 2
      - name: 解析を実行
        run: ./understand/analyze.sh --upload
      - name: クリーンアップ
        if: ${{ always() }}
        run: ./understand/clean.sh

プルリクエストが作成されたときのワークフロー

understand-review-pr.yml では、 main ブランチへマージするプルリクエストが作成されたとき、変更された関数のグラフを生成し、プルリクエストにコメントを追加するワークフローを定義します。このファイルの内容は次のとおりです。

name: Review-PR-By-Understand
run-name: Understandによるプルリクエストのレビュー
on:
  pull_request:
    branches:
      - "main"
env:
  GIT_COMMIT: ${{ github.event.pull_request.head.sha }}
  GIT_BASE_COMMIT: ${{ github.event.pull_request.base.sha }}
jobs:
  Generate-Changed-Functions-Graphs:
    name: 変更された関数のグラフを生成
    runs-on: [self-hosted, Linux, Understand]
    steps:
      - name: チェックアウト
        uses: actions/checkout@v3
        with:
          ref: ${{ env.GIT_COMMIT }}
      - name: 解析を実行
        run: ./understand/analyze.sh
      - name: 変更された関数のグラフを生成
        run: ./understand/generate-graphs.sh > review-comment.txt
      - name: PRにコメント
        uses: peter-evans/create-or-update-comment@v2
        with:
          issue-number: ${{ github.event.pull_request.number }}
          body-file: review-comment.txt
      - name: クリーンアップ
        if: ${{ always() }}
        run: ./understand/clean.sh

これらのファイルを main ブランチにコミットして GitHub リポジトリにプッシュします。すると understand-analyze.yml で定義したワークフローが実行され、 Understand データベースが生成されます。

プルリクエストしてみる

次に新しいブランチを作成し、 cgit のソースコードを変更します。今回の変更内容は 3 つの関数を変更し、 16 行を追加、 19 行を削除しました。そして変更をコミット・プッシュし、 GitHub の UI でこのブランチを main ブランチへマージするためのプルリクエストを作成します。すると約 1 分後にコメントが追加され、変更した 3 つの関数のグラフが冒頭のイメージのように表示されました。

生成したファイルの保存先とセキュリティ

今回は生成したグラフと Understand データベースファイルを Amazon S3 に保存しました。当初は GitHub のプルリクエストに添付することを検討したのですが、 GitHub のドキュメントに記載の警告を読んで、セキュリティ上ファイルを添付することは避けた方が良いと判断しました。 Amazon S3 に保存したファイルは、会社および GitHub のサーバーの IP アドレスからのみ参照可能とするアクセス許可を設定することにより保護しています。

まとめ

Understand 6.3 の新機能を利用して、 GitHub のプルリクエストに、変更内容が分かる制御フローグラフを自動的に追加することができました。このグラフを見てからコードの変更をレビューすることで、変更内容を早く理解でき、効率的にレビューできるようになると思いますが、いかがでしょうか。コメントの内容や生成するグラフの種類などは変更可能ですので、プロジェクトの要望に合わせて適切なコメントを追加するように変更することにより、さらにプルリクエストのレビューの助けになると思います。

なお今回作成したワークフローを実行するには、 Understand フローティングライセンス with API というエディションが必要です。また、 Understand 6.3 で機能改善された、 Git リビジョンを指定した比較プロジェクトの作成機能を利用しているため、本試行の実施には、 Understand 6.3 をご利用ください。詳細につきましては弊社の Understand 製品ページよりお問い合わせください。

By tsakai

Jenkins関連のサービスやCloudBees製品を主に担当しています。 Certified CloudBees Jenkins Engineer (CCJE) および CloudBees CI DevOps Associate です。