Enable publishing for a RID with `PublishRuntimeIdentifier`
See original GitHub issueEnable 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
withdotnet 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
andtest
) 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 alinux-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.
Issue Analytics
- State:
- Created a year ago
- Reactions:2
- Comments:8 (8 by maintainers)
Top GitHub Comments
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 viapublish -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.Command line args should always win.