dotnet / arcade

Tools that provide common build infrastructure for multiple .NET Foundation projects.
MIT License
656 stars 331 forks source link

Restoring .NET workloads when using .NET Arcade #14893

Closed kevinchalet closed 1 day ago

kevinchalet commented 6 days ago

Hey 👋🏻

Hope everyone here is doing well.

I'm planning on adding iOS support to the OpenIddict client (see https://github.com/openiddict/openiddict-core/pull/2108). Doing that requires installing a bunch of .NET workloads but unfortunately, simply running dotnet workload restore doesn't seem to work as MSBuild later complains the iOS workload isn't installed (I guess it doesn't work because .NET Arcade installs its own SDK/runtime at a different location than the global place used by dotnet workload restore:

NETSDK1147: To build this project, the following workloads must be installed: ios [/Users/runner/work/openiddict-core/openiddict-core/src/OpenIddict/OpenIddict.csproj::TargetFramework=net8.0-ios]

https://github.com/openiddict/openiddict-core/pull/2108/checks#step:7:59

My question is simple: what's the correct way to install/restore .NET workloads when using .NET Arcade?

Thanks!

markwilkie commented 6 days ago

https://github.com/dotnet/arcade/blob/main/Documentation/ArcadeSdk.md#globaljson help?

kevinchalet commented 6 days ago

Honestly no idea, I'm not very familiar with .NET workloads 😅 That section mentions "VS workloads" but it's not clear to me whether it's the same thing as .NET workloads?

Optionally, a list of Visual Studio workload component ids may be specified under vs:

"vs": {
 "version": "15.9",
 "components": ["Microsoft.VisualStudio.Component.VSSDK"]
}
kevinchalet commented 4 days ago

@markwilkie after re-reading that section, it doesn't seem like it's what I'm looking for, as configuring the vs node means the VS, .NET Framework-based flavor of MSBuild is used. .NET workloads on the other hand are supposed to be cross-platform and usable with the .NET tooling. Any other idea? 😃

kevinchalet commented 2 days ago

I tried adding that vs node under tools but it didn't help, I'm still getting the same error...

"tools": {
  // ...

  "vs": {
    "version": "17.10",
    "components": [ "ios" ]
  }
}

I also tried to hook an MSBuild target running before NuGet restore but it didn't help either:

<Target Name="RestoreWorkloads" BeforeTargets="CollectPackageReferences">
    <Exec Command='"$(DotNetTool)" workload restore' WorkingDirectory="$(RepoRoot)" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
    </Exec>
  </Target>

It takes ages and yet I'm still getting the same stupid error 😭

Error: D:\a\openiddict-core\openiddict-core\.dotnet\sdk\8.0.302\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.ImportWorkloads.targets(38,5): error NETSDK1147: To build this project, the following workloads must be installed: ios [D:\a\openiddict-core\openiddict-core\src\OpenIddict.Client.SystemIntegration\OpenIddict.Client.SystemIntegration.csproj::TargetFramework=net8.0-ios]
Error: D:\a\openiddict-core\openiddict-core\.dotnet\sdk\8.0.302\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.ImportWorkloads.targets(38,5): error NETSDK1147: To install these workloads, run the following command: dotnet workload restore [D:\a\openiddict-core\openiddict-core\src\OpenIddict.Client.SystemIntegration\OpenIddict.Client.SystemIntegration.csproj::TargetFramework=net8.0-ios]

Next option is to get rid of .NET Arcade and move to something else, which is really something I'd like to avoid.

What a frustrating experience...

kevinchalet commented 1 day ago

After several unsuccessful attempts, I finally found a workaround that works: I added a custom RestoreWorkloads target in Tools.props that executes immediately after InstallDotNetCore and the .NET workloads are now installed at the right place:

<Project>

  <!-- ... --> 

  <!--
    Restore the .NET workloads immediately after the .NET tooling has been installed by Arcade.
  -->

  <Target Name="RestoreWorkloads" AfterTargets="InstallDotNetCore">
    <Message Text="Installing the .NET workloads required to build the solution..." />

    <Exec Command='"$(DotNetTool)" workload restore' WorkingDirectory="$(RepoRoot)" ConsoleToMSBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
    </Exec>
  </Target>

</Project>