dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.22k stars 1.35k forks source link

Can't load loggers from Runtime package store #5105

Open foriequal0 opened 4 years ago

foriequal0 commented 4 years ago

Steps to reproduce

I've somehow installed some msbuild loggers (e.g, https://www.nuget.org/packages/MSBuild.StructuredLogger/) with dotnet store command.

Manifest file

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="XunitXml.TestLogger" Version="2.1.26" />
  </ItemGroup>
</Project>

Command line

dotnet store --manifest RuntimePackages.manifest --framework netcoreapp3.1 --runtime win10-x64
dotnet build -l:BinaryLogger,StructuredLogger

Expected behavior

Can use BinaryLogger in the assembly StructuredLogger, which is installed in ~/.dotnet/store/**/

Actual behavior

.NET Core용 Microsoft (R) Build Engine 버전 16.4.0+e901037fe
Copyright (C) Microsoft Corporation. All rights reserved.

MSBUILD : error MSB1021: 로거의 인스턴스를 만들 수 없습니다. Could not load file or assembly 'GithubActionsDotnetLogger, Culture=neutral, PublicKeyToken=null'. 지정된 파일을 찾을 수 없습니다.
스위치: GithubActionsDotnetLogger

Environment data

msbuild /version output:

OS info:

If applicable, version of the tool that invokes MSBuild (Visual Studio, dotnet CLI, etc):

rainersigwald commented 4 years ago

MSBuild on .NET Core isn't aware of the runtime store, so you must pass a full path to the logger assembly on the command line. Did you see something that suggested that this would work?

foriequal0 commented 4 years ago

I found a similar issue like this: https://github.com/dotnet/runtime/issues/3802 I'm using my custom logger on the Github Actions. It is hosted on the private Github Package Repository, and it is used across projects in the solution. It is only useful on the Github Actions since it transforms MSBuild errors to Github Actions logging commands, therefore it is never used in the runtime, or developer's machine. So It is quiet annoying to add as a dependency on all projects. I might can do some conditional install or install by CLI, but it doesn't work well if I use the lockfile or anticipating deterministic build.

rainersigwald commented 4 years ago

So It is quiet annoying to add as a dependency on all projects. I might can do some conditional install or install by CLI, but it doesn't work well if I use the lockfile or anticipating deterministic build.

Can you please expand on this? I don't understand what you mean by "use the lockfile" or "anticipating deterministic build".

In general, I would expect a logger like this to be configured in your Actions definition: you'd need to

  1. download the logger package
  2. specify the logger assembly (by path) in the dotnet build invocation (or equivalent).

I'd also note that the setup-dotnet action includes an MSBuild-log-format-to-Actions-logging problem matcher that should obviate the need to use a custom logger in Actions.

foriequal0 commented 4 years ago

Thank you. I'm restoring my app with --use-lock-file and --locked-mode, and the options that I've counted have each unique cons.

  1. <PackageReference Include="MyLogger"> I have to install it for every package. I'm using dotnet-outdated to automatic package upgrade. It seems that it isn't compatible with Directory.Build.props or <Import> way. Also, it requires every developer should set private Github Package Repository, and issue and configure Github Personal Access Token on their computer even it is only used in the Github Actions. Just a restoring package requires PAT.
  2. <PackageReference Condition="'$(UseMyLogger)'" Include="MyLogger"> It inherits every cons in 1, and also it messes the lock file with --use-lock-file and breaks build with --locked-mode
  3. dotnet add PROJECT package MyLogger in the CI I have to for PROJ in $(dotnet sln | tail -n+4); do dotnet add "$PROJ" ... to install for every project in the solution, also it temporarily modifies csproj and projects.lock.json file, and I worry that it might break some deterministic property of the build?
  4. last option, dotnet store

I'm already doing it with dotnet store --output some_dir options and some shopt -s globstar; BUILD_LOGGER=$(ls some_dir/**/MyLogger.dll); dotnet build -l"$BUILD_LOGGER", but I think it would be better to have a regular mechanism to resolve runtime packages.

I know there is a problem matcher in the setup-dotnet. However, I found that it is a quite fragile with --verbosity level and sometimes it prints twice due to the summary. I know there is a NoSummary option. TestLogger also suffer from the same problem and there is also multi-line output pattern match problems. That's why I'm packaging Loggers.

rainersigwald commented 4 years ago

I think I'm still missing something. Why are you referencing the logger in projects? The logger is a property of the build, not individual projects.

Are you doing this to make the logger available? Today, that must be done in a separate step and can't be bundled with your main build/restore operation.

foriequal0 commented 4 years ago

Yes I am. I'm doing this to make the logger available. I thought dotnet store would help to separate the step and even to find assemblies.

rainersigwald commented 4 years ago

MSBuild is not aware of dotnet store, so I'm afraid it does not help there.

foriequal0 commented 4 years ago

Okay. Thank you for the help. Have a good day :+1: