Open Wil73 opened 7 years ago
I don't have any long-term need for the -DependencyVersion
option. I was confused about how some aspects of NuGet package management work.
In the process of trying to remove binding redirects from my code, I thought a good solution was to request Serilog.AspNetCore
change their dependencies. (I now know this was a bad idea.) The first response I got was to try Install-Package Serilog.AspNetCore -DependencyVersion Highest
. But that didn't do anything different for any argument to -DependencyVersion
(because, I know now, I am specifying my NuGet package dependencies via PackageReference
tags in the project file...per the present issue). When I asked why in this GitHub project, I was pointed to the present issue.
To help others like me, a new issue was created suggesting that a warning be given when -DependencyVersion
is used with PackageReference
-specified NuGet package dependencies (at least, until the present issue is resolved).
While I have the attention of a NuGet expert, here is one thing that I think might be helpful to me. How can I "see" the NuGet dependency graph of my solution? Specifically, if some project in my solution depends on the same NuGet package (potentially with different version constraints), I would like to know what all the paths in the NuGet dependency graph are to that NuGet package as well as the version constraint contributed by each of these paths. The goal is to figure out a better way to handle duplicate indirect dependencies than a binding redirect (such as making this indirect dependency into a direct dependency and to picking the desired version). Does that all seem reasonable to you?
My plan is to understand this well enough that I can give a talk a my company to help everyone improve their NuGet package dependency management.
While I have the attention of a NuGet expert, here is one thing that I think might be helpful to me. How can I "see" the NuGet dependency graph of my solution? ...
One of the ways is to run dotnet list --include-transitive
. This funtionality is not yet available with Visual Studio, but we will get there.
The other part is to understand why a specific version was selected. We do not have a mechanism to show this information, but may be having a why
command would help here. Alternatively, you can look at the lock file to figure out what was requested vs. what got resolved , but this requires parsing of the lock file.
I don't understand the danger in allowing package mantainers to add additional options to their csproj files to specify the dependency resolution strategy. At my workplace, minor version never break code and we always want to use the latest minor version. If we need to lock to a specific version for a specific build, we would use the lock file.
Any traction on this issue? It's outstanding. It's desired. Why are we being ignored? Does someone have the CEO's twitter? I hear bad publicity on Twitter gets fast responses.
hello there i think i can't just repeat thing that are already on the thread i have also issue for example with Serilog that has many Microsoft.Extensions.Xxx as transitive in 2.x being pulled down to aspnetcore3.1 i let you guess the disaster
(Some PR were rejected on Serilog to update to msft.extensions.xx 3.1.x)
it forces us to pin down transitive explicitly
we are re-creating one of the biggest issue package.config
had => having both direct and transitive pinned per project
i would really love to see this land as aspnetcore3.1 is now netcoreapp3.1 BUT depends on msft.exrension 3.1 that are netstandard2.0, unless all third part updates the default behavior will attempt to get 2.x as potential transitive in 3.1 apps
@TannerBragg do the things you depend on have the same guarantee?
sorry about pushing that topic again, is there any info on how to to get that Highest
resolution for transitive from an MsBuild Props
today ?
especially when using [*, )
and lockfile properly.
For example :
If you depend on Serilog
You would get transitive resolution of some Microsoft.Extensions.xxxx
(like logging) to 2.x while the Host project is aspnetcore / netcoreapp3.1
It seems to happen because serilog also depends on Microsoft.Extensions.xxx >= 2.1
but the resolution defaults to "Lowest" for example
As it is open on the right, i would love to have a switch in my sources.props
to be able to choose how i want that resolution to happen so i can try whatever suits my needs
First, let me say I have nothing to add to this conversation. I would just like to be able to use Install-Package -DependencyVersion Highest [package_id]
for .NET Core projects. I've been manually installing dependencies when I want to force the latest version and that's a PITA. Thanks for the work you do. I just wish this issue was on the list.
@tebeco The pity is that between most Microsoft.Extensions.*.Abstracts
v2.x and v3.x there is no single breaking change, so in SemVer-thinking there should be no major number change at all.
But on the other hand I don't want different NuGet versions of netcore parts so I can use a single build variable to update them all, for example from 3.1.4 to 3.1.5.
You are applying the converse of SemVer rule 8 instead of rule 8 itself. SemVer allows the major version to be incremented for any reason (as long as the minor and patch versions are reset to 0.)
For example, I think it would be appropriate to increment the major version level if the code was totally rewritten (maybe even in another language) while keeping the API (and even all behavior) unchanged.
Are there any updates on this issue?
It would save a ton of work for releasing well maintained internal packages at my company.
I can only suggest anyone to upvote the first comment / issue in this issue, as it seems to be the relevant metrics being used to prioritize how much user want something to move on activity is hard to quantify by bot (because spam / irrelevant etc ...) while a +1 is quite clear
I mean, 4 years old, perhaps it's just not a priority.
Is the NuGet team open for pull requests?
Is the NuGet team open for pull requests?
Looks like they are. https://github.com/NuGet/Home/blob/dev/CONTRIBUTING.md
Still waiting for this critical feature, Microsoft!
If there's no way to override the lowest version behavior, how are people expected to deal with security vulnerabilities in transitive dependencies?
As a concrete example, Azure.Core has a dependency on System.Text.Encodings.Web 4.6.0 which is susceptible to remote code execution. Even though the issue was fixed in System.Text.Encodings.Web 4.7.2 almost a year ago, I get the vulnerable version if I consume the latest Azure.Core.
If there's no way to override the lowest version behavior, how are people expected to deal with security vulnerabilities in transitive dependencies?
As a concrete example, Azure.Core has a dependency on System.Text.Encodings.Web 4.6.0 which is susceptible to remote code execution. Even though the issue was fixed in System.Text.Encodings.Web 4.7.2 almost a year ago, I get the vulnerable version if I consume the latest Azure.Core.
Hi @mikamins , I actually ran into the same issue with specifically : "Microsoft.ServiceFabric.AspNetCore.Kestrel 4.2.477" => "Microsoft.ServiceFabric.AspNetCore.Abstractions 4.2.477" => "Microsoft.AspNetCore.Http.Abstractions 1.0.0"=>"System.Text.Encodings.Web 4.0.0":
I resolved this by adding System.Text.Encodings.Web 4.7.2 as a direct dependency of the msbuild project, and it will cause all lower level dependencies to reference v4.7.2 instead of v4.0.0
@RandyT97 while your workaround of course works, it solves the problem for a specific package. Your project could well have other transitive dependencies suffering from the same problem without you even being aware of it.
Besides, a few months from now, anyone working on the project (or even some automatic tool) may remove the direct dependency on System.Text.Encodings.Web
because it is not used directly, everything builds just fine without it, so why have it around?
net5 now totally f*cked up it just from the start. Being now at 5.0.4 some newest packages are at 5.0.3, 5.0.2, 5.0.1, 5.0.0, and some other versions. And it doesn't matter whether I use 5.0.4 packages on 5.0.0 runtime or 5.0.0 packages on 5.0.4 runtime. All combinations just work and I can't tell the build server that this all probably is just wrong and smelly bullshit.
A lock file has been introduced in order to properly do this with PackageReference. Are there any updates on this issue?
So is this issue fixed? And will there be documentation to show how to properly handle float versioning throughout an entire project?
the title is about direct OR TRANSITIVE so it's still not possible no
also you can't decide about a strategy AT ALL, you have to go manually edit every single dependency one by one as a text file and replace digit with *
like when you use dotnet add package
it won't care about other package using wildcard it will put the full version down
as for the lockfile, did they fixed
Can we hear from the NuGet team? Is this:
Hi all,
I'm going to write a message here for now because this issue hasn't had a reply from the team in quite some time. I apologize in advance.
This issue is currently the 3rd đź‘Ť most upvoted issue in our client repository. There are many considerations to take into account for the behavior of package resolution that have already been discussed amongst everyone here and known workarounds & features that help you be more deterministic when resolving packages(especially with regards to security).
I want to be transparent with everyone and tell you that from my perspective(PM on the NuGet team), this issue is important but we currently do not have a plan for it. What that means is that we believe there are other critical work to complete this year prior to getting time to invest into this (and the consideration of capacity). This can change however.
We also need to understand this issue further, the current pain points, and know what is possible for the product given many of the previous blockers have been implemented or have plans to be(i.e. lock files / package overriding / etc) and the limitations we have.
Your feedback on how we can move forward with this issue and your ideal happy paths in your daily management of dependencies have already helped us tremendously. Please feel free to keep commenting on your ideal experiences so we can make the best solution. Knowing the desired end goal/experience will keep us headed in the right direction.
I am currently working with our teams to produce a year's living roadmap to clue everyone in on what we have planned for 2022. When we publish this, please provide your feedback so we can understand how this issue weighs in comparison to other highly requested features. This will help us get our plans right and be more community driven.
Thank you.
Thank you for providing an update, even if it is unfortunate news.
Thanks, appreciate the update, and glad to know it's at least (somewhat) on your radar.
The ideal experience would be to resolve the transitive dependencies with a defined resolution strategy and consolidate the transitive dependencies for a solution because the lock file is by project.
@HugoLemieux In the meantime, how would that look in your current development experience? What type of CLI flags, VS UI, or other happy paths would allow you to do that?
Consider the ability to:
How would you like to express that in your configurations today?
It would be great to have the same experience as it was with the packages.config.
In order to resolve the transitive dependencies with a defined resolution strategy:
The VS UI in order to consolidate all the dependencies (direct and transitive) for a solution:
I think these could work using lock file by project.
We would like to have better control and cohesion between the versions of our dependencies (transitive included) across multiple projects (workspace/solution). This could be done with a global lock file and a granular control of the transitive dependencies within.
One particular scenario that causes us to want something like this might be worth calling out as a special case: it's the fact that every single package in Microsoft.Extensions.*
revs every single time there's an update to .NET whether anything has changed in a package or not. We have 40 odd open source libraries that we maintain, and every week or so we get a deluge of Dependabot notifications telling us about the zillion places in which it thinks we should update one of these packages.
So what we'd really like is some way to express the policy that we always want the latest available patch of those components by default. The combination of Microsoft's high standards for backwards compatibility plus the fact that most of the time a new patch version on one of these components hasn't changed anything of substance means that we basically always want to take the latest version of these, but tend to want to be deliberate about everything else.
(Alternatively, if these packages would only drop new patch versions when something has actually changed, that would be much better. I wouldn't be drowning in dependabot requests, and I'd also know when there is actually a meaningful change.)
Would be nice to have the dependencyVersion
^1 option again, so every body can decide which updated to get
My issue is in large part that there is no pretty way to solve outdated transient dependencies, especially when there is a critical security issue which is often. If I want to update the transient dependency I currently need to add it as a direct dependency, even though I have no actual direct dependency on it. This both bloats the project file, confuses the hell out of any project readers and observations of dependency trees either using tools or lock files.
I would prefer to be able to set both default transient dependency resolution and/or (preferably and) override transient dependencies in a clearer manner which doesn't add it as a direct dependency. Ideally for specific transient dependencies.
It's crazy that there is no plan articulated for this problem. Our vulnerability scanners check dependencies and report problems on dependencies we don't even deploy. Manually managing these alerts is not practical. Automation is needed.
It's crazy that there is no plan articulated for this problem. Our vulnerability scanners check dependencies and report problems on dependencies we don't even deploy. Manually managing these alerts is not practical. Automation is needed.
Take a hintz! Microsoft will never fix this issue until there is some bad press about it. Microsoft is being apathetic to the risk they are putting their own customers in, in regard to critical vulnerabilities.
Maybe this project can become mainstream... https://fsprojects.github.io/Paket/
I just re-read this, and there's been lots of changes to nuget since this was filed ~5 years ago. Have the problems changed? There are now lock files and central package management that allows you to control the resolution of packages whether they are transitive or not.
I don't want to come off as being "paternalistic" and I want developers to have control, but package dependency resolution requires a global view of the world (the world being your project's transitive closure). Packet had to work around many assumptions in how package versioning works, and some strategies will never work with certain packages.
What might help move this forward are examples of problems and existing workarounds. That would help narrow down how the existing tools have gaps. Some questions on the top of my head:
@davidfowl
~
and ^
)@davidfowl
It's crazy that there is no plan articulated for this problem. Our vulnerability scanners check dependencies and report problems on dependencies we don't even deploy. Manually managing these alerts is not practical. Automation is needed.
I'm in the same boat, however there are other approaches that could be implemented for this specific concern, I've suggested these in a separate ticket https://github.com/NuGet/Home/issues/12341
I stumbled upon this discussion looking to do exactly as the OP stated, however reading the discussion and thinking long and hard about it, I definitely changed my mind: I don't think this feature is really needed nor desirable as stated, but I think some tweaks to the current features could help.
Keep in mind I'm talking only about transitive packages, since we have the ability, to specify Version=*
in *.csproj
files for direct packages. It's about the ability to configure one way or the other the resolution for transitive packages of a dependency you have.
I think relying on "highest possible" dependency version resolution for security is a terrible idea, since there is absolutely no guarantee you will get a version without security issues. And assuming we could specify *
for a transitive dependency version, there is no guarantee you will get the latest version anyway.
So that would be something that makes you think you are getting the latest and greatest patched versions of everything, when in fact you do not. The security argument is, in my opinion irrelevant.
--
Another point: we can classify packages in two types.
I don't think there is a need to change anything. As long as they work, they work, even if the version used is "ancient". And if you do rely on specific optimizations or features of a transitive package, well it should definitely be part of your direct project dependencies.
There is usually NO good reason to use an older version of those packages. Most of the time, you do want the latest package possible. There is usually only 1 instance of a Web API you want to consume, that definitely works with the latest packages, and most definitely do not work with older packages. And for those packages, even tough the code interface did not change, it is entirely possible that internal changes produce different Requests to the External API: Even though your code can compile AND run without exceptions, it might not work the the resource you want to consume.
So those packages sound like a good candidate for the feature. However, those packages are well identified, you definitely know which resources you are consuming (or else you have more pressing concerns), and can already use Central Package Management Transitive Pinning to tell which version you want (but you cannot at the moment specify Version=*
in central package management, which is one of my suggestions).
But most likely, they should be included as direct dependecies of your poject, see suggestion 2).
TL;DR: I think we only really need custom transitive dependency resolution for a small well known subset of packages, allowing global "Highest"-version for transitive packages will cause more trouble than it is worth.
--
So then, a couple of suggestions:
Basically allow the exact syntax we have in *.csproj
at the moment. Using floating versions at the moment result in error NU1011.
Maybe only allow floating versions when packages.lock.json
is enabled. CPM does work with package lock, so I don't see any blocker.
.nuspec
option to mark some dependencies as "direct"It helps solves the issue for packages that depend on an "API nuget".
Exemple: An helper library (
Lib1
) that simplifies working with an Azure API. This helper library has a dependency on an Azure API Nuget (Azure.X.nupkg
).
As a Nuget publisher, my package (Lib1.nupkg
) works for the foreseeable future, with version >= 2.0.0 of Azure.X.nupkg
. I would like to mark this dependency as "direct", so a user of my helper library has more control over this dependency.
As consumer of Lib1
, I want to be able to easily control the Azure.X
dependency and update it when needed.
With the new .nuspec
"direct" dependency option, as a consumer of Lib1
, adding Lib1.nupkg
to my project would add Lib1
as a direct reference, but also Azure.X
as a direct dependency, instead of a transitive one.
My *.csproj
would look like this after adding only Lib1
:
<Project Sdk="Microsoft.NET.Sdk">
<!-- ... -->
<ItemGroup>
<PackageVersion Include="Lib1" Version="1.0.0" />
<!-- Below was added automatically, this dependency is less hidden and I can easily mark it as floating if I wish to. -->
<!-- "direct" dependencies in Azure.X package (if any) should recursively follow the same logic, and be included here -->
<!-- Since it's not a transitive dependency, I will easily be able to update this package -->
<PackageVersion Include="Azure.X" Version "2.0.0" />
</ItemGroup>
</Project>
Nuget that should be referenced directly because they are "important" to your project can now be automatically included. When there is an update to this package, I will be prompted to update this dependency in the future.
I'll keep this one short since it's not related to Nuget directly: I should not be able to use code existing only in a transitive dependency without at least a warning, hinting me at including the package I'm using as a direct dependency.
--
Having thought about all the use cases I have met, I think those first 2 suggestions would cover pretty much everything, and allow me to be pretty confident in the management of my transitive packages.
@clyvari If this strategy can be set individually for each dependency/package source, I'd turn it on for packages in my private feed, so whenever minor
or patch
get bump, packages are automatically updated.
@voroninp That's already possible for direct dependecies of your projet. If you add a depency with Version=2.*
, you will automatically use the latest version possible that is <3.0.
It's only an issue for transitive dependencies, when you add a nuget Lib1
that itself uses, say, System.Text.Json
. You don't really care what version of System.Text.Json Lib1
uses, as long as it works. And if you do, well that means you care enough about System.Text.Json
to add it as a direct dependency of your project.
@clyvari , let's replace System.Text.Json with MyLib and imagine larger (deeper) dependency graph.
Now imagine, we found a bug in MyLib.
How many manipulations/rebuilds are required to update end project with the fixed MyLib depending on resolution strategy?
@voroninp Assuming a bug in any dependency, at the moment you can (and probably should) use CPM with Transitive Pinning.
It's 1 commit to the Dependency.Packages.props
file, and 1 build.
If at the root of a solution, it will be common to all projects in a solution, useful if the dependency is used in multiple projects.
Here is why using "highest possible" resolution strategy isn't sufficient :
Let's assume you have a several packages referencing VulnerableLib.
One requires VulnerableLib Version=[5.2, )
, another VulnerableLib [5.0, 5.7)
.
Latest VulnerableLib
version is 5.7
You specify "Highest possible version" as a resolution strategy.
The version that satisfy your requirement is 5.6
.
Let's say a bug is found in VulnerableLib 5.x versions, fixed in version 5.8
Despite your "Highest possible version" as a resolution strategy, VulnerableLib
will still resolve to vulnerable version 5.6.
And worse, because it is not intuitive (the version requirements might be deep down the dependency tree), you might be mislead into thinking: "VulnerableLib was bumped, all my projects use "Highest possible version" for transitive packages, I'm safe."
Its true that “highest possible” doesn’t always fix the vulnerability, but in my experience it fixes most. An audit report will tell you if it didn’t fix something and enables you to focus on the less easily resolved issues.
@clyvari > another VulnerableLib [5.0, 5.7)
I'd question first this range ;-)
I never understood why Nuget had to re-invent the wheel here and come up with this bonkers system that we now sit with.
It's confusing for users coming from anywhere else and almost ensures you are going to have security vulnerabilities, even though patches are available. It's also encouraged an ecosystem where only a minimum version constraint is specified on dependencies, MS packages being a prime example of this.
Pre-dating Nuget, package managers had some simple concepts:
NuGet developed (or maybe always was) into a new kind of DLL hell - source of random "Method not found" exceptions at runtime (can't the exe-compiler or at least the publish task just check everything once?)
I'm just right now adding the net6 package ErikEJ.EntityFrameworkCore.SqlServer.DateOnlyTimeOnly
to a net7 project which already uses EFcore.SqlServer 7.0.x, the package itself only to extend EFcore.SqlServer 6.0.0+
Thats what "Preview Changes" tells me:
Uninstalling:
Microsoft.Win32.Registry.5.0.0
System.Globalization.4.3.0
System.IO.4.3.0
System.Reflection.4.3.0
System.Reflection.Primitives.4.3.0
System.Resources.ResourceManager.4.3.0
System.Threading.Tasks.4.3.0
Updates:
Azure.Core.1.24.0 -> Azure.Core.1.25.0
Azure.Identity.1.6.0 -> Azure.Identity.1.7.0
Microsoft.Data.SqlClient.5.0.1 -> Microsoft.Data.SqlClient.5.1.0
Microsoft.Data.SqlClient.SNI.runtime.5.0.1 -> Microsoft.Data.SqlClient.SNI.runtime.5.1.0
Microsoft.Identity.Client.4.45.0 -> Microsoft.Identity.Client.4.47.2
Microsoft.IdentityModel.Abstractions.6.21.0 -> Microsoft.IdentityModel.Abstractions.6.24.0
Microsoft.IdentityModel.JsonWebTokens.6.21.0 -> Microsoft.IdentityModel.JsonWebTokens.6.24.0
Microsoft.IdentityModel.Logging.6.21.0 -> Microsoft.IdentityModel.Logging.6.24.0
Microsoft.IdentityModel.Protocols.6.21.0 -> Microsoft.IdentityModel.Protocols.6.24.0
Microsoft.IdentityModel.Protocols.OpenIdConnect.6.21.0 -> Microsoft.IdentityModel.Protocols.OpenIdConnect.6.24.0
Microsoft.IdentityModel.Tokens.6.21.0 -> Microsoft.IdentityModel.Tokens.6.24.0
Microsoft.NETCore.Platforms.5.0.0 -> Microsoft.NETCore.Platforms.1.1.0
Microsoft.Win32.SystemEvents.5.0.0 -> Microsoft.Win32.SystemEvents.6.0.0
System.Buffers.4.5.1 -> System.Buffers.4.5.0
System.Configuration.ConfigurationManager.5.0.0 -> System.Configuration.ConfigurationManager.6.0.1
System.Diagnostics.DiagnosticSource.5.0.0 -> System.Diagnostics.DiagnosticSource.6.0.0
System.Drawing.Common.5.0.0 -> System.Drawing.Common.6.0.0
System.IdentityModel.Tokens.Jwt.6.21.0 -> System.IdentityModel.Tokens.Jwt.6.24.0
System.Runtime.Caching.5.0.0 -> System.Runtime.Caching.6.0.0
System.Security.AccessControl.5.0.0 -> System.Security.AccessControl.6.0.0
System.Security.Cryptography.ProtectedData.5.0.0 -> System.Security.Cryptography.ProtectedData.6.0.0
System.Security.Permissions.5.0.0 -> System.Security.Permissions.6.0.0
System.Text.Encoding.CodePages.5.0.0 -> System.Text.Encoding.CodePages.6.0.0
System.Windows.Extensions.5.0.0 -> System.Windows.Extensions.6.0.0
Installing:
ErikEJ.EntityFrameworkCore.SqlServer.DateOnlyTimeOnly.7.0.1
System.Runtime.CompilerServices.Unsafe.6.0.0
It's a wild mix of up- and downgrades, outtake:
Microsoft.NETCore.Platforms.5.0.0 -> Microsoft.NETCore.Platforms.1.1.0
Microsoft.Win32.SystemEvents.5.0.0 -> Microsoft.Win32.SystemEvents.6.0.0
System.Buffers.4.5.1 -> System.Buffers.4.5.0
I can just only hope this has no serious effect on the final app.
In my company, we develop several nuget packages and consume them in other programs. E.g. P1 <- N1 <- E1 Program1 (P1) references internal nuget N1 that references some external nuget (E1). When I fix bugs in N1 we increase the patch part of the version.
P1 references N1 with floating version (e.g. 1.*). So that P1 (and all other Ps) will take all the bug fixes automatically in next build.
Now if a newer version of E1 was released (e.g. 1.0.1), we want P1 to get it (cause it's might contain a bug fix, or security fix). What we usually do is update N1 to reference the newer N1 (1.0.1), otherwise, we will need to go over all the consuming projects (P1, P2, …) and reference E1 (1.0.1) directly, which is ugly and time consuming.
But since P1 might be directly refencing older version of E1 (1.0.0) it might cause a warning of package downgrade, and because treat warnings as errors it breaks P1.
So eventually the change to N1 is a breaking change. Which is not ideal. Either we break some builds or we increase major of N1 each time we change some minor version of some referenced nuget package (time consuming cause all P's need to be changed).
Is there a better way to do it, that will solve both problems?
What I would like to do is that N1 references the minimum version it requires (e.g. E1 1.0.0) and when P1 is compiled it takes the highest E1, with the bug fixes. This way there won't be a package downgrade error and still the fixes will arrive to all refencing programs (Px). This is not feasible currently since there is no "Biggest major" dependency resolution.
We don't really care about deterministic builds. Our builds are not deterministic anyway, since we use floating versions and for other reasons.
Long time no response anymore, any update on this? I really need to be able to use the latest minor version of dependencies without having to recompile all other packages
I am not going to debate if highest or lowest should be the default: leave the actual behavior up to the consumer.
Why on earth should Microsoft FORCE users to adopt the "safest is best" strategy in the first place?
Is there any reason why we cannot add a switch to nuget.exe and NPM that allows the user to decide their own package restore strategy?
This way consumers of nuget can align nuget behavior to their own business strategies, be they conservative or aggressive.
What I don't understand is why Microsoft has to decide this for consumers in the first place.
To me this is a straight up consumer decision based on private business strategy and policy.
It makes absolutely no sense why a tool vendor should allow themselves to unilaterally decide business strategy for all nuget consumers on the planet without an option to override that.
It's been two years and there's no apparent movement on this issue.
Leave lowest version as the default strategy if you want Microsoft, but for goodness sakes offer a switch to allow consumers to make their own business decisions.