GitHub ActionsでReSharperのコード解析を実行する

こんにちは。

最近、ReSharperコマンドライン版が無料で公開されている事を知り、ちょうどC#で書かれたコードの静的解析をCIで実行したいと考えていた所だったので、GitHub Actionsで動かしてみました。

結論

リポジトリの.githubディレクトリに静的解析結果の書式を指定するjsonファイルを置き、

{
    "problemMatcher": [
        {
            "owner": "resharper_xml_output",
            "pattern": [
                {
                    "regexp": "^\\s+<Issue TypeId=\"[^\"]+\" File=\"([^\"]+)\" Offset=\"(\\d+)-\\d+\" (Line=\"(\\d+)\" )?Message=\"([^\"]+)\"",
                    "file": 1,
                    "column": 2,
                    "line": 4,
                    "message": 5
                }
            ]
        }
    ]
}

以下のジョブを定義するだけで

name: Incpection

on: [push,pull_request]

jobs:
  inspection:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-dotnet@v1
        with:
          dotnet-version: '3.1.x'
      - name: Install ReSharper Command Line Tool
        run: dotnet tool install -g JetBrains.ReSharper.GlobalTools
      - name: Run Inspection
        run: jb inspectcode -o=result.xml -a ソリューション名.sln
      - name: Set Output Format
        run: echo "::add-matcher::.github/上記JSONのファイル名.json"
      - name: Output Inspection Result
        run: cat result.xml
      - name: Exit on failure if issue is exist
        run: if grep -Eq '<Issue [^>]+>' result.xml; then exit 1; fi

静的解析結果がアノテーションとして認識され、PRのFile Changedタブに差し込まれるようになります。

f:id:muno_92:20210130211428p:plain

バージョン情報

  • .NET Core SDK 3.1系
  • JetBrains.ReSharper.CommandLineTools 2020.3.2

ReSharper コマンドラインツール

ReShaperはコマンドライン版が無料で公開されています。

https://www.jetbrains.com/help/resharper/ReSharper_Command_Line_Tools.html

.NETツールとして公開されているため、.NET Core SDKがインストールされている環境さえ用意すれば気軽に利用可能です。

注意点として、現在の最新バージョン(2020.3.2)は.NET5で動作しません。
実行環境には.NET Core SDK3.1系がインストールされている必要があります。
(NuGetのページには依存無と記載されていましたが、nupkgファイルをダウンロード・展開したところruntimeconfig.jsonのtfmにnetcoreapp3.1と指定されていました。)

2021/4/11 追記
バージョン2021.1.0から.NET5でも動作するようになりました。
inspectcode.unix.runtimeconfig.jsonrollForward: "Major"が追記されていたため、ロールフォワードするようになったものと思われます。

ReSharperコマンドラインツールは

  • コードのクリーンアップ (CleanupCode)
  • 重複コードの検出 (dupFinder)
  • コードの検査 (InspectCode)

を機能として備えており、コードの検査は以下のコマンドで実行出来ます。

jb inspectcode [option] ソリューション名.sln

今回使用したオプションも含め、いくつかのオプションについて説明します。

  • --output (-o)
    解析結果はファイルに書き出されるため、出力先の指定が必要です。
  • --format (-f)
    デフォルト: Xml
    出力形式をHtml、Text、Xmlの中から選択出来ます。
    今回はパースし易いXMLで出力させるため、未指定としてデフォルト値をそのまま使っています。
  • --absolute-paths (-a)
    解析結果に記載する各ファイルのパスを絶対パスで出力します。
    デフォルトでは相対パスで出力されますが、MacLinux上で実行していたとしてもファイルパスがバックスラッシュ区切りで出力されてしまいます。
    絶対パスの場合はスラッシュ区切りになるため、このオプションを有効にして回避しています。

また、解析でコードに問題が発見されたとしても、コマンドは正常終了します。

そのため、ジョブを失敗させたい場合は実行結果次第でexit 1するステップを追加しましょう。

Problem Matchers

GitHub Actions で .NETプロジェクトの静的コード解析を行うを読んで知ったのですが、GitHub Actionsはjsonで指定したパターンに一致した出力をアノテーションとして認識してくれます。

アノテーションとして認識されるとPRのFile Changedタブに差し込まれるため、出力メッセージのファイル名・行番号を元に自分の目で問題になったコードを探さなくて済むようになります。
(とても便利)

指定方法の詳細については以下のドキュメントをご参照下さい。

https://github.com/actions/toolkit/blob/master/docs/problem-matchers.md

まとめ

ReSharper コマンドラインツールが.NETツールとして公開されているおかげで、気軽に/どのOSでも高度なコード解析機能を利用出来る事が分かりました。

また、今回初めてGitHub Actionsを使ってみましたが、公式から様々なワークフローが提供されていたり、Problem Matchersを使ってコマンドの実行結果をアノテーションとして認識させられたりと、中々便利だなと感じました。

今後も色々と試していきたいと思います。