Browse Source

Merge pull request #28295 from dotnet-maestro-bot/merge/release/5.0-to-master

[automated] Merge branch 'release/5.0' => 'master'
msftbot[bot] 5 years ago
parent
commit
ec2e8a0444

+ 2 - 0
eng/Dependencies.props

@@ -73,6 +73,8 @@ and are generated based on the last package release.
     <LatestPackageReference Include="System.Reflection.Metadata" />
     <LatestPackageReference Include="System.Runtime.CompilerServices.Unsafe" />
     <LatestPackageReference Include="System.Runtime.InteropServices.RuntimeInformation" />
+    <!-- System.Security.AccessControl should only be referenced in Dependencies.props and RepoTasks.csproj. -->
+    <LatestPackageReference Include="System.Security.AccessControl" />
     <LatestPackageReference Include="System.Security.Cryptography.Cng" />
     <LatestPackageReference Include="System.Security.Cryptography.Pkcs" />
     <LatestPackageReference Include="System.Security.Cryptography.Xml" />

+ 30 - 0
eng/Versions.props

@@ -159,6 +159,36 @@
     -->
     <MicrosoftNETCoreAppRuntimeVersion>$(MicrosoftNETCoreAppRuntimewinx64Version)</MicrosoftNETCoreAppRuntimeVersion>
   </PropertyGroup>
+  <!--
+    We ship ref/ assemblies for runtime packages in our targeting targeting pack. When servicing that targeting pack,
+    these assemblies must not change. Must also compile our assemblies against the initial ref/ assemblies for runtime
+    packages. But, need to test against the latest implementation assemblies and ship them in our shared framework.
+    Upshot is we need Major.Minor.0 runtime packages for compilation and the targeting pack and Major.Minor.Latest
+    runtime packages for everything else. This is not an issue for assemblies available in Microsoft.NETCore.App.Ref or
+    Microsoft.Extensions.Internal.Transport because it is next to impossible we would service those packages.
+
+    System.Security.AccessControl should only be referenced in Dependencies.props and RepoTasks.csproj. Because
+    it's a transitive reference, we reship the ref/ assembly in Microsoft.AspNetCore.App.Ref. dotnet/runtime ships
+    the implementation assemblies in Microsoft.NETCore.App.Runtime.* packages.
+
+    If testing this configuration prior to servicing, update the versions of dependencies too. E.g. change
+    `$(SystemSecurityPrincipalWindowsV0PackageVersion)` if you change `$(SystemSecurityAccessControlV0PackageVersion)`
+    because System.Security.AccessControl will otherwise be loadable. This should not be necessary in servicing.
+  -->
+  <PropertyGroup Condition=" '$(IsServicingBuild)' == 'true' ">
+    <MicrosoftWin32RegistryV0PackageVersion>$(MicrosoftWin32RegistryPackageVersion.Split('.')[0]).$(MicrosoftWin32RegistryPackageVersion.Split('.')[1]).0</MicrosoftWin32RegistryV0PackageVersion>
+    <MicrosoftWin32SystemEventsV0PackageVersion>$(MicrosoftWin32SystemEventsPackageVersion.Split('.')[0]).$(MicrosoftWin32SystemEventsPackageVersion.Split('.')[1]).0</MicrosoftWin32SystemEventsV0PackageVersion>
+    <SystemDiagnosticsEventLogV0PackageVersion>$(SystemDiagnosticsEventLogPackageVersion.Split('.')[0]).$(SystemDiagnosticsEventLogPackageVersion.Split('.')[1]).0</SystemDiagnosticsEventLogV0PackageVersion>
+    <SystemDrawingCommonV0PackageVersion>$(SystemDrawingCommonPackageVersion.Split('.')[0]).$(SystemDrawingCommonPackageVersion.Split('.')[1]).0</SystemDrawingCommonV0PackageVersion>
+    <SystemIOPipelinesV0PackageVersion>$(SystemIOPipelinesPackageVersion.Split('.')[0]).$(SystemIOPipelinesPackageVersion.Split('.')[1]).0</SystemIOPipelinesV0PackageVersion>
+    <SystemSecurityAccessControlV0PackageVersion>$(SystemSecurityAccessControlPackageVersion.Split('.')[0]).$(SystemSecurityAccessControlPackageVersion.Split('.')[1]).0</SystemSecurityAccessControlV0PackageVersion>
+    <SystemSecurityCryptographyCngV0PackageVersion>$(SystemSecurityCryptographyCngPackageVersion.Split('.')[0]).$(SystemSecurityCryptographyCngPackageVersion.Split('.')[1]).0</SystemSecurityCryptographyCngV0PackageVersion>
+    <SystemSecurityCryptographyPkcsV0PackageVersion>$(SystemSecurityCryptographyPkcsPackageVersion.Split('.')[0]).$(SystemSecurityCryptographyPkcsPackageVersion.Split('.')[1]).0</SystemSecurityCryptographyPkcsV0PackageVersion>
+    <SystemSecurityCryptographyXmlV0PackageVersion>$(SystemSecurityCryptographyXmlPackageVersion.Split('.')[0]).$(SystemSecurityCryptographyXmlPackageVersion.Split('.')[1]).0</SystemSecurityCryptographyXmlV0PackageVersion>
+    <SystemSecurityPermissionsV0PackageVersion>$(SystemSecurityPermissionsPackageVersion.Split('.')[0]).$(SystemSecurityPermissionsPackageVersion.Split('.')[1]).0</SystemSecurityPermissionsV0PackageVersion>
+    <SystemSecurityPrincipalWindowsV0PackageVersion>$(SystemSecurityPrincipalWindowsPackageVersion.Split('.')[0]).$(SystemSecurityPrincipalWindowsPackageVersion.Split('.')[1]).0</SystemSecurityPrincipalWindowsV0PackageVersion>
+    <SystemWindowsExtensionsV0PackageVersion>$(SystemWindowsExtensionsPackageVersion.Split('.')[0]).$(SystemWindowsExtensionsPackageVersion.Split('.')[1]).0</SystemWindowsExtensionsV0PackageVersion>
+  </PropertyGroup>
   <PropertyGroup Label="Manual">
     <!-- Packages from dotnet/roslyn -->
     <MicrosoftNetCompilersToolsetVersion>3.8.0-5.20519.18</MicrosoftNetCompilersToolsetVersion>

+ 67 - 2
eng/targets/ResolveReferences.targets

@@ -248,16 +248,57 @@
         Text="Could not resolve this reference. Could not locate the package or project for &quot;%(Reference.Identity)&quot;. Did you update baselines and dependencies lists? See docs/ReferenceResolution.md for more details." />
   </Target>
 
+  <!--
+    Change @(ResolvedCompileFileDefinitions) items between generation and use in order to compile against RTM lib/
+    or ref/ assemblies. The approach works for all TFMs because it happens after a specific assembly is chosen for
+    compilation; no need to restrict this to (say) the default TFM.
+
+    This target could get confused if the layout changes for one of the dozen special-cased packages during servicing.
+    E.g. ResolvePackageAssets picks a compatible assembly from the 5.0.1 package and _UseRTMReferenceAssemblies
+    changes the path to one not present in the 5.0.0 package. Fortunately, this will break the build with complaints
+    about the "invalid strong name".
+  -->
+  <Target Name="_UseRTMReferenceAssemblies"
+      Condition=" '$(MSBuildProjectName)' != 'RepoTasks' "
+      AfterTargets="ResolvePackageAssets"
+      BeforeTargets="GenerateBuildDependencyFile;GeneratePublishDependencyFile;ILLink;ResolveLockFileReferences"
+      DependsOnTargets="ResolvePackageAssets">
+    <Error Condition=" !EXISTS('$(RepoRoot)artifacts\obj\RepoTasks\RepoTasks.csproj.nuget.g.props') "
+        Text="The eng/tools/RepoTasks project must be restored before building other projects." />
+
+    <JoinItems Left="@(ResolvedCompileFileDefinitions)"
+        Right="@(LatestPackageReference->HasMetadata('RTMVersion'))"
+        LeftKey="Filename"
+        ItemSpecToUse="Left"
+        LeftMetadata="*"
+        RightMetadata="RTMVersion;Version">
+      <Output TaskParameter="JoinResult" ItemName="_ResolvedCompileFileDefinitionsToChange" />
+    </JoinItems>
+
+    <ItemGroup>
+      <ResolvedCompileFileDefinitions Remove="@(_ResolvedCompileFileDefinitionsToChange)" />
+
+      <!-- Ignore %(NuGetPackageVersion) when doing substitution because some projects use downlevel packages. -->
+      <_ResolvedCompileFileDefinitionsToChange
+          HintPath="$([System.String]::new('%(Identity)').Replace('\%(Version)\', '\%(RTMVersion)\').Replace('/%(Version)/', '/%(RTMVersion)/'))" />
+      <ResolvedCompileFileDefinitions Include="@(_ResolvedCompileFileDefinitionsToChange -> '%(HintPath)')" />
+
+      <_ResolvedCompileFileDefinitionsToChange Remove="@(_ResolvedCompileFileDefinitionsToChange)" />
+    </ItemGroup>
+  </Target>
+
   <PropertyGroup>
     <_CompileTfmUsingReferenceAssemblies>false</_CompileTfmUsingReferenceAssemblies>
     <_CompileTfmUsingReferenceAssemblies
         Condition=" '$(CompileUsingReferenceAssemblies)' != false AND '$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)' ">true</_CompileTfmUsingReferenceAssemblies>
   </PropertyGroup>
+
   <!--
     If we have a ref/ assembly from dotnet/runtime for an Extension package, use that when compiling but do not reference its assemblies.
   -->
-  <ItemGroup
-      Condition=" $(_CompileTfmUsingReferenceAssemblies) OR ('$(IsTargetingPackBuilding)' != 'false' AND '$(MSBuildProjectName)' == 'Microsoft.AspNetCore.App.Ref') ">
+  <ItemGroup Condition=" '$(MSBuildProjectName)' != 'Microsoft.AspNetCore.App.Runtime' AND
+      ($(_CompileTfmUsingReferenceAssemblies) OR
+       ('$(IsTargetingPackBuilding)' != 'false' AND '$(MSBuildProjectName)' == 'Microsoft.AspNetCore.App.Ref')) ">
     <PackageReference Include="Microsoft.Extensions.Internal.Transport"
         Version="$(MicrosoftExtensionsInternalTransportVersion)"
         IsImplicitlyDefined="true"
@@ -266,6 +307,30 @@
         GeneratePathProperty="true" />
   </ItemGroup>
 
+  <!--
+    Remove compile-time assets for packages that overlap Microsoft.Extensions.Internal.Transport. Serviced packages
+    may otherwise increase the referenced version. Avoid this because change reduces compatible runtime versions.
+    That's not a big deal within the shared framework but can cause problems for shipped packages. Leave test
+    projects and Ignitor alone because they may transitively reference newer netstandard assemblies and need a
+    net5.0 assembly with the same version. (This can happen in implementation projects but is less likely.)
+  -->
+  <Target Name="RemoveExtensionsCompileAssets"
+      AfterTargets="ResolvePackageAssets"
+      Condition=" '$(PkgMicrosoft_Extensions_Internal_Transport)' != '' AND
+          '$(IsServicingBuild)' == 'true' AND
+          '$(IsImplementationProject)' == 'true' AND
+          '$(MSBuildProjectName)' != 'Ignitor' AND
+          '$(MSBuildProjectName)' != 'Microsoft.AspNetCore.App.Runtime' AND
+          ($(_CompileTfmUsingReferenceAssemblies) OR
+           ('$(IsTargetingPackBuilding)' != 'false' AND '$(MSBuildProjectName)' == 'Microsoft.AspNetCore.App.Ref')) ">
+    <ItemGroup>
+      <ResolvedCompileFileDefinitions Remove="@(ResolvedCompileFileDefinitions)"
+          Condition=" '%(NuGetPackageId)' != 'Microsoft.Extensions.Internal.Transport' AND
+              EXISTS('$(PkgMicrosoft_Extensions_Internal_Transport)\ref\$(TargetFramework)\%(Filename).dll') AND
+              $([System.String]::new('%(Directory)').Contains('$(TargetFramework)')) " />
+    </ItemGroup>
+  </Target>
+
   <!-- These targets are used to generate the map of assembly name to project files. See also the /t:GenerateProjectList target in build/repo.targets. -->
   <Target Name="GetReferencesProvided" Returns="@(ProvidesReference)">
     <ItemGroup>

+ 10 - 0
eng/tools/RepoTasks/RepoTasks.csproj

@@ -15,6 +15,16 @@
   <ItemGroup>
     <PackageReference Include="NuGet.Packaging" Version="5.6.0" />
     <PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.1.0" />
+
+    <!--
+      Gather project references for compilation against RTM packages. %(RTMVersion) is set for about a dozen packages
+      in all servicing builds. Cannot reference two versions of a package, mandating this separation from projects
+      using the relevant packages.
+    -->
+    <PackageReference Include="@(LatestPackageReference->HasMetadata('RTMVersion'))"
+        IncludeAssets="None"
+        PrivateAssets="All"
+        Version="%(RTMVersion)" />
   </ItemGroup>
 
   <ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">

+ 8 - 1
src/Framework/test/Microsoft.AspNetCore.App.UnitTests.csproj

@@ -9,7 +9,10 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <_ExpectedSharedFrameworkBinaries Include="@(AspNetCoreAppReference);@(AspNetCoreAppReferenceAndPackage);@(ExternalAspNetCoreAppReference);@(_TransitiveExternalAspNetCoreAppReference)" />
+    <!-- Ignore aspnetcorev2_inprocess because tests expect only managed assemblies in this item group. -->
+    <_SharedFrameworkBinariesFromRepo Include="@(AspNetCoreAppReference);@(AspNetCoreAppReferenceAndPackage)" />
+
+    <_ExpectedSharedFrameworkBinaries Include="@(_SharedFrameworkBinariesFromRepo);@(ExternalAspNetCoreAppReference);@(_TransitiveExternalAspNetCoreAppReference)" />
     <_ExpectedSharedFrameworkBinaries Condition="'$(TargetOsName)' == 'win' AND '$(TargetArchitecture)' != 'arm'" Include="aspnetcorev2_inprocess" />
 
     <AssemblyAttribute Include="Microsoft.AspNetCore.TestData">
@@ -28,6 +31,10 @@
       <_Parameter1>MicrosoftNETCoreAppRuntimeVersion</_Parameter1>
       <_Parameter2>$(MicrosoftNETCoreAppRuntimeVersion)</_Parameter2>
     </AssemblyAttribute>
+    <AssemblyAttribute Include="Microsoft.AspNetCore.TestData">
+      <_Parameter1>SharedFrameworkBinariesFromRepo</_Parameter1>
+      <_Parameter2>@(_SharedFrameworkBinariesFromRepo)</_Parameter2>
+    </AssemblyAttribute>
     <AssemblyAttribute Include="Microsoft.AspNetCore.TestData">
       <_Parameter1>SharedFxDependencies</_Parameter1>
       <_Parameter2>@(_ExpectedSharedFrameworkBinaries)</_Parameter2>

+ 34 - 4
src/Framework/test/SharedFxTests.cs

@@ -32,7 +32,9 @@ namespace Microsoft.AspNetCore
             _sharedFxRoot = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ASPNET_RUNTIME_PATH"))
                 ? Path.Combine(TestData.GetTestDataValue("SharedFrameworkLayoutRoot"), "shared", "Microsoft.AspNetCore.App", TestData.GetTestDataValue("RuntimePackageVersion"))
                 : Environment.GetEnvironmentVariable("ASPNET_RUNTIME_PATH");
-            _expectedVersionFileName = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ASPNET_RUNTIME_PATH")) ? ".version" : "Microsoft.AspNetCore.App.versions.txt";
+            _expectedVersionFileName = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ASPNET_RUNTIME_PATH"))
+                ? ".version"
+                : "Microsoft.AspNetCore.App.versions.txt";
         }
 
         [Fact]
@@ -164,31 +166,58 @@ namespace Microsoft.AspNetCore
         [Fact]
         public void SharedFrameworkAssembliesHaveExpectedAssemblyVersions()
         {
-            // Only test managed assemblies
-            IEnumerable<string> dlls = Directory.GetFiles(_sharedFxRoot, "*.dll", SearchOption.AllDirectories).Where(i => !i.Contains("aspnetcorev2_inprocess"));
+            // Only test managed assemblies from dotnet/aspnetcore.
+            var repoAssemblies = TestData.GetSharedFrameworkBinariesFromRepo()
+                .Split(';', StringSplitOptions.RemoveEmptyEntries)
+                .ToHashSet();
+
+            var versionStringWithoutPrereleaseTag = TestData.GetMicrosoftNETCoreAppPackageVersion().Split('-', 2)[0];
+            var version = Version.Parse(versionStringWithoutPrereleaseTag);
+            var dlls = Directory.GetFiles(_sharedFxRoot, "*.dll", SearchOption.AllDirectories);
             Assert.NotEmpty(dlls);
 
             Assert.All(dlls, path =>
             {
+                // Unlike dotnet/aspnetcore, dotnet/runtime varies the assembly version while in servicing.
+                if (!repoAssemblies.Contains(Path.GetFileNameWithoutExtension(path)))
+                {
+                    return;
+                }
+
                 using var fileStream = File.OpenRead(path);
                 using var peReader = new PEReader(fileStream, PEStreamOptions.Default);
                 var reader = peReader.GetMetadataReader(MetadataReaderOptions.Default);
                 var assemblyDefinition = reader.GetAssemblyDefinition();
 
                 // Assembly versions should all match Major.Minor.0.0
+                Assert.Equal(version.Major, assemblyDefinition.Version.Major);
+                Assert.Equal(version.Minor, assemblyDefinition.Version.Minor);
                 Assert.Equal(0, assemblyDefinition.Version.Build);
                 Assert.Equal(0, assemblyDefinition.Version.Revision);
             });
         }
 
+        // ASP.NET Core shared Fx assemblies should reference only ASP.NET Core assemblies with Revsion == 0.
         [Fact]
         public void SharedFrameworkAssemblyReferencesHaveExpectedAssemblyVersions()
         {
-            IEnumerable<string> dlls = Directory.GetFiles(_sharedFxRoot, "*.dll", SearchOption.AllDirectories).Where(i => !i.Contains("aspnetcorev2_inprocess") && !i.Contains("System.Security.Cryptography.Xml", StringComparison.OrdinalIgnoreCase));
+            // Only test managed assemblies from dotnet/aspnetcore.
+            var repoAssemblies = TestData.GetSharedFrameworkBinariesFromRepo()
+                .Split(';', StringSplitOptions.RemoveEmptyEntries)
+                .ToHashSet();
+
+            IEnumerable<string> dlls = Directory.GetFiles(_sharedFxRoot, "*.dll", SearchOption.AllDirectories);
             Assert.NotEmpty(dlls);
 
             Assert.All(dlls, path =>
             {
+                // Unlike dotnet/aspnetcore, dotnet/runtime varies the assembly version while in servicing.
+                // dotnet/aspnetcore assemblies build against RTM targeting pack from dotnet/runtime.
+                if (!repoAssemblies.Contains(Path.GetFileNameWithoutExtension(path)))
+                {
+                    return;
+                }
+
                 using var fileStream = File.OpenRead(path);
                 using var peReader = new PEReader(fileStream, PEStreamOptions.Default);
                 var reader = peReader.GetMetadataReader(MetadataReaderOptions.Default);
@@ -196,6 +225,7 @@ namespace Microsoft.AspNetCore
                 Assert.All(reader.AssemblyReferences, handle =>
                 {
                     var reference = reader.GetAssemblyReference(handle);
+                    Assert.Equal(0, reference.Version.Build);
                     Assert.Equal(0, reference.Version.Revision);
                 });
             });

+ 5 - 1
src/Framework/test/TestData.cs

@@ -8,9 +8,10 @@ using System.Reflection;
 
 namespace Microsoft.AspNetCore
 {
-    public class TestData
+    public static class TestData
     {
         public static List<string> ListedSharedFxAssemblies;
+
         public static SortedDictionary<string, string> ListedTargetingPackAssemblies;
 
         static TestData()
@@ -149,6 +150,7 @@ namespace Microsoft.AspNetCore
                 "System.Security.Permissions",
                 "System.Windows.Extensions"
             };
+
             ListedTargetingPackAssemblies = new SortedDictionary<string, string>
             {
                 { "Microsoft.AspNetCore", "6.0.0.0" },
@@ -302,6 +304,8 @@ namespace Microsoft.AspNetCore
 
         public static string GetSharedFxRuntimeIdentifier() => GetTestDataValue("TargetRuntimeIdentifier");
 
+        public static string GetSharedFrameworkBinariesFromRepo() => GetTestDataValue("SharedFrameworkBinariesFromRepo");
+
         public static string GetSharedFxDependencies() => GetTestDataValue("SharedFxDependencies");
 
         public static string GetTargetingPackDependencies() => GetTestDataValue("TargetingPackDependencies");

+ 2 - 2
src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/App.razor

@@ -1,5 +1,5 @@
 @*#if (NoAuth)
-<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="true">
+<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
     <Found Context="routeData">
         <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
     </Found>
@@ -11,7 +11,7 @@
 </Router>
 #else
 <CascadingAuthenticationState>
-    <Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="true">
+    <Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
         <Found Context="routeData">
             <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
         </Found>

+ 2 - 2
src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/App.razor

@@ -1,5 +1,5 @@
 @*#if (NoAuth)
-<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="true">
+<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
     <Found Context="routeData">
         <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
     </Found>
@@ -11,7 +11,7 @@
 </Router>
 #else
 <CascadingAuthenticationState>
-    <Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="true">
+    <Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
         <Found Context="routeData">
             <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                 <NotAuthorized>