RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.78k stars 1.29k forks source link

NSwag.MSBuild executable not available at build time #3202

Closed GabrielSandor closed 3 years ago

GabrielSandor commented 3 years ago

I am generating Swagger clients using NSwag.MSBuild as a pre-build step in a C# project in the following manner:

<Target Name="NSwag" BeforeTargets="PrepareForBuild">
  <Exec Command="$(NSwagExe) run $(ProjectDir)\nswag.json" />
</Target>

The csproj is in the new SDK format (<Project Sdk="Microsoft.NET.Sdk">) and it targets net452.

The problem is that, in a newly checked out solution where the NSwag.MSBuild NuGet package does not exist yet on the local machine, the build fails because it can't find the executable. I work around this by commenting the pre-build step above in the csproj file, build the solution, then re-instate the build step. This is unwanted manual work so i tried to avoid it by adding a dotnet restore step right before calling the exe, like this:

<Exec Command="dotnet restore" Condition="!Exists('$(NSwagExe)')" />

This does the trick and the build doesn't fail anymore, however i noticed that "!Exists('$(NSwagExe)')" always returns true, which means that dotnet restore will be unnecessarily executed even when the NuGet package with the executable is already downloaded. Is there a way to avoid this? Alternatively, is there a better workaround to avoid the pre-build failure altogether?

jeremyVignelles commented 3 years ago

Did you try BeforeTargets="BeforeBuild" instead of PrepareForBuild?

Otherwise, I'd call dotnet restore in your CI steps, before calling dotnet build.

GabrielSandor commented 3 years ago

@jeremyVignelles I just did, and it seems to work even without the explicit dotnet restore instruction. Thanks! I'll do some more testing to make sure the initial problem no longer appears.

As for the CI build, that's not a problem because it has an explicit dotnet restore step before the build, the problem only arose when building from Visual Studio.

jeremyVignelles commented 3 years ago

If I remember correctly, dotnet build performs a dotnet restore, but BeforeTargets="PrepareForBuild" executes before the restore could happen, while BeforeBuild is before the actual compilation (and after the restore).