🎬

.NETのGitHub Actionsワークフローでエラーが2回表示される問題の解決

2022/09/06に公開

先に結論

dotnet build -clp:NoSummary

問題

以下の内容の続きです。GitHub Actionsで dotnet build するだけで、コード中へのエラー指摘までしてくれる、という内容でした。
https://zenn.dev/shimat/articles/c0bfb6e8dfb0fb

.github/workflows/dotnet.yml
    - name: Setup .NET
      uses: actions/setup-dotnet@v2
      with:
        dotnet-version: 6.0.x

    - name: Build
      run: |
        dotnet build -warnaserror

公式ドキュメントにも同様に方法が紹介されています。https://docs.github.com/ja/actions/automating-builds-and-tests/building-and-testing-net

ただし実は不備がありまして、素朴に dotnet build するだけだと、コード差分中へのエラー表示が2回出てしまいます。

原因

dotnet build からの出力の中に、同じエラーメッセージが2回含まれているからです。

一例です: https://github.com/shimat/dotnet_actions_test/runs/8195952494?check_suite_focus=true

MSBuild version 17.3.0+92e077650 for .NET
CSC : error CA1014: Mark assemblies with CLSCompliant [/home/runner/work/dotnet_actions_test/dotnet_actions_test/ConsoleApp1/ConsoleApp1.csproj]
Error: /home/runner/work/dotnet_actions_test/dotnet_actions_test/ConsoleApp1/Program.cs(2,19): error CA1303: Method '<top-level-statements-entry-point>' passes a literal string as parameter 'value' of a call to 'void Console.WriteLine(string? value)'. Retrieve the following string(s) from a resource table instead: "Hello, World!". [/home/runner/work/dotnet_actions_test/dotnet_actions_test/ConsoleApp1/ConsoleApp1.csproj]
  ConsoleApp1 -> /home/runner/work/dotnet_actions_test/dotnet_actions_test/ConsoleApp1/bin/Debug/net6.0/ConsoleApp1.dll

Build FAILED.

CSC : error CA1014: Mark assemblies with CLSCompliant [/home/runner/work/dotnet_actions_test/dotnet_actions_test/ConsoleApp1/ConsoleApp1.csproj]
Error: /home/runner/work/dotnet_actions_test/dotnet_actions_test/ConsoleApp1/Program.cs(2,19): error CA1303: Method '<top-level-statements-entry-point>' passes a literal string as parameter 'value' of a call to 'void Console.WriteLine(string? value)'. Retrieve the following string(s) from a resource table instead: "Hello, World!". [/home/runner/work/dotnet_actions_test/dotnet_actions_test/ConsoleApp1/ConsoleApp1.csproj]
    0 Warning(s)
    2 Error(s)

Time Elapsed 00:00:02.63
Error: Process completed with exit code 1.

当然ではありますが、手元でも再現できます。dotnetコマンド (MSBuild) の仕様に起因するということです。下にエラー・警告をサマリとしてまとめて出してくれる仕様で、このため上に最初に出たエラーメッセージと重複します。

エラーメッセージとコード中の指摘がどう結びついているかは、以下の記事等をご参照ください。actions/setup-dotnetがProblem Matchersを仕込んでくれているためです。[1]
https://buildersbox.corp-sansan.com/entry/2021/02/18/110000

解決

dotnet build の引数に -clp:NoSummary を追加します。

.github/workflows/dotnet.yml
    - name: Build
      run: |
        dotnet build -warnaserror -clp:NoSummary

これはMSBuildへのパラメータを意味します。以下を参照してください。MSBuildでのビルドメッセージでは最後に警告・エラーをまとめて表示してくれるのを、NoSummaryにより抑止します。
https://docs.microsoft.com/ja-jp/visualstudio/msbuild/msbuild-command-line-reference?view=vs-2022

-consoleLoggerParameters:parameters -clp:parameters
指定したパラメーターをコンソール logger に渡し、コンソール ウィンドウにビルド情報を表示します。 次のパラメーターを指定できます。
(中略)
NoSummary。 エラーや警告の概要を終了時に表示しません。

ここにあるように、-consoleLoggerParameters:NoSummaryのように長い名前を使っても構いません。またMSBuildの仕様上 -/に変えても良いですし、大文字小文字の区別もありません。

# どれでもOK
dotnet build -clp:NoSummary
dotnet build -consoleLoggerParameters:NoSummary
dotnet build /clp:NoSummary
dotnet build /CLP:NoSummary

これで期待通り指摘が1回になったのが確認できました。

ワークフロー定義まとめ

以上は2022年9月時点のubuntu-latestで実験しました。

.github/workflows/dotnet.yml
name: .NET

on:
  pull_request:
    types: [synchronize, opened]

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 5

    steps:
    - uses: actions/checkout@v3
      
    - name: Setup .NET
      uses: actions/setup-dotnet@v2
      with:
        dotnet-version: 6.0.x

    - name: Build
      run: |
        dotnet build -warnaserror -clp:NoSummary
脚注
  1. 実際にsetup-dotnetが仕込んでくれているProblem Matchers定義はこちら: https://github.com/actions/setup-dotnet/blob/77a48bbb85cd3809790223e895ba4b6cbc110fe8/.github/csc.json ↩︎

Discussion