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

Enable publishing for a RID with PublishRuntimeIdentifier #26444

Closed
richlander opened this issue Jul 6, 2022 · 8 comments
Closed

Enable publishing for a RID with PublishRuntimeIdentifier #26444

richlander opened this issue Jul 6, 2022 · 8 comments
Assignees
Labels
Area-NetSDK untriaged Request triage from a team member

Comments

@richlander
Copy link
Member

Enable publishing for a RID with PublishRuntimeIdentifier

.NET is simultaneously cross-platform and good at targeting a single platform. Arguably, its cross-platform nature has the greatest benefit during development, where teams might span multiple operating systems and architectures. This nature also works well for deployment but building an app for a specific target often yields the best results. The gestures required to support the model of cross-platform development and single-platform deployment are OK but could be improved . We can fix that by adding a PublishRuntimeIdentifier property.

We've been progressively adding Publish* properties over the last several .NET versions. They are a nice pattern since they are only effective for the publish task. It makes to extending that to Runtime Identifier (RID) targeting.

Desired UX

Today, you have two basic choices (using Linux x64 as an example):

  • Add <RuntimeIdentifier>linux-x64<RuntimeIdentifier>, matching the deployment target.
    • This assumes that all developers working with the project are on Linux x64 machines.
    • Developers can workaround this by adding -r win-x64 (assuming they are on Windows x64) to all of their CLI operations.
    • This is bad UX.
  • Use -r linux-x64 with dotnet publish commands when preparing a production deployment.
    • This works well for development and avoids all the development problems of the prior option.
    • It's easy to forget which arguments to use to product the correct build.
    • It's also not possible to encode publishing information in an MSBuild file.
    • It makes Dockerfiles look not pretty.

Going forward, we can offer a new property that splits the difference between the current options, which is PublishRuntimeIdentifier.

It will have the following characteristics, assuming PublishRuntimeIdentifier=linux-x64

  • dotnet build and related verbs (run and test) are unaffected.
  • For example, dotnet run will use the native Arm64 runtime on macOS by default. This assumes that the app is cross-platform (like a typical ASP.NET Core app).
  • dotnet publish will produce a linux-x64 by default, with the intention of producing an app for deployment.

A common pattern with containers is:

dotnet restore
dotnet publish -r linux-x64 --self-contained false --no-restore

That's similar to the intended behavior of PublishRuntimeIdentifier (ignoring SCD vs FDD). Ideally, the initial restore would download the linux-x64 apphost, since we're about to need it. Perhaps that doesn't matter (or isn't how it works).

Related context

I've been thinking about how to better differentiate build and publish. We need to ensure that we're seeing the full picture on what controls developers should have for the best local dev and production outcomes. In particular, we should think about which MSBuild configuration makes sense to specify differently via publish. Perhaps PublishRuntimeIdentifier and PublishRelease are the last remaining publish-specific gestures. Likely, we'll see something else that should be enabled in a similar way. My point is that we need to continue to think in these terms to ensure that we have good differentiation between the build and publish experiences.

I recently saw this Azure SDK sample. This (presumably) Azure-oriented property caused me some concern. I didn't look at the definition of it, but it's hard to imagine how it could be doing anything coherent. It's, in part, my inspiration for this scheme.

@rolfbjarne
Copy link
Member

It would be nice if this includes a way for an SDK (the iOS SDK on our case) to set a default PublishRuntimeIdentifier.

This is what happens right now:

  • In order to speed up the dev loop, we default to a simulator runtime identifier (developers debug on a simulator more than they debug on a device).
  • A simulator runtime identifier is always the wrong choice when publishing.
  • The runtime identifier has to be set quite early in the build, and at that point we don't know whether the developer is publishing or just building.
  • The result is that the developer will always have to specify a runtime identifier when publishing (dotnet publish -r ...) - we've improved this slightly by detecting the scenario and telling the user to pass a runtime identifier if none was passed (as opposed to publishing something that will never work), but that's just a tiny bandaid on the problem.

@richlander
Copy link
Member Author

That is a good idea. I never thought about that kind of option. Can you open a separate issue for that?

@rolfbjarne
Copy link
Member

Done: #27253

@nagilson
Copy link
Member

I assume we want <RuntimeIdentifier/> in a project file to be overriden by PublishRuntimeIdentifier in the project when publishing? But if someone specifies a RID in the call, like dotnet publish -r RID and that conflicts with PublishRuntimeIdentifier, I assume we instead want to take the CLI option over the project option? May you confirm that's the better UX in your opinion @richlander ?

I wish there was a better way to safeguard / prevent users from putting themselves into these messy situations with conflicting properties, but probably more of a hassle if we fail on these cases

@DamianEdwards
Copy link
Member

Command line args should always win.

@nagilson
Copy link
Member

nagilson commented Oct 3, 2022

Thanks, that is a helpful rule to live by. Makes sense!

One scenario that's kind of funky is dotnet publish -r RID -/p:PublishRuntimeIdentifier=RID_2. We could pick RID, RID_2, or fail. But I don't think we care as much about scenarios where there's conflicting global information. I don't really lean one way or the other when it comes to failing vs letting the implementation pick whichever one it picks. If it comes down to an easy change vs one with potential to break stuff that takes a long time to implement. But if there's any strong opinions on this please do lmk!

@DamianEdwards
Copy link
Member

Yeah that is kinda funky just due to what those parameters map to and this specific action (publish).

However, it should be totally reasonable to have PublishRuntimeIdentifier defined in the project file and then override that via publish -r RID, and given that /p:PublishRuntimeIdentifier would override the value in the project file anyway, I'd expect -r to win in this case.

@nagilson
Copy link
Member

nagilson commented Nov 7, 2022

Closing this as resolved by: #28717. Thanks for the help and lmk if you have any issues with this!

@nagilson nagilson closed this as completed Nov 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-NetSDK untriaged Request triage from a team member
Projects
None yet
Development

No branches or pull requests

4 participants