dotnet / sdk-container-builds

Libraries and build tooling to create container images from .NET projects using MSBuild
https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container
MIT License
179 stars 37 forks source link

PublishProfile doesn't work out of the box for non-web projects #141

Closed baronfel closed 9 months ago

baronfel commented 2 years ago

The default-fallback mechanism for PublishProfiles in the SDK doesn't work for non-web projects. We should fix this, otherwise console app users end up having to use /t:PublishContainer as the entrypoint, which we don't want from a uniformity of experience perspective.

kaylumah commented 2 years ago

Most of my apps are Console based so looking forward to this

baronfel commented 1 year ago

We're planning to fix this in 7.0.300 by unifying the publish profile targets in the SDK across the project types.

baronfel commented 1 year ago

This is being tracked in https://github.com/dotnet/sdk/pull/32422 - we need to get input from the Publish team about if this is safe to do. Once this is done, the publish gesture will be the same for all project types.

vlada-shubina commented 1 year ago

Looks as duplicate of https://github.com/dotnet/sdk-container-builds/issues/402

tmds commented 1 year ago

@baronfel is there a way to containerize a console app using the .NET 8 SDK?

baronfel commented 1 year ago

yes - we document this in our Getting Started and a few other places, but you can add the PublishContainer target to a publish call and that just works:

dotnet publish /t:PublishContainer -r linux-x64
tmds commented 1 year ago

I have tried that using the rc1 and a dialy rc2 build (both built from source). Both say the PublishContainer target does not exist:

$ dotnet --version
8.0.100-rc.2.23470.1
$ dotnet publish /t:PublishContainer
MSBuild version 17.8.0-preview-23468-06+1b84c9b5c for .NET
  Determining projects to restore...
  Restored /tmp/console3/console3.csproj (in 199 ms).
/home/tmds/Downloads/dotnet-rc2/sdk/8.0.100-rc.2.23470.1/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.RuntimeIdentifierInference.targets(311,5): message NETSDK1057: You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy [/tmp/console3/console3.csproj]
  console3 -> /tmp/console3/bin/Release/net8.0/console3.dll
  console3 -> /tmp/console3/bin/Release/net8.0/publish/
/tmp/console3/console3.csproj : error MSB4057: The target "PublishContainer" does not exist in the project.
baronfel commented 1 year ago

Does the console app have the package reference added?

tmds commented 1 year ago

No, I missed that step, and I had assumed it would work with the built-in SDK container tooling.

It is working when I add the package.

baronfel commented 9 months ago

Closing as the targets are available for all projects starting in 8.0.200.

kijanawoodard commented 9 months ago

Is this tip in the docs resolved?

image https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container?pivots=dotnet-8-0

baronfel commented 9 months ago

It will be when 8.0.200 releases next month - we'll be doing a pass on some of the docs at that time.

winzuus commented 7 months ago

It will be when 8.0.200 releases next month - we'll be doing a pass on some of the docs at that time.

Hi @baronfel I got the 8.0.200, how can I verify it is fixed?

Also , it seems hard to me to find what the explanation of "/t:PublishContainer" . Do we have a API reference doc for this? I would like to know what does "/t" do and what other options (other than "PublishContainer") are available, and what does each option do. Also it is good to add the "/t" and its options into the "dotnet publish" help command:

E.g. image

As you can see that the help doc for "dotnet publish" does not mention anything about the "/t:PublishContainer".

Thank you

baronfel commented 7 months ago

/t is the MSBuild command line parameter to build a particular MSBuild target, that's all. PublishContainer is the name of the MSBuild target that actually builds and pushes the container.

In previous versions, all the PublishProfile did was hide the fact that we were calling an MSBuild target under the hood - now this is less hidden and more clear.

winzuus commented 7 months ago

/t is the MSBuild command line parameter to build a particular MSBuild target, that's all. PublishContainer is the name of the MSBuild target that actually builds and pushes the container.

In previous versions, all the PublishProfile did was hide the fact that we were calling an MSBuild target under the hood - now this is less hidden and more clear.

Thanks @baronfel for your timely reply.

I have checked the MSBuild command args and did not find the "/t " parameter. Is it the "-target" or "-t" parameter?

If yes, does it mean that in Windows OS, we can freely swap the "-" and "/" ?

Also where can we find the available MSBuild targets? I found https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-targets?view=vs-2022 https://stackoverflow.com/questions/57719166/what-are-the-existing-build-targets-for-msbuild

But I cannot see the PublishContainer as an available target, so I guess there might be an official doc for this?

baronfel commented 7 months ago

There's a paragraph on the MSBuild CLI docs that describe the various forms of the switches:

Every switch is available in two forms: -switch and /switch. The documentation only shows the -switch form. Switches are not case-sensitive. If you run MSBuild from a shell other than the Windows command prompt, lists of arguments to a switch (separated by semicolons or commas) might need single or double quotes to ensure that lists are passed to MSBuild instead of interpreted by the shell.

So yes, - and / are equivalent in MSBuild's CLI syntax.

For discovering all of the available targets, you can use the -targets flag - here's an example from one of my projects:

> dotnet msbuild -targets | select-string Container

_ContainerVerifySDKVersion
ComputeContainerBaseImage
ComputeContainerConfig
_CheckContainersPackage
PublishContainer
winzuus commented 7 months ago

@baronfel thank you!!

Is there a documentation on Microsoft Website for all of these MSBuild Targets?? I am expecting to see a document which has the full list of supported targets with Explanation about earch target.

Also, I found that I can only use the command "> dotnet msbuild -targets | select-string Container" in a folder which contains the .csproj file, not any other folders. Why? I thought the MSBuild targets are across OS wide, not just for a particular project.

baronfel commented 7 months ago

Is there a documentation on Microsoft Website for all of these MSBuild Targets??

Not generally - targets can come from anywhere, and only targets that do not start with _ are considered 'public'. To be completely honest with you, many users do not interact with targets outside of calling dotnet build, dotnet publish, etc - SDK Container publishing is somewhat unique in this regard. The contract we give to users is that a) the target exists, and b) you can use the MSBuild Properties and Items described in this set of documentation to control its behavior. If you'd like to see more information about your builds, I'd encourage you to investigate MSBuild Binary Logs.

I thought the MSBuild targets are across OS wide, not just for a particular project.

That's actually exactly inverse - targets are only relevant to a project, just like all of MSBuild. It's just that for solution files, MSBuild creates a project file for the solution behind the scenes.

winzuus commented 7 months ago

thanks @baronfel for your explanation.

Now, back to the unified publish experience. I have .NET 8.0.200, does this mean that I can remove the "/t:PublishContainer" and use the common "-p:PublishProfile=DefaultContainer" ?

baronfel commented 7 months ago

Exactly the inverse - PublishProfiles are not usable by all project types, instead you should use /t:PublishContainer. This will work for all application project types, and can even be done at the solution-level (which PublishProfiles cannot).

winzuus commented 7 months ago

@baronfel Lmao, I got it totally opposite every time haha.

  1. So if /t:PublishContainer works for all types of project. Why do we even need it, shouldn't it be removed from the "dotnet publish" command, because this section will always be there and no change at all.

  2. What does it indicate when it work at the solution-level? Does it mean that if there were more than 1 project under 1 solution, I can go to the solution folder and do dotnet publish ..... command and it just publish all projects under the solution folder?(hopefully, not completely inverse again x_x)

baronfel commented 7 months ago

Good questions, and I'm happy to keep answering :)

  1. not all applications want to create a container - the 'default' for publish should be a 'normal' publish (lots of docs on this here). The container feature builds on top of this standard publish and adds a bit more - that's why it's not the default :)

  2. so you can do a number of operations at the 'solution level' - for example dotnet build, dotnet pack, etc. in these cases MSBuild will build/pack/etc each applicable project in the solution. PublishContainer works the same way, which is super helpful! If you take a binlog (see my earlier link) you'll see this in action - each containerizable project (i.e. projects where the EnableSdkContainerSupport property is set to true) will create a container, the others won't. Publish Profiles, the older mechanism, only ever worked for Web and Worker SDK projects - and there are a bunch of other project types not one of those two.

winzuus commented 7 months ago

Thank you so much @baronfel .

I got all my questions answered. You should be the MVP Microsoft Employee haha