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

[BUG] nx run my-web-api:serve:development in .net8 project produces invalid executing command #865

Closed
Den-dp opened this issue Jul 19, 2024 · 3 comments · Fixed by #873
Closed
Labels
bug Something isn't working needs-triage This issue has yet to be looked over by a core team member outdated

Comments

@Den-dp
Copy link
Contributor

Den-dp commented Jul 19, 2024

Current Behavior

While moving from net7 to net8, running nx serve with custom configuration started to produce an invalid executing command.
Now it passes configuration to the app as an argument:

#net8
dotnet watch ⌚ Running NxDotnetExample.MyWebApi with the following arguments: '--configuration Debug'
#net7
dotnet watch ⌚ Running dotnet with the following arguments: run --configuration Debug

Expected Behavior

Configuration should be passed to the run (?) subcommand (not to the dll we serve).

Github Repo

No response

Steps to Reproduce

npx create-nx-workspace@19 nx-dotnet-example
cd nx-dotnet-example
npm install --save-dev @nx-dotnet/core
npx nx g @nx-dotnet/core:init
nx g @nx-dotnet/core:application --name=my-web-api --language=C# --template=webapi --testTemplate=nunit --pathScheme=nx
nx run my-web-api:serve:development

Nx Report

Node   : 20.12.2
OS     : win32-x64
npm    : 10.8.1

nx (global)    : 19.3.2
nx             : 19.5.1
@nx/js         : 19.5.1
@nx/workspace  : 19.5.1
@nx/devkit     : 19.5.1
@nrwl/tao      : 19.5.1
typescript     : 5.5.3
---------------------------------------
Registered Plugins:
@nx-dotnet/core
---------------------------------------
Community plugins:
@nx-dotnet/core : 2.2.0

nx.json

{
  "$schema": "./node_modules/nx/schemas/nx-schema.json",
  "namedInputs": {
    "default": [
      "{projectRoot}/**/*",
      "sharedGlobals"
    ],
    "production": [
      "default"
    ],
    "sharedGlobals": []
  },
  "plugins": [
    "@nx-dotnet/core"
  ]
}

Failure Logs

> $env:DOTNET_CLI_CONTEXT_VERBOSE='true'; nx run my-web-api:serve:development

> nx run my-web-api:serve

Executing Command: dotnet "watch" "--project" "C:\tmp\nx-dotnet-example\my-web-api\NxDotnetExample.MyWebApi.csproj" "run" "--configuration" "Debug"
Telemetry is: Enabled
Running C:\Program Files\dotnet\dotnet.exe "C:\Program Files\dotnet\sdk\8.0.303\DotnetTools\dotnet-watch\8.0.303-servicing.24317.6\tools\net8.0\any\dotnet-watch.dll" --project C:\tmp\nx-dotnet-example\my-web-api\NxDotnetExample.MyWebApi.csproj run --configuration Debug
Process ID: 19336
dotnet watch ⌚ Watching with Hot Reload.
dotnet watch 🔥 Hot reload enabled. For a list of supported edits, see https://aka.ms/dotnet/hot-reload.
  💡 Press "Ctrl + R" to restart.
dotnet watch 🔧 Building...
dotnet watch 🚀 Started 'C:\Program Files\dotnet\dotnet.exe' with arguments 'msbuild /nologo /t:Build /restore': process id 21332
Telemetry is: Enabled
  Determining projects to restore...
  All projects are up-to-date for restore.
  NxDotnetExample.MyWebApi -> C:\tmp\nx-dotnet-example\dist\my-web-api\net8.0\NxDotnetExample.MyWebApi.dll
  Checking module boundaries for my-web-api
  CONFIGURED undefined
dotnet watch ⌚ Process id 21332 ran for 2640ms
dotnet watch ⌚ Running MSBuild target 'GenerateWatchList' on 'C:\tmp\nx-dotnet-example\my-web-api\NxDotnetExample.MyWebApi.csproj'
dotnet watch 🚀 Started 'C:\Program Files\dotnet\dotnet.exe' with arguments 'msbuild /nologo C:\tmp\nx-dotnet-example\my-web-api\NxDotnetExample.MyWebApi.csproj /p:_DotNetWatchListFile=C:\Users\bendrikov\AppData\Local\Temp\tmpbmddzg.tmp /nologo /v:n /t:GenerateWatchList /p:DotNetWatchBuild=true /p:DesignTimeBuild=true "/p:CustomAfterMicrosoftCommonTargets=C:\Program Files\dotnet\sdk\8.0.303\DotnetTools\dotnet-watch\8.0.303-servicing.24317.6\tools\net8.0\any\DotNetWatch.targets" "/p:CustomAfterMicrosoftCommonCrossTargetingTargets=C:\Program Files\dotnet\sdk\8.0.303\DotnetTools\dotnet-watch\8.0.303-servicing.24317.6\tools\net8.0\any\DotNetWatch.targets" /p:_DotNetWatchTraceOutput=true': process id 5952
dotnet watch ⌚ Process id 5952 ran for 856ms
dotnet watch ⌚ Watching 2 file(s) for changes
dotnet watch ⌚ dotnet-watch is configured to launch a browser on ASP.NET Core application startup.
dotnet watch ⌚ Configuring the app to use browser-refresh middleware.
Telemetry is: Enabled
Running C:\Program Files\dotnet\dotnet.exe "C:\Program Files\dotnet\sdk\8.0.303\DotnetTools\dotnet-dev-certs\8.0.7-servicing.24314.2\tools\net8.0\any\dotnet-dev-certs.dll" https --check --quiet
Process ID: 10556
dotnet watch ⌚ Refresh server running at wss://localhost:62004,ws://localhost:62005.
dotnet watch 🔥 HotReloadProfile: Default.
dotnet watch ⌚ Connecting to the application.
dotnet watch ⌚ Running NxDotnetExample.MyWebApi with the following arguments: '--configuration Debug'
dotnet watch 🚀 Started 'C:\tmp\nx-dotnet-example\dist\my-web-api\net8.0\NxDotnetExample.MyWebApi.exe' with arguments '--configuration Debug': process id 23496
dotnet watch 🚀 Started
dotnet watch 🔥 Hot reload capabilities: Baseline AddMethodToExistingType AddStaticFieldToExistingType AddInstanceFieldToExistingType NewTypeDefinition ChangeCustomAttributes UpdateParameters GenericUpdateMethod GenericAddMethodToExistingType GenericAddFieldToExistingType.
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5039
dotnet watch ⌚ Launching browser.
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\tmp\nx-dotnet-example\my-web-api

Additional Information

Disabling hot-reload workarounds it in my case:

{
  "$schema": "./node_modules/nx/schemas/nx-schema.json",
  "targetDefaults": {
    //...
    "@nx-dotnet/core:serve": {
      "options": {
        "no-hot-reload": "true"
      }
    }
  },

It looks like there are some breaking changes in net8 related to dotnet watch + hot reload so that is why it works

@Den-dp Den-dp added bug Something isn't working needs-triage This issue has yet to be looked over by a core team member labels Jul 19, 2024
@AgentEnder
Copy link
Member

Interesting, I'm not sure what changed on the CLI side for that. Outside of Nx, can you get it to work?

@Den-dp
Copy link
Contributor Author

Den-dp commented Jul 20, 2024

After some research, I found that these commands work for both .net7 and .net8

# explicitly pass msbuild property
dotnet watch run --project .\my-web-api\NxDotnetExample.MyWebApi.csproj --property:Configuration=Release
dotnet watch run --project .\my-web-api\NxDotnetExample.MyWebApi.csproj --property:Configuration=Debug

# disable hot reload so dotnet watch switches to old behavior:
dotnet watch run --project .\my-web-api\NxDotnetExample.MyWebApi.csproj --configuration Release --no-hot-reload
dotnet watch run --project .\my-web-api\NxDotnetExample.MyWebApi.csproj --configuration Debug --no-hot-reload

I've checked it by adding this to the Program.cs:

#if DEBUG
Console.WriteLine("The current configuration is Debug");
#elif RELEASE
Console.WriteLine("The current configuration is Release");
#else
Console.WriteLine("The current configuration is unknown");
#endif

The reason why dotnet watch run --project <...>.csproj --configuration Release was working in .net7 but stopped in .net8 is probably related to the fact that the watch command in .net7 wasn't capable of enabling HotReload for generated app, falling back to some old behavior that allows passing --configuration:

> $env:DOTNET_CLI_CONTEXT_VERBOSE='true'; nx run my-web-api:serve:development

> nx run my-web-api:serve

Executing Command: dotnet "watch" "--project" "C:\tmp\nx-dotnet7-example\my-web-api\NxDotnet7Example.MyWebApi.csproj" "run" "--configuration" "Debug"
Telemetry is: Enabled
Running C:\Program Files\dotnet\dotnet.exe "C:\Program Files\dotnet\sdk\7.0.410\DotnetTools\dotnet-watch\7.0.410-servicing.24272.9\tools\net7.0\any\dotnet-watch.dll" --project C:\tmp\nx-dotnet7-example\my-web-api\NxDotnet7Example.MyWebApi.csproj run --configuration Debug
Process ID: 15364
dotnet watch ⌚ Did not find a HotReloadProfile or running a non-default command. Watching with legacy behavior.
dotnet watch ⌚ Evaluating dotnet-watch file set.
dotnet watch ⌚ Running MSBuild target 'GenerateWatchList' on 'C:\tmp\nx-dotnet7-example\my-web-api\NxDotnet7Example.MyWebApi.csproj'
dotnet watch 🚀 Started 'C:\Program Files\dotnet\dotnet.exe' 'msbuild /nologo C:\tmp\nx-dotnet7-example\my-web-api\NxDotnet7Example.MyWebApi.csproj /p:_DotNetWatchListFile=C:\Users\bendrikov\AppData\Local\Temp\tmp88E9.tmp /nologo /v:n /t:GenerateWatchList /p:DotNetWatchBuild=true /p:DesignTimeBuild=true /p:CustomAfterMicrosoftCommonTargets=C:\Program Files\dotnet\sdk\7.0.410\DotnetTools\dotnet-watch\7.0.410-servicing.24272.9\tools\net7.0\any\DotNetWatch.targets /p:CustomAfterMicrosoftCommonCrossTargetingTargets=C:\Program Files\dotnet\sdk\7.0.410\DotnetTools\dotnet-watch\7.0.410-servicing.24272.9\tools\net7.0\any\DotNetWatch.targets' with process id 12776
dotnet watch ⌚ Process id 12776 ran for 1062ms
dotnet watch ⌚ Watching 4 file(s) for changes
dotnet watch ⌚ Watch command can be configured to use --no-restore.
dotnet watch ⌚ No restore arguments: run --no-restore --configuration Debug
dotnet watch ⌚ dotnet-watch is configured to launch a browser on ASP.NET Core application startup.
dotnet watch ⌚ Configuring the app to use browser-refresh middleware.
Telemetry is: Enabled
Running C:\Program Files\dotnet\dotnet.exe "C:\Program Files\dotnet\sdk\7.0.410\DotnetTools\dotnet-dev-certs\7.0.20-servicing.24269.7\tools\net7.0\any\dotnet-dev-certs.dll" https --check --quiet
Process ID: 15724
dotnet watch ⌚ Refresh server running at wss://localhost:59572,ws://localhost:59573.
dotnet watch 🚀 Started 'C:\Program Files\dotnet\dotnet.exe' 'run --configuration Debug' with process id 1252
dotnet watch ⌚ Running dotnet with the following arguments: run --configuration Debug
dotnet watch 🚀 Started
Telemetry is: Enabled
Building...
Running C:\tmp\nx-dotnet7-example\dist\my-web-api\net7.0\NxDotnet7Example.MyWebApi.exe
Process ID: 15704
The current configuration is Debug
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5241
dotnet watch ⌚ Launching browser.
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\tmp\nx-dotnet7-example\my-web-api

but in .net8 this command started to enable HotReload (check dotnet watch 🔥 Hot reload enabled. logs in issue description).

Also, here are some interesting places in SDK that show previous and new behavior:

https://github.com/dotnet/sdk/blob/f32d32cbb9275dc2cbdf6293b68f346acc59779c/src/BuiltInTools/dotnet-watch/Program.cs#L287-L303

https://github.com/dotnet/sdk/blob/release/7.0.4xx/src/BuiltInTools/dotnet-watch/Program.cs#L284-L303

https://github.com/dotnet/sdk/blob/release/8.0.4xx/src/BuiltInTools/dotnet-watch/Program.cs#L225-L234

Copy link
Contributor

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 28, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working needs-triage This issue has yet to be looked over by a core team member outdated
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants