nuke-build / nuke

🏗 The AKEless Build System for C#/.NET
https://nuke.build
MIT License
3.07k stars 369 forks source link

DotNetPublishSettings lacks some arguments #1350

Closed ArwynFr closed 4 months ago

ArwynFr commented 8 months ago

Usage Information

NUKE version 8.0.0 / SDK version 8.0.200 / net 8.0 / Win 10 21H2 LTSC

Description

Some arguments of the dotnet publish command are missing from the fluent API, especially --os and --arch. Also you can't provide a custom build target. This feature is especially missing when using dotnet publish to push a docker image to a registry.

These options are probably missing on other commands such as pack/build.

Sources: https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container?pivots=dotnet-8-0#publish-net-app https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-publish

Reproduction Steps

DotNetTasks.DotNetPublish(_ => _
  .SetProject("project")
  .SetConfiguration(Configuration)
  .AddProperty("ContainerImageTag", OctoVersionInfo.FullSemVer)
  .SetOS("linux")
  .SetArch("x64")
  .SetTarget("PublishContainer"));

Expected Behavior

dotnet publish project --configuration Debug /p:ContainerImageTag=0.1.16 --os linux --arch x64 /t:PublishContainer

Actual Behavior

Compilation error

Regression?

No

Known Workarounds

DotNetTasks.DotNetPublish(_ => _
  .SetProject("project")
  .SetConfiguration(Configuration)
  .AddProperty("ContainerImageTag", OctoVersionInfo.FullSemVer)
  .SetProcessArgumentConfigurator(_ => _
    .Add("/t:PublishContainer")
    .Add("--os linux")
    .Add("--arch x64")));

Could you help with a pull-request?

No

ITaluone commented 8 months ago

@ArwynFr Could you please share your csproj.. I do not understand the /t:.. parameter.. Does it call something specific in the csproj, or is this an SDK specific switch?

Edit: As of this documentation the only possibility is /t:PublishContainer: https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container?pivots=dotnet-8-0

So, probably we just could make it paramterless, don't we?

ArwynFr commented 8 months ago

@ITaluone I've made some further investigations.

Basically dotnet-cli is a wrapper around other MS tools, espacially msbuild.dll, which is a .NET5+ port of the old legacy MsBuild.exe. The /t: is originally an msbuild parameter that stands for "target". It works exacly like a nuke target and that's how the sdk knows it must restore nuget before building and build before publishing. Usually, the MsBuild target is set by the dotnet cli command. For instance, dotnet publish command translates to msbuild.dll -target:Publish and dotnet restore translates to msbuild.dll -target:Restore.

dotnet publish /t:PublishContainer allows to override the actual msbuild target that was implicitly placed by the usage of the dotnet publish command into a msbuild.dll -target:PublishContainer. This allows the msbuild to know it has to publish a docker image rather than a binary. For many reasons MS prefered this over a separate dotnet publishContainer command. This behavior can be showased by the fact that running dotnet restore /t:Publish is equivalent to dotnet publish.

My tests have shown that you can use three different syntax for this feature at the dotnet cli level:

The --target PublishContainer format is not supported.

What targets are available is very complex though. Some targets come directly from the framework (Restore, Build, Publish). Some targets depend on the Sdk used: Microsoft.NET.Sdk, Microsoft.NET.Sdk.Web, ... Some targets are added by nuget packages, espacially packages involved in testing for instance. Also, developpers can directly add custom target in their csproj. Parsing targets are probably gonna be a pain to do and are beyond the scope of nuke in my opinion.

I would say you have two valid options:

ITaluone commented 8 months ago

I would go with both SetTarget(string value) and SetPublishContainer(), but @matkoch should decide..

ArwynFr commented 6 months ago

Any update ?