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

Don't overwrite pinned assembly versions in servicing #84079

Merged
merged 6 commits into from
Apr 6, 2023

Conversation

ViktorHofer
Copy link
Member

Fixes #84031

Eight packable projects pin their assembly version for .NET Framework compatibility. The incremental package servicing infrastructure didn't check if the assembly version is pinned and changed it during servicing.

As an example, System.Speech pins its assembly version to 4.0.0.0 but that version gets overwritten during servicing. I.e. for .NET 7 the version would then change to "7.0.0.$(ServicingVersion)" which is incorrect.

Please find the full list of impacted assemblies below:

  • System.ComponentModel.Composition
  • System.DirectoryServices
  • System.DirectoryServices.AccountManagement
  • System.DirectoryServices.Protocols
  • System.Management
  • System.Reflection.Context
  • System.Runtime.Caching
  • System.Speech

This change should be backported into release/6.0 and release/7.0.

@ghost
Copy link

ghost commented Mar 29, 2023

Tagging subscribers to this area: @dotnet/area-infrastructure-libraries
See info in area-owners.md if you want to be subscribed.

Issue Details

Fixes #84031

Eight packable projects pin their assembly version for .NET Framework compatibility. The incremental package servicing infrastructure didn't check if the assembly version is pinned and changed it during servicing.

As an example, System.Speech pins its assembly version to 4.0.0.0 but that version gets overwritten during servicing. I.e. for .NET 7 the version would then change to "7.0.0.$(ServicingVersion)" which is incorrect.

Please find the full list of impacted assemblies below:

  • System.ComponentModel.Composition
  • System.DirectoryServices
  • System.DirectoryServices.AccountManagement
  • System.DirectoryServices.Protocols
  • System.Management
  • System.Reflection.Context
  • System.Runtime.Caching
  • System.Speech

This change should be backported into release/6.0 and release/7.0.

Author: ViktorHofer
Assignees: ViktorHofer
Labels:

area-Infrastructure-libraries

Milestone: -

There are eight packable projects that pin their assembly version for .NET
Framework compatibility. The incremental package servicing
infrastructure didn't check if the assembly version is pinned and always
changed it.

As an example, System.Speech pins its assembly version to 4.0.0.0 but
that version gets overwritten during servicing. I.e. for .NET 7 the
version would then change to "7.0.0.$(ServicingVersion)" which is
incorrect.

Please find the full list of impacted assemblies below:
- System.ComponentModel.Composition
- System.DirectoryServices
- System.DirectoryServices.AccountManagement
- System.DirectoryServices.Protocols
- System.Management
- System.Reflection.Context
- System.Runtime.Caching
- System.Speech
@carlossanlop carlossanlop added Servicing-consider Issue for next servicing release review and removed Servicing-consider Issue for next servicing release review labels Mar 29, 2023
Comment on lines -4 to -5
<!-- AssemblyVersion is frozen to that which originally shipped in 2.1 -->
<AssemblyVersion>4.0.0.0</AssemblyVersion>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This library only ships inside the Microsoft.NETCore.App shared framework. I assume we don't need to pin its assembly version anymore?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it once had a package and this is left over from that time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the expected side-effect of removing AssemblyVersion from here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assembly will version in the same way as every other assembly that ships only in the targeting packs (N.0.0.0 which remains frozen in servicing).

Copy link
Member

@ericstj ericstj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you consider only applying AssemblyVersion to the netstandard2.0 assembly -- that way we wouldn't break folks targeting .NETCore who consumed the serviced packages? It also limits the "ugliness" of this pinned assembly version - letting us do the right thing in new versions and only having this fixed version for .NETStandard.

These assemblies pin their AssemblyVersion to be compatible with
.NETFramework where the same assembly is inbox.

The only TargetFramework we build that is compatible with .NETFramework
is netstandard2.0, so only pin the assembly on that framework.
@ericstj
Copy link
Member

ericstj commented Apr 3, 2023

I tested this change in servicing and noticed that it isn't behaving quite right.
https://gist.github.com/ericstj/308e0ba41e977fe7c4f6e1025d076e0e

eng/packaging.targets Outdated Show resolved Hide resolved
Previously assemblies would set AssemblyVersion in Directory.Build.props
which was too early, because later packaging.targets could not distinguish
between a value that was explicitly set and the default value of the repo.

Instead override the value after the Servicing value is set, in
Directory.Build.targets
@ericstj
Copy link
Member

ericstj commented Apr 3, 2023

Of the 8 packages listed, System.DirectoryServices is also part of the WindowsDesktop shared framework, so that prevented it from hitting this problem.

While I do think we should make the change I mentioned above #84079 (review) to reduce the places where we hardcode the version, I recommend we avoid doing that in servicing for System.DirectoryServices since it isn't broken and that change would leak into the targeting pack.

Of the remaining 7 packages, only System.DirectoryServices.Protocols and System.Management have shipped at all in servicing in 6.0 and 7.0. We could further reduce servicing risk by only conditioning the version for these 2 packages in servicing branches. That way new builds of those two packages would support the previously serviced versions, but we wouldn't introduce upgrade problems should we ever decide to ship the other 5 packages.

The only thing this target did was a redundant check that AssemblyVersion was
set for projects in the Targeting Pack.  That check was failing for
the NETStandard build of System.DirectoryServices.

This target was providing no value, instead we need to fix dotnet#42961
which will be a proper check of our servicing version rules.
@ericstj
Copy link
Member

ericstj commented Apr 5, 2023

Here's the 7.0 version of the fix. https://github.com/dotnet/runtime/compare/release/7.0-staging...ericstj:runtime:FixPinnedAssemblyVersion-7.0?expand=1

Here's the diff of assembly versions: https://gist.github.com/ericstj/5e914be725066df9824fd1e3fca12c08

Note the change for 5 binaries which we never shipped. These were still seeing the 7.0.0.0 version because their version was being replaced with a ServicingVersion of 0. We would have noticed this problem if we shipped any other packages which had references to these projects. I don't think we've done this but I'll audit all references and update this comment. Update: I reviewed all the references to these projects and though some exist, luckily none of them were shipped. Additionally, since these are all 1/1 assemblies with .NETFramework we didn't leak the bad versions in our .NETFramework compat shims.

Copy link
Member

@carlossanlop carlossanlop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. If the manual tests work, let's merge it.
And thanks for sending the backports.

@ericstj ericstj merged commit 71deac7 into dotnet:main Apr 6, 2023
@ViktorHofer ViktorHofer deleted the FixPinnedAssemblyVersion branch April 11, 2023 20:25
Copy link
Member Author

@ViktorHofer ViktorHofer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that looks great. Unfortunately I didn't notice that the AssemblyVersion property was already set in Versions.props.

@ghost ghost locked as resolved and limited conversation to collaborators May 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Libraries with hardcoded netstandard2.0 AssemblyVersions are shipping incorrect AssemblyVersions in servicing.
3 participants