🛠️

SonarQube の Pull Request 解析コメントでプロジェクト名を表示する

2022/04/15に公開

SREホールディングス株式会社のエンジニアの小澤です。
主にサーバーサイド・インフラ方面を担当していて、今は特にCI/CD整備や各種自動化に取り組んでいます。
今回は弊社で静的コード解析に利用している SonarCloud (SonarQubeのSaaS版) の Pull Request 解析が付ける GitHub のコメントで、スキャン対象のプロジェクト名を表示させるという小ネタを紹介します。

対象読者

  • プロジェクトで SonarQube/SonarCloud を利用
  • GitHub上で1つのレポジトリで複数プロジェクトを管理 (モノレポ構成)
  • CI/CD プラットフォームに GitHub Action を利用

経緯と課題

弊社のプロジェクトでは静的コード解析にSonarCloudを利用しています。GitHubにPull Requestを作成すると自動的に解析が走り、以下のようなコメントが付きます。

これにより新規に追加されたコードについて

  • バグっぽいコード
  • 脆弱性に繋がりそうなコード
  • 臭いコード(可読性や保守性を低下させるコード)
  • テストカバレッジ

といった指摘を行ってくれるので、コード品質の向上やレビュー時間の削減などに大いに役立っています。
しかし、1つのレポジトリで複数のプロジェクトをビルドする場合、Pull Request 解析が複数回走ることで上記のコメントが複数付くことがあります。この時各コメントがどのプロジェクトのことを指しているのか一目で区別できないため不便です。
SonarSourceのコミュニティで同様の悩みを持っている人はいないか調べたところ、一応見つかりました。
https://community.sonarsource.com/t/show-project-name-in-pull-request-decoration/40212
PRコメントに対してプロジェクト名を追加してほしいという要望です。しかしながら記事作成時点でコメントは0かつVote数も1で注目度は低く、公式による機能追加は望むべくも無さそうです。

提案手法

そこで、 GitHub Actions で最近追加された github-script を利用し、直接コメントを編集してプロジェクト名を追加してみます。github-script は Javascript を用いて簡単に GitHub API を呼び出すことができます。

  1. SonarCloud Bot が付けたPRコメントのリストを取得
  2. コメント本文からプロジェクト名を抽出
  3. コメント本文先頭に Project: ${プロジェクト名} を付けて更新

というようにやればできそうです。実際に書いたStepが下記になります。

- name: Modify SonarCloud PR comment
  uses: actions/github-script@v6
  with:
    script: |
      // コメントのリストを取得
      const all_comments = await github.rest.issues.listComments({
        owner: context.repo.owner,
        repo: context.repo.repo,
        issue_number: context.issue.number,
        per_page: 100    // コメントは100件以下を仮定
      })
      // SonarCloud Bot のコメントを抽出
      const sonar_comments = all_comments.data.filter(c => c.user.login === "sonarcloud[bot]")
      console.log(sonar_comments)
      for (const c of sonar_comments) {
        // 既に追加済みならスキップ
        if (c.body.startsWith("Project")) {
          console.log(`skip ${c.id}`)
          continue
        }
	// コメント本文のリンクからプロジェクト名を取得する
        const matched = c.body.match(/id=(.*)&/)
        const project = matched[1]
        // コメント本文を編集
	const body_updated = `Project: **${project}**\n\n` + c.body
        console.log(`update body for project ${project}`)
        // コメントを更新
	github.rest.issues.updateComment({
          owner: context.repo.owner,
          repo: context.repo.repo,
          comment_id: c.id,
          body: body_updated
        })
      }

このStepをPR解析の後に実行させると、以下のようにプロジェクト名がコメントの先頭に表示されるようになりました。

感想

以上です。github-script かなり便利ですね。

SRE Holdings 株式会社

Discussion