Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intermittent NSwag failure on .NET 8.0 #4998

Open
WenningQiu opened this issue Oct 10, 2024 · 13 comments
Open

Intermittent NSwag failure on .NET 8.0 #4998

WenningQiu opened this issue Oct 10, 2024 · 13 comments

Comments

@WenningQiu
Copy link

WenningQiu commented Oct 10, 2024

My application is seeing intermittent build failure after being migrated to .NET 8.0 with NSwag.MSBuild upgraded to 14.1.0. So far we have been seeing the error only when the application is built by Azure DevOps pipeline and not when built locally.

The error seems to be started with a file access error: "The process cannot access the file 'D:\csg-azure-agent_work\1241\s\Bin\Debug\net8.0-windows\BillComposer.BL.deps.json' because it is being used by another process. [D:\csg-azure-agent_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj]".

The file access error has always been on the same file in the failed builds. I am not sure why NSwag needs to access that file in Debug folder when the command file specifies Release build: "dotnet "D:\Cache.nuget\packages\nswag.msbuild\14.1.0\buildTransitive../tools/Net80/dotnet-nswag.dll" run nswag.json /variables:Configuration=Release"


C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): error MSB4018: at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode) [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj] [D:\csg-azure-agent\_work\1241\s\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj]
##[error]C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): Error MSB4018: at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode) [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj]
C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): error MSB4018: at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode) [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj] [D:\csg-azure-agent\_work\1241\s\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj]
##[error]C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): Error MSB4018: at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode) [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj]
C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): error MSB4018: at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode) [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj] [D:\csg-azure-agent\_work\1241\s\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj]
##[error]C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): Error MSB4018: at System.IO.File.Create(String path) [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj]
C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): error MSB4018: at System.IO.File.Create(String path) [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj] [D:\csg-azure-agent\_work\1241\s\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj]
##[error]C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): Error MSB4018: at Microsoft.NET.Build.Tasks.GenerateDepsFile.WriteDepsFile(String depsFilePath) [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj]
C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): error MSB4018: at Microsoft.NET.Build.Tasks.GenerateDepsFile.WriteDepsFile(String depsFilePath) [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj] [D:\csg-azure-agent\_work\1241\s\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj]
##[error]C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): Error MSB4018: at Microsoft.NET.Build.Tasks.TaskBase.Execute() [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj]
C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): error MSB4018: at Microsoft.NET.Build.Tasks.TaskBase.Execute() [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj] [D:\csg-azure-agent\_work\1241\s\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj]
##[error]C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): Error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj]
C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj] [D:\csg-azure-agent\_work\1241\s\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj]
##[error]C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): Error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask) [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj]
C:\Program Files\dotnet\sdk\8.0.304\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask) [D:\csg-azure-agent\_work\1241\s\src\BillComposer.BL\BillComposer.BL.csproj] [D:\csg-azure-agent\_work\1241\s\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj]
  System.InvalidOperationException: Unable to retrieve project metadata. Ensure it's an MSBuild-based .NET Core project.If you're using custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option.
     at NSwag.Commands.Generation.AspNetCore.ProjectMetadata.ReadUsingMsBuildTargets(List`1 args, String file, String buildExtensionsDir, IConsoleHost console) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/ProjectMetadata.cs:line 160
     at NSwag.Commands.Generation.AspNetCore.ProjectMetadata.GetProjectMetadata(String file, String buildExtensionsDir, String framework, String configuration, String runtime, Boolean noBuild, String outputPath, IConsoleHost console) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/ProjectMetadata.cs:line 92
     at NSwag.Commands.Generation.AspNetCore.AspNetCoreToOpenApiCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/AspNetCoreToOpenApiCommand.cs:line 70
     at NSwag.Commands.NSwagDocumentBase.GenerateSwaggerDocumentAsync() in /_/src/NSwag.Commands/NSwagDocumentBase.cs:line 270
     at NSwag.Commands.NSwagDocument.ExecuteAsync() in /_/src/NSwag.Commands/NSwagDocument.cs:line 67
     at NSwag.Commands.Document.ExecuteDocumentCommand.ExecuteDocumentAsync(IConsoleHost host, String filePath) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 76
     at NSwag.Commands.Document.ExecuteDocumentCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 33
     at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input)
     at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input)
     at NSwag.Commands.NSwagCommandProcessor.ProcessAsync(String[] args) in /_/src/NSwag.Commands/NSwagCommandProcessor.cs:line 65
##[error]src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj(46,5): Error MSB3073: The command "dotnet "D:\Cache\.nuget\packages\nswag.msbuild\14.1.0\buildTransitive\../tools/Net80/dotnet-nswag.dll" run nswag.json /variables:Configuration=Release" exited with code -1.
D:\csg-azure-agent\_work\1241\s\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj(46,5): error MSB3073: The command "dotnet "D:\Cache\.nuget\packages\nswag.msbuild\14.1.0\buildTransitive\../tools/Net80/dotnet-nswag.dll" run nswag.json /variables:Configuration=Release" exited with code -1.
Done Building Project "D:\csg-azure-agent\_work\1241\s\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj" (default targets) -- FAILED.
Done Building Project "D:\csg-azure-agent\_work\1241\s\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj.metaproj" (default targets) -- FAILED.
Done Building Project "D:\csg-azure-agent\_work\1241\s\BillComposer.sln" (Clean;Build target(s)) -- FAILED.

Below are the .csproj snippet that is relavant to NSwag:

  <ItemGroup>
    <PackageReference Include="NSwag.MSBuild" Version="14.1.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>
  <Target Name="NSwag" AfterTargets="PostBuildEvent">
    <Exec Command="$(NSwagExe_Net80) run nswag.json /variables:Configuration=$(Configuration)" />
  </Target>

Below is the content of nswag.json file:

{
  "runtime": "Net80",
  "defaultVariables": null,
  "documentGenerator": {
    "aspNetCoreToOpenApi": {
      "project": "../BillComposer.API/BillComposer.API.csproj",
      "msBuildProjectExtensionsPath": null,
      "configuration": null,
      "runtime": null,
      "targetFramework": null,
      "noBuild": false,
      "msBuildOutputPath": null,
      "verbose": true,
      "workingDirectory": null,
      "requireParametersWithoutDefault": false,
      "apiGroupNames": null,
      "defaultPropertyNameHandling": "Default",
      "defaultReferenceTypeNullHandling": "Null",
      "defaultDictionaryValueReferenceTypeNullHandling": "NotNull",
      "defaultResponseReferenceTypeNullHandling": "NotNull",
      "generateOriginalParameterNames": true,
      "defaultEnumHandling": "Integer",
      "flattenInheritanceHierarchy": false,
      "generateKnownTypes": true,
      "generateEnumMappingDescription": false,
      "generateXmlObjects": false,
      "generateAbstractProperties": false,
      "generateAbstractSchemas": true,
      "ignoreObsoleteProperties": false,
      "allowReferencesWithProperties": false,
      "useXmlDocumentation": true,
      "resolveExternalXmlDocumentation": true,
      "excludedTypeNames": [],
      "serviceHost": null,
      "serviceBasePath": null,
      "serviceSchemes": [],
      "infoTitle": "My Title",
      "infoDescription": null,
      "infoVersion": "1.0.0",
      "documentTemplate": null,
      "documentProcessorTypes": [],
      "operationProcessorTypes": [],
      "typeNameGeneratorType": null,
      "schemaNameGeneratorType": null,
      "contractResolverType": null,
      "serializerSettingsType": null,
      "useDocumentProvider": true,
      "documentName": "v1",
      "aspNetCoreEnvironment": null,
      "createWebHostBuilderMethod": null,
      "startupType": null,
      "allowNullableBodyParameters": true,
      "useHttpAttributeNameAsOperationId": false,
      "output": null,
      "outputType": "Swagger2",
      "newLineBehavior": "Auto",
      "assemblyPaths": [],
      "assemblyConfig": null,
      "referencePaths": [],
      "useNuGetCache": false
    }
  },
  "codeGenerators": {
    "openApiToTypeScriptClient": {
      "className": "{controller}Client",
      "moduleName": "",
      "namespace": "",
      "typeScriptVersion": 4.3,
      "template": "Fetch",
      "promiseType": "Promise",
      "httpClass": "HttpClient",
      "withCredentials": false,
      "useSingletonProvider": false,
      "injectionTokenType": "OpaqueToken",
      "rxJsVersion": 6.0,
      "dateTimeType": "Date",
      "nullValue": "Undefined",
      "generateClientClasses": true,
      "generateClientInterfaces": false,
      "generateOptionalParameters": false,
      "exportTypes": true,
      "wrapDtoExceptions": false,
      "exceptionClass": "ApiException",
      "clientBaseClass": null,
      "wrapResponses": false,
      "wrapResponseMethods": [],
      "generateResponseClasses": true,
      "responseClass": "SwaggerResponse",
      "protectedMethods": [],
      "configurationClass": null,
      "useTransformOptionsMethod": false,
      "useTransformResultMethod": false,
      "generateDtoTypes": true,
      "operationGenerationMode": "MultipleClientsFromOperationId",
      "markOptionalProperties": true,
      "generateCloneMethod": false,
      "typeStyle": "Class",
      "enumStyle": "Enum",
      "useLeafType": false,
      "classTypes": [],
      "extendedClasses": [],
      "extensionCode": null,
      "generateDefaultValues": true,
      "excludedTypeNames": [],
      "excludedParameterNames": [],
      "handleReferences": false,
      "generateConstructorInterface": true,
      "convertConstructorInterfaceData": false,
      "importRequiredTypes": true,
      "useGetBaseUrlMethod": false,
      "baseUrlTokenName": "API_BASE_URL",
      "queryNullValue": "",
      "useAbortSignal": false,
      "inlineNamedDictionaries": false,
      "inlineNamedAny": false,
      "includeHttpContext": false,
      "templateDirectory": null,
      "typeNameGeneratorType": null,
      "propertyNameGeneratorType": null,
      "enumNameGeneratorType": null,
      "serviceHost": null,
      "serviceSchemes": null,
      "output": "../BillComposer.UI/src/api/client.ts",
      "newLineBehavior": "Auto"
    }
  }
}
@WenningQiu
Copy link
Author

WenningQiu commented Oct 11, 2024

Update - I see the error on my local machine too, although much less frequently than on Azure DevOps pipeline.

  1. Why does NSwag drives Debug build even with "Configuration=Release"?
  2. Does NSwag kicks off parallel build tasks that may result in file contention?
NSwag:
  dotnet "C:\Users\qiuw01\.nuget\packages\nswag.msbuild\14.1.0\buildTransitive\../tools/Net80/dotnet-nswag.dll" run nswag.json /variables:Configuration=Release
  NSwag command line tool for .NET Core Net80, toolchain v14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))
  Visit http://NSwag.org for more information.
  NSwag bin directory: C:\Users\qiuw01\.nuget\packages\nswag.msbuild\14.1.0\tools\Net80

  Executing file 'nswag.json' with variables 'Configuration=Release'...
CSC : error CS2012: Cannot open 'C:\work\git\os_system\BillComposer\src\BillComposer.API\obj\Debug\net8.0-windows\BillComposer.API.dll' for writing -- 'The process cannot access the file 'C:\work\git\os_system\
BillComposer\src\BillComposer.API\obj\Debug\net8.0-windows\BillComposer.API.dll' because it is being used by another process.' [C:\work\git\os_system\BillComposer\src\BillComposer.API\BillComposer.API.csproj] [
C:\work\git\os_system\BillComposer\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj]
  System.InvalidOperationException: Unable to retrieve project metadata. Ensure it's an MSBuild-based .NET Core project.If you're using custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values,
  Use the --msbuildprojectextensionspath option.
     at NSwag.Commands.Generation.AspNetCore.ProjectMetadata.ReadUsingMsBuildTargets(List`1 args, String file, String buildExtensionsDir, IConsoleHost console) in /_/src/NSwag.Commands/Commands/Generation/AspNe
  tCore/ProjectMetadata.cs:line 160
     at NSwag.Commands.Generation.AspNetCore.ProjectMetadata.GetProjectMetadata(String file, String buildExtensionsDir, String framework, String configuration, String runtime, Boolean noBuild, String outputPath
  , IConsoleHost console) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/ProjectMetadata.cs:line 92
     at NSwag.Commands.Generation.AspNetCore.AspNetCoreToOpenApiCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/AspNetCoreToOpenApiCom
  mand.cs:line 70
     at NSwag.Commands.NSwagDocumentBase.GenerateSwaggerDocumentAsync() in /_/src/NSwag.Commands/NSwagDocumentBase.cs:line 270
     at NSwag.Commands.NSwagDocument.ExecuteAsync() in /_/src/NSwag.Commands/NSwagDocument.cs:line 67
     at NSwag.Commands.Document.ExecuteDocumentCommand.ExecuteDocumentAsync(IConsoleHost host, String filePath) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 76
     at NSwag.Commands.Document.ExecuteDocumentCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 33
     at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input)
     at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input)
     at NSwag.Commands.NSwagCommandProcessor.ProcessAsync(String[] args) in /_/src/NSwag.Commands/NSwagCommandProcessor.cs:line 65
C:\work\git\os_system\BillComposer\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj(69,5): error MSB3073: The command "dotnet "C:\Users\qiuw01\.nuget\packages\nswag.msbuild\14.1.0\buildTransitive\../too
ls/Net80/dotnet-nswag.dll" run nswag.json /variables:Configuration=Release" exited with code -1.

@vvdb-architecture
Copy link

The error happens intermittently. That is usually because of parallelism.
It's a file in a project called BillComposer.BL.csproj, and your NSwag invocation is from BillComposer.API.NSwag.csproj. If no direct or indirect dependencies exist between these two projects, the builds may occur in parallel, triggering the problem.

If you can't add the former as a dependency on the latter, perhaps you can try to set the build order explicitly in Visual Studio... just a thought.

@SerenaPrososki
Copy link

I added the following project dependency as suggested. I am still getting the error above that Wenning mentions.

EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BillComposer.API.NSwag", "src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj", "{30B86CD0-25C4-4F7E-8B1F-4BAD9498DF1D}"
ProjectSection(ProjectDependencies) = postProject
{9DB34C69-3CB7-4FB0-B2BA-DB3F65217051} = {9DB34C69-3CB7-4FB0-B2BA-DB3F65217051}
{ACE9289D-70F8-4615-B947-D0D6ED0857ED} = {ACE9289D-70F8-4615-B947-D0D6ED0857ED}
EndProjectSection
EndProject

@MichaelSpencerJr
Copy link

(I'm a coworker of Serena and Wenning) We're trying some other changes on our end, and will come back to this ticket if we are still stuck after. Thanks again, NSwag team.

@vvdb-architecture
Copy link

I don't use .sln mods, but the .csproj way

<ProjectReference Include="...\BillComposer.BL.csproj">
  <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>

@WenningQiu
Copy link
Author

WenningQiu commented Oct 29, 2024

@vvdb-architecture Thanks for the suggestion, but we are still getting the same error with the change.

The issue probably is not related to the possible parallel building of projects based on the evidences we have at hand:

  1. We did not specify "-maxCpuCount" on MsBuild command line, so there should only be one build process.
  2. The file contention is on a JSON file in the Debug folder; however, we only performed Release build (/p:configuration=Release), so the building of other projects should only be touching files in the Release folder.

The Debug folders apparently are created and accessed by NSwag build, so it comes down to the two questions that I raised 3 weeks ago that have not been answered:

image

@WenningQiu
Copy link
Author

The file contention issue appears to have been introduced in NSwag.MSBuild version 14.0.0 with which I saw the file contention error even for net6.0-windows build. There is no issue with version 13.20.0.

@vvdb-architecture
Copy link

Too bad. Other suggestions: could it be because of a recursive build? Do you have "nobuild": true in your nswag file? I forgot it once and I saw either a lot of recursive calls or some file locks, but I forgot which file since it's some time ago.

In general, updating from 13.x to 14.x requires some work. There's a thread at the top of the issues list that contains more information, alas in a more scattered way.

@WenningQiu
Copy link
Author

nobuild is set to false. Below is our nswag.json file.

{
  "runtime": "Net60",
  "defaultVariables": null,
  "documentGenerator": {
    "aspNetCoreToOpenApi": {
      "project": "../BillComposer.API/BillComposer.API.csproj",
      "msBuildProjectExtensionsPath": null,
      "configuration": null,
      "runtime": null,
      "targetFramework": null,
      "noBuild": false,
      "msBuildOutputPath": null,
      "verbose": true,
      "workingDirectory": null,
      "requireParametersWithoutDefault": false,
      "apiGroupNames": null,
      "defaultPropertyNameHandling": "Default",
      "defaultReferenceTypeNullHandling": "Null",
      "defaultDictionaryValueReferenceTypeNullHandling": "NotNull",
      "defaultResponseReferenceTypeNullHandling": "NotNull",
      "generateOriginalParameterNames": true,
      "defaultEnumHandling": "Integer",
      "flattenInheritanceHierarchy": false,
      "generateKnownTypes": true,
      "generateEnumMappingDescription": false,
      "generateXmlObjects": false,
      "generateAbstractProperties": false,
      "generateAbstractSchemas": true,
      "ignoreObsoleteProperties": false,
      "allowReferencesWithProperties": false,
      "useXmlDocumentation": true,
      "resolveExternalXmlDocumentation": true,
      "excludedTypeNames": [],
      "serviceHost": null,
      "serviceBasePath": null,
      "serviceSchemes": [],
      "infoTitle": "My Title",
      "infoDescription": null,
      "infoVersion": "1.0.0",
      "documentTemplate": null,
      "documentProcessorTypes": [],
      "operationProcessorTypes": [],
      "typeNameGeneratorType": null,
      "schemaNameGeneratorType": null,
      "contractResolverType": null,
      "serializerSettingsType": null,
      "useDocumentProvider": true,
      "documentName": "v1",
      "aspNetCoreEnvironment": null,
      "createWebHostBuilderMethod": null,
      "startupType": null,
      "allowNullableBodyParameters": true,
      "useHttpAttributeNameAsOperationId": false,
      "output": null,
      "outputType": "Swagger2",
      "newLineBehavior": "Auto",
      "assemblyPaths": [],
      "assemblyConfig": null,
      "referencePaths": [],
      "useNuGetCache": false
    }
  },
  "codeGenerators": {
    "openApiToTypeScriptClient": {
      "className": "{controller}Client",
      "moduleName": "",
      "namespace": "",
      "typeScriptVersion": 4.3,
      "template": "Fetch",
      "promiseType": "Promise",
      "httpClass": "HttpClient",
      "withCredentials": false,
      "useSingletonProvider": false,
      "injectionTokenType": "OpaqueToken",
      "rxJsVersion": 6.0,
      "dateTimeType": "Date",
      "nullValue": "Undefined",
      "generateClientClasses": true,
      "generateClientInterfaces": false,
      "generateOptionalParameters": false,
      "exportTypes": true,
      "wrapDtoExceptions": false,
      "exceptionClass": "ApiException",
      "clientBaseClass": null,
      "wrapResponses": false,
      "wrapResponseMethods": [],
      "generateResponseClasses": true,
      "responseClass": "SwaggerResponse",
      "protectedMethods": [],
      "configurationClass": null,
      "useTransformOptionsMethod": false,
      "useTransformResultMethod": false,
      "generateDtoTypes": true,
      "operationGenerationMode": "MultipleClientsFromOperationId",
      "markOptionalProperties": true,
      "generateCloneMethod": false,
      "typeStyle": "Class",
      "enumStyle": "Enum",
      "useLeafType": false,
      "classTypes": [],
      "extendedClasses": [],
      "extensionCode": null,
      "generateDefaultValues": true,
      "excludedTypeNames": [],
      "excludedParameterNames": [],
      "handleReferences": false,
      "generateConstructorInterface": true,
      "convertConstructorInterfaceData": false,
      "importRequiredTypes": true,
      "useGetBaseUrlMethod": false,
      "baseUrlTokenName": "API_BASE_URL",
      "queryNullValue": "",
      "useAbortSignal": false,
      "inlineNamedDictionaries": false,
      "inlineNamedAny": false,
      "includeHttpContext": false,
      "templateDirectory": null,
      "typeNameGeneratorType": null,
      "propertyNameGeneratorType": null,
      "enumNameGeneratorType": null,
      "serviceHost": null,
      "serviceSchemes": null,
      "output": "../BillComposer.UI/src/api/client.ts",
      "newLineBehavior": "Auto"
    }
  }
}

@WenningQiu
Copy link
Author

WenningQiu commented Oct 30, 2024

I dug into NSwag source code and likely have found the answers to my questions:

  1. The reason why NSwag insists on performing Debug build is because Condifuration command line argument is not set to ProjectMetadata.Configuration property by AspNetCoreToOpenApiCommand class.
    image

  2. The possible source of file contention might come from the TryReadingUsingGetProperties() method that appears to be added to version 14.*. I repost the call stack below which shows that both TryReadingUsingGetProperties() and ReadUsingMsBuildTargets() must have been invoked when file contention happens.
    image

NSwag:
  dotnet "C:\Users\qiuw01\.nuget\packages\nswag.msbuild\14.1.0\buildTransitive\../tools/Net80/dotnet-nswag.dll" run nswag.json /variables:Configuration=Release
  NSwag command line tool for .NET Core Net80, toolchain v14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))
  Visit http://NSwag.org for more information.
  NSwag bin directory: C:\Users\qiuw01\.nuget\packages\nswag.msbuild\14.1.0\tools\Net80

  Executing file 'nswag.json' with variables 'Configuration=Release'...
CSC : error CS2012: Cannot open 'C:\work\git\os_system\BillComposer\src\BillComposer.API\obj\Debug\net8.0-windows\BillComposer.API.dll' for writing -- 'The process cannot access the file 'C:\work\git\os_system\
BillComposer\src\BillComposer.API\obj\Debug\net8.0-windows\BillComposer.API.dll' because it is being used by another process.' [C:\work\git\os_system\BillComposer\src\BillComposer.API\BillComposer.API.csproj] [
C:\work\git\os_system\BillComposer\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj]
  System.InvalidOperationException: Unable to retrieve project metadata. Ensure it's an MSBuild-based .NET Core project.If you're using custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values,
  Use the --msbuildprojectextensionspath option.
     at NSwag.Commands.Generation.AspNetCore.ProjectMetadata.ReadUsingMsBuildTargets(List`1 args, String file, String buildExtensionsDir, IConsoleHost console) in /_/src/NSwag.Commands/Commands/Generation/AspNe
  tCore/ProjectMetadata.cs:line 160
     at NSwag.Commands.Generation.AspNetCore.ProjectMetadata.GetProjectMetadata(String file, String buildExtensionsDir, String framework, String configuration, String runtime, Boolean noBuild, String outputPath
  , IConsoleHost console) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/ProjectMetadata.cs:line 92
     at NSwag.Commands.Generation.AspNetCore.AspNetCoreToOpenApiCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/AspNetCoreToOpenApiCom
  mand.cs:line 70
     at NSwag.Commands.NSwagDocumentBase.GenerateSwaggerDocumentAsync() in /_/src/NSwag.Commands/NSwagDocumentBase.cs:line 270
     at NSwag.Commands.NSwagDocument.ExecuteAsync() in /_/src/NSwag.Commands/NSwagDocument.cs:line 67
     at NSwag.Commands.Document.ExecuteDocumentCommand.ExecuteDocumentAsync(IConsoleHost host, String filePath) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 76
     at NSwag.Commands.Document.ExecuteDocumentCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 33
     at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input)
     at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input)
     at NSwag.Commands.NSwagCommandProcessor.ProcessAsync(String[] args) in /_/src/NSwag.Commands/NSwagCommandProcessor.cs:line 65
C:\work\git\os_system\BillComposer\src\BillComposer.API.NSwag\BillComposer.API.NSwag.csproj(69,5): error MSB3073: The command "dotnet "C:\Users\qiuw01\.nuget\packages\nswag.msbuild\14.1.0\buildTransitive\../too
ls/Net80/dotnet-nswag.dll" run nswag.json /variables:Configuration=Release" exited with code -1.

@vvdb-architecture
Copy link

But if "nobuild": false then you are effectively instructing NSwag to build your project while it is building your project..... Set it to true and read the v14 migration thread on top of the issues list to find out how v14 works. We use v14 in dozens of projects without seeing problems you have (but it took some effort to move to v14)

@WenningQiu
Copy link
Author

Oh, I see; I misread your previous message.

I believe setting "nobuild": true, which disables NSwag building projects, would prevent the file contention from happening.

@WenningQiu
Copy link
Author

WenningQiu commented Nov 1, 2024

To report back to the community, below is what we have done to get it working with version 14.*:

  1. Turn off building in nswag.json file to get around file contention issue
    "noBuild": true,
  2. Change the value in nswag.json to pick up command line variables
    "configuration": "$(Configuration)",

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants