From 6eef47d31706238f291d31616fb1b7546cdcef33 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2019 17:44:16 +0000 Subject: [PATCH] [master] Update dependencies from dotnet/arcade aspnet/Extensions (#16370) * Update dependencies from https://github.com/dotnet/arcade build 20190630.1 - Microsoft.DotNet.Arcade.Sdk - 1.0.0-beta.19330.1 * Update dependencies from https://github.com/aspnet/Extensions build 20190701.1 - Microsoft.Extensions.DependencyInjection - 3.0.0-preview7.19351.1 - Microsoft.Extensions.Configuration.Json - 3.0.0-preview7.19351.1 - Microsoft.Extensions.Configuration.EnvironmentVariables - 3.0.0-preview7.19351.1 - Microsoft.Extensions.Configuration - 3.0.0-preview7.19351.1 - Microsoft.Extensions.Caching.Memory - 3.0.0-preview7.19351.1 - Microsoft.Extensions.HostFactoryResolver.Sources - 3.0.0-preview7.19351.1 - Microsoft.Extensions.Logging - 3.0.0-preview7.19351.1 * Update dependencies from https://github.com/aspnet/Extensions build 20190701.2 - Microsoft.Extensions.DependencyInjection - 3.0.0-preview8.19351.2 - Microsoft.Extensions.Configuration.Json - 3.0.0-preview8.19351.2 - Microsoft.Extensions.Configuration.EnvironmentVariables - 3.0.0-preview8.19351.2 - Microsoft.Extensions.Configuration - 3.0.0-preview8.19351.2 - Microsoft.Extensions.Caching.Memory - 3.0.0-preview8.19351.2 - Microsoft.Extensions.HostFactoryResolver.Sources - 3.0.0-preview8.19351.2 - Microsoft.Extensions.Logging - 3.0.0-preview8.19351.2 * Update dependencies from https://github.com/aspnet/Extensions build 20190701.4 - Microsoft.Extensions.DependencyInjection - 3.0.0-preview8.19351.4 - Microsoft.Extensions.Configuration.Json - 3.0.0-preview8.19351.4 - Microsoft.Extensions.Configuration.EnvironmentVariables - 3.0.0-preview8.19351.4 - Microsoft.Extensions.Configuration - 3.0.0-preview8.19351.4 - Microsoft.Extensions.Caching.Memory - 3.0.0-preview8.19351.4 - Microsoft.Extensions.HostFactoryResolver.Sources - 3.0.0-preview8.19351.4 - Microsoft.Extensions.Logging - 3.0.0-preview8.19351.4 Dependency coherency updates - Microsoft.CSharp - 4.6.0-preview8.19351.3 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-07 (parent: Microsoft.Extensions.Logging) - Microsoft.DotNet.PlatformAbstractions - 3.0.0-preview8-27901-07 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.DependencyModel - 3.0.0-preview8-27901-07 (parent: Microsoft.Extensions.Logging) - Microsoft.NETCore.Platforms - 3.0.0-preview8.19351.3 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-07 (parent: Microsoft.Extensions.Logging) - Microsoft.NETCore.App.Ref - 3.0.0-preview8-27901-07 (parent: Microsoft.Extensions.Logging) - NETStandard.Library.Ref - 2.1.0-preview8-27901-07 (parent: Microsoft.Extensions.Logging) - System.Collections.Immutable - 1.6.0-preview8.19351.3 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-07 (parent: Microsoft.Extensions.Logging) - System.ComponentModel.Annotations - 4.6.0-preview8.19351.3 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-07 (parent: Microsoft.Extensions.Logging) - System.Diagnostics.DiagnosticSource - 4.6.0-preview8.19351.3 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-07 (parent: Microsoft.Extensions.Logging) * Update dependencies from https://github.com/aspnet/Extensions build 20190701.5 - Microsoft.Extensions.DependencyInjection - 3.0.0-preview8.19351.5 - Microsoft.Extensions.Configuration.Json - 3.0.0-preview8.19351.5 - Microsoft.Extensions.Configuration.EnvironmentVariables - 3.0.0-preview8.19351.5 - Microsoft.Extensions.Configuration - 3.0.0-preview8.19351.5 - Microsoft.Extensions.Caching.Memory - 3.0.0-preview8.19351.5 - Microsoft.Extensions.HostFactoryResolver.Sources - 3.0.0-preview8.19351.5 - Microsoft.Extensions.Logging - 3.0.0-preview8.19351.5 Dependency coherency updates - Microsoft.CSharp - 4.6.0-preview8.19351.5 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-08 (parent: Microsoft.Extensions.Logging) - Microsoft.DotNet.PlatformAbstractions - 3.0.0-preview8-27901-08 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.DependencyModel - 3.0.0-preview8-27901-08 (parent: Microsoft.Extensions.Logging) - Microsoft.NETCore.Platforms - 3.0.0-preview8.19351.5 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-08 (parent: Microsoft.Extensions.Logging) - Microsoft.NETCore.App.Ref - 3.0.0-preview8-27901-08 (parent: Microsoft.Extensions.Logging) - NETStandard.Library.Ref - 2.1.0-preview8-27901-08 (parent: Microsoft.Extensions.Logging) - System.Collections.Immutable - 1.6.0-preview8.19351.5 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-08 (parent: Microsoft.Extensions.Logging) - System.ComponentModel.Annotations - 4.6.0-preview8.19351.5 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-08 (parent: Microsoft.Extensions.Logging) - System.Diagnostics.DiagnosticSource - 4.6.0-preview8.19351.5 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-08 (parent: Microsoft.Extensions.Logging) * Update dependencies from https://github.com/aspnet/Extensions build 20190701.6 - Microsoft.Extensions.DependencyInjection - 3.0.0-preview8.19351.6 - Microsoft.Extensions.Configuration.Json - 3.0.0-preview8.19351.6 - Microsoft.Extensions.Configuration.EnvironmentVariables - 3.0.0-preview8.19351.6 - Microsoft.Extensions.Configuration - 3.0.0-preview8.19351.6 - Microsoft.Extensions.Caching.Memory - 3.0.0-preview8.19351.6 - Microsoft.Extensions.HostFactoryResolver.Sources - 3.0.0-preview8.19351.6 - Microsoft.Extensions.Logging - 3.0.0-preview8.19351.6 Dependency coherency updates - Microsoft.CSharp - 4.6.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - Microsoft.DotNet.PlatformAbstractions - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.DependencyModel - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - Microsoft.NETCore.Platforms - 3.0.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - Microsoft.NETCore.App.Ref - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - NETStandard.Library.Ref - 2.1.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - System.Collections.Immutable - 1.6.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - System.ComponentModel.Annotations - 4.6.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - System.Diagnostics.DiagnosticSource - 4.6.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) * Update dependencies from https://github.com/aspnet/Extensions build 20190702.1 - Microsoft.Extensions.DependencyInjection - 3.0.0-preview8.19352.1 - Microsoft.Extensions.Configuration.Json - 3.0.0-preview8.19352.1 - Microsoft.Extensions.Configuration.EnvironmentVariables - 3.0.0-preview8.19352.1 - Microsoft.Extensions.Configuration - 3.0.0-preview8.19352.1 - Microsoft.Extensions.Caching.Memory - 3.0.0-preview8.19352.1 - Microsoft.Extensions.HostFactoryResolver.Sources - 3.0.0-preview8.19352.1 - Microsoft.Extensions.Logging - 3.0.0-preview8.19352.1 Dependency coherency updates - Microsoft.CSharp - 4.6.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - Microsoft.DotNet.PlatformAbstractions - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.DependencyModel - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - Microsoft.NETCore.Platforms - 3.0.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - Microsoft.NETCore.App.Ref - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - NETStandard.Library.Ref - 2.1.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - System.Collections.Immutable - 1.6.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - System.ComponentModel.Annotations - 4.6.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - System.Diagnostics.DiagnosticSource - 4.6.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) * Update dependencies from https://github.com/aspnet/Extensions build 20190702.2 - Microsoft.Extensions.DependencyInjection - 3.0.0-preview8.19352.2 - Microsoft.Extensions.Configuration.Json - 3.0.0-preview8.19352.2 - Microsoft.Extensions.Configuration.EnvironmentVariables - 3.0.0-preview8.19352.2 - Microsoft.Extensions.Configuration - 3.0.0-preview8.19352.2 - Microsoft.Extensions.Caching.Memory - 3.0.0-preview8.19352.2 - Microsoft.Extensions.HostFactoryResolver.Sources - 3.0.0-preview8.19352.2 - Microsoft.Extensions.Logging - 3.0.0-preview8.19352.2 Dependency coherency updates - Microsoft.CSharp - 4.6.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - Microsoft.DotNet.PlatformAbstractions - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.DependencyModel - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - Microsoft.NETCore.Platforms - 3.0.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - Microsoft.NETCore.App.Ref - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - NETStandard.Library.Ref - 2.1.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - System.Collections.Immutable - 1.6.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - System.ComponentModel.Annotations - 4.6.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) - System.Diagnostics.DiagnosticSource - 4.6.0-preview8.19351.6 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27901-10 (parent: Microsoft.Extensions.Logging) * Update dependencies from https://github.com/aspnet/Extensions build 20190702.3 - Microsoft.Extensions.DependencyInjection - 3.0.0-preview8.19352.3 - Microsoft.Extensions.Configuration.Json - 3.0.0-preview8.19352.3 - Microsoft.Extensions.Configuration.EnvironmentVariables - 3.0.0-preview8.19352.3 - Microsoft.Extensions.Configuration - 3.0.0-preview8.19352.3 - Microsoft.Extensions.Caching.Memory - 3.0.0-preview8.19352.3 - Microsoft.Extensions.HostFactoryResolver.Sources - 3.0.0-preview8.19352.3 - Microsoft.Extensions.Logging - 3.0.0-preview8.19352.3 Dependency coherency updates - Microsoft.CSharp - 4.6.0-preview8.19352.1 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27902-02 (parent: Microsoft.Extensions.Logging) - Microsoft.DotNet.PlatformAbstractions - 3.0.0-preview8-27902-02 (parent: Microsoft.Extensions.Logging) - Microsoft.Extensions.DependencyModel - 3.0.0-preview8-27902-02 (parent: Microsoft.Extensions.Logging) - Microsoft.NETCore.Platforms - 3.0.0-preview8.19352.1 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27902-02 (parent: Microsoft.Extensions.Logging) - Microsoft.NETCore.App.Ref - 3.0.0-preview8-27902-02 (parent: Microsoft.Extensions.Logging) - NETStandard.Library.Ref - 2.1.0-preview8-27902-02 (parent: Microsoft.Extensions.Logging) - System.Collections.Immutable - 1.6.0-preview8.19352.1 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27902-02 (parent: Microsoft.Extensions.Logging) - System.ComponentModel.Annotations - 4.6.0-preview8.19352.1 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27902-02 (parent: Microsoft.Extensions.Logging) - System.Diagnostics.DiagnosticSource - 4.6.0-preview8.19352.1 (parent: Microsoft.NETCore.App.Runtime.win-x64) - Microsoft.NETCore.App.Runtime.win-x64 - 3.0.0-preview8-27902-02 (parent: Microsoft.Extensions.Logging) * Update nullability convention to new nullability metadata See https://github.com/dotnet/roslyn/blob/master/docs/features/nullable-metadata.md. Makes #16370 pass. --- eng/Version.Details.xml | 72 ++++---- eng/Versions.props | 34 ++-- eng/common/SigningValidation.proj | 30 ++-- eng/common/post-build/nuget-validation.ps1 | 28 +++ eng/common/post-build/promote-build.ps1 | 53 ++++++ .../post-build/trigger-subscriptions.ps1 | 69 +++++++ eng/common/sdl/extract-artifact-packages.ps1 | 70 ++++++++ eng/common/sdl/packages.config | 2 +- eng/common/templates/job/execute-sdl.yml | 12 +- .../templates/job/publish-build-assets.yml | 1 - .../channels/internal-servicing.yml | 170 ++++++++++++++++++ .../channels/public-dev-release.yml | 59 ++++-- .../post-build/channels/public-release.yml | 170 ++++++++++++++++++ .../channels/public-validation-release.yml | 52 ++++-- .../templates/post-build/common-variables.yml | 9 + .../templates/post-build/post-build.yml | 24 +++ .../templates/post-build/promote-build.yml | 12 +- .../post-build/setup-maestro-vars.yml | 4 +- .../post-build/trigger-subscription.yml | 11 ++ global.json | 2 +- .../ProviderConventionSetBuilder.cs | 6 +- .../Conventions/NonNullableConventionBase.cs | 119 ++++++++++-- .../NonNullableNavigationConvention.cs | 11 +- .../NonNullableReferencePropertyConvention.cs | 2 +- 24 files changed, 883 insertions(+), 139 deletions(-) create mode 100644 eng/common/post-build/nuget-validation.ps1 create mode 100644 eng/common/post-build/promote-build.ps1 create mode 100644 eng/common/post-build/trigger-subscriptions.ps1 create mode 100644 eng/common/sdl/extract-artifact-packages.ps1 create mode 100644 eng/common/templates/post-build/channels/internal-servicing.yml create mode 100644 eng/common/templates/post-build/channels/public-release.yml create mode 100644 eng/common/templates/post-build/trigger-subscription.yml diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8496ec92b6a..15ee387dd18 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,79 +1,79 @@ - + https://github.com/dotnet/corefx - 72da80db3fd14b84fefeef54ac0930c711f306f4 + ec138afba514ce9b53d931d66129e02e8be147a1 - + https://github.com/dotnet/core-setup - ee0c7ead1a46f06f98aff9102b785f532b71da9c + d31c9e8055992b61f4a1b8898b646e5fcb7b62b3 - + https://github.com/aspnet/Extensions - 531db4e313e577192cdbca3931c4298b6db1e611 + 57863aedad5bac2e109345a70fa4de2acfebf34e - + https://github.com/aspnet/Extensions - 531db4e313e577192cdbca3931c4298b6db1e611 + 57863aedad5bac2e109345a70fa4de2acfebf34e - + https://github.com/aspnet/Extensions - 531db4e313e577192cdbca3931c4298b6db1e611 + 57863aedad5bac2e109345a70fa4de2acfebf34e - + https://github.com/aspnet/Extensions - 531db4e313e577192cdbca3931c4298b6db1e611 + 57863aedad5bac2e109345a70fa4de2acfebf34e - + https://github.com/aspnet/Extensions - 531db4e313e577192cdbca3931c4298b6db1e611 + 57863aedad5bac2e109345a70fa4de2acfebf34e - + https://github.com/dotnet/core-setup - ee0c7ead1a46f06f98aff9102b785f532b71da9c + d31c9e8055992b61f4a1b8898b646e5fcb7b62b3 - + https://github.com/aspnet/Extensions - 531db4e313e577192cdbca3931c4298b6db1e611 + 57863aedad5bac2e109345a70fa4de2acfebf34e - + https://github.com/aspnet/Extensions - 531db4e313e577192cdbca3931c4298b6db1e611 + 57863aedad5bac2e109345a70fa4de2acfebf34e - + https://github.com/dotnet/corefx - 72da80db3fd14b84fefeef54ac0930c711f306f4 + ec138afba514ce9b53d931d66129e02e8be147a1 - + https://github.com/dotnet/core-setup - ee0c7ead1a46f06f98aff9102b785f532b71da9c + d31c9e8055992b61f4a1b8898b646e5fcb7b62b3 - + https://github.com/dotnet/core-setup - ee0c7ead1a46f06f98aff9102b785f532b71da9c + d31c9e8055992b61f4a1b8898b646e5fcb7b62b3 - + https://github.com/dotnet/core-setup - ee0c7ead1a46f06f98aff9102b785f532b71da9c + d31c9e8055992b61f4a1b8898b646e5fcb7b62b3 - + https://github.com/dotnet/corefx - 72da80db3fd14b84fefeef54ac0930c711f306f4 + ec138afba514ce9b53d931d66129e02e8be147a1 - + https://github.com/dotnet/corefx - 72da80db3fd14b84fefeef54ac0930c711f306f4 + ec138afba514ce9b53d931d66129e02e8be147a1 - + https://github.com/dotnet/corefx - 72da80db3fd14b84fefeef54ac0930c711f306f4 + ec138afba514ce9b53d931d66129e02e8be147a1 - + https://github.com/dotnet/arcade - 9946534da4f73e6242ca105f6798ab58119c9ab0 + 89fab80685c91024c8f9e21f1c37f62580f648f8 diff --git a/eng/Versions.props b/eng/Versions.props index e0e0280c024..26cf3ec9560 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -28,27 +28,27 @@ 1.0.19128.1-Preview - 3.0.0-preview7.19328.2 - 3.0.0-preview7.19328.2 - 3.0.0-preview7.19328.2 - 3.0.0-preview7.19328.2 - 3.0.0-preview7.19328.2 - 3.0.0-preview7.19328.2 - 3.0.0-preview7.19328.2 + 3.0.0-preview8.19352.3 + 3.0.0-preview8.19352.3 + 3.0.0-preview8.19352.3 + 3.0.0-preview8.19352.3 + 3.0.0-preview8.19352.3 + 3.0.0-preview8.19352.3 + 3.0.0-preview8.19352.3 - 4.6.0-preview7.19326.13 - 3.0.0-preview7.19326.13 - 1.6.0-preview7.19326.13 - 4.6.0-preview7.19326.13 - 4.6.0-preview7.19326.13 + 4.6.0-preview8.19352.1 + 3.0.0-preview8.19352.1 + 1.6.0-preview8.19352.1 + 4.6.0-preview8.19352.1 + 4.6.0-preview8.19352.1 - 3.0.0-preview7-27826-20 - 3.0.0-preview7-27826-20 - 3.0.0-preview7-27826-20 - 3.0.0-preview7-27826-20 - 2.1.0-preview7-27826-20 + 3.0.0-preview8-27902-02 + 3.0.0-preview8-27902-02 + 3.0.0-preview8-27902-02 + 3.0.0-preview8-27902-02 + 2.1.0-preview8-27902-02 - - - + diff --git a/eng/common/post-build/nuget-validation.ps1 b/eng/common/post-build/nuget-validation.ps1 new file mode 100644 index 00000000000..1bdced1e307 --- /dev/null +++ b/eng/common/post-build/nuget-validation.ps1 @@ -0,0 +1,28 @@ +# This script validates NuGet package metadata information using this +# tool: https://github.com/NuGet/NuGetGallery/tree/jver-verify/src/VerifyMicrosoftPackage + +param( + [Parameter(Mandatory=$true)][string] $PackagesPath, # Path to where the packages to be validated are + [Parameter(Mandatory=$true)][string] $ToolDestinationPath # Where the validation tool should be downloaded to +) + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version 2.0 + +. $PSScriptRoot\..\tools.ps1 + +try { + $url = "https://raw.githubusercontent.com/NuGet/NuGetGallery/jver-verify/src/VerifyMicrosoftPackage/verify.ps1" + + New-Item -ItemType "directory" -Path ${ToolDestinationPath} -Force + + Invoke-WebRequest $url -OutFile ${ToolDestinationPath}\verify.ps1 + + & ${ToolDestinationPath}\verify.ps1 ${PackagesPath}\*.nupkg +} +catch { + Write-PipelineTaskError "NuGet package validation failed. Please check error logs." + Write-Host $_ + Write-Host $_.ScriptStackTrace + ExitWithExitCode 1 +} diff --git a/eng/common/post-build/promote-build.ps1 b/eng/common/post-build/promote-build.ps1 new file mode 100644 index 00000000000..84a608fa569 --- /dev/null +++ b/eng/common/post-build/promote-build.ps1 @@ -0,0 +1,53 @@ +param( + [Parameter(Mandatory=$true)][int] $BuildId, + [Parameter(Mandatory=$true)][int] $ChannelId, + [Parameter(Mandatory=$true)][string] $BarToken, + [string] $MaestroEndpoint = "https://maestro-prod.westus2.cloudapp.azure.com", + [string] $ApiVersion = "2019-01-16" +) + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version 2.0 + +. $PSScriptRoot\..\tools.ps1 + +function Get-Headers([string]$accept, [string]$barToken) { + $headers = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' + $headers.Add('Accept',$accept) + $headers.Add('Authorization',"Bearer $barToken") + return $headers +} + +try { + $maestroHeaders = Get-Headers 'application/json' $BarToken + + # Get info about which channels the build has already been promoted to + $getBuildApiEndpoint = "$MaestroEndpoint/api/builds/${BuildId}?api-version=$ApiVersion" + $buildInfo = Invoke-WebRequest -Method Get -Uri $getBuildApiEndpoint -Headers $maestroHeaders | ConvertFrom-Json + + if (!$buildInfo) { + Write-Host "Build with BAR ID $BuildId was not found in BAR!" + ExitWithExitCode 1 + } + + # Find whether the build is already assigned to the channel or not + if ($buildInfo.channels) { + foreach ($channel in $buildInfo.channels) { + if ($channel.Id -eq $ChannelId) { + Write-Host "The build with BAR ID $BuildId is already on channel $ChannelId!" + ExitWithExitCode 0 + } + } + } + + Write-Host "Build not present in channel $ChannelId. Promoting build ... " + + $promoteBuildApiEndpoint = "$maestroEndpoint/api/channels/${ChannelId}/builds/${BuildId}?api-version=$ApiVersion" + Invoke-WebRequest -Method Post -Uri $promoteBuildApiEndpoint -Headers $maestroHeaders + Write-Host "done." +} +catch { + Write-Host "There was an error while trying to promote build '$BuildId' to channel '$ChannelId'" + Write-Host $_ + Write-Host $_.ScriptStackTrace +} diff --git a/eng/common/post-build/trigger-subscriptions.ps1 b/eng/common/post-build/trigger-subscriptions.ps1 new file mode 100644 index 00000000000..db8a839457a --- /dev/null +++ b/eng/common/post-build/trigger-subscriptions.ps1 @@ -0,0 +1,69 @@ +param( + [Parameter(Mandatory=$true)][string] $SourceRepo, + [Parameter(Mandatory=$true)][int] $ChannelId, + [string] $MaestroEndpoint = "https://maestro-prod.westus2.cloudapp.azure.com", + [string] $BarToken, + [string] $ApiVersion = "2019-01-16" +) + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version 2.0 + +. $PSScriptRoot\..\tools.ps1 + +function Get-Headers([string]$accept, [string]$barToken) { + $headers = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' + $headers.Add('Accept',$accept) + $headers.Add('Authorization',"Bearer $barToken") + return $headers +} + +# Get all the $SourceRepo subscriptions +$normalizedSurceRepo = $SourceRepo.Replace('dnceng@', '') +$getSubscriptionsApiEndpoint = "$maestroEndpoint/api/subscriptions?sourceRepository=$normalizedSurceRepo&api-version=$apiVersion" +$headers = Get-Headers 'application/json' $barToken + +$subscriptions = Invoke-WebRequest -Uri $getSubscriptionsApiEndpoint -Headers $headers | ConvertFrom-Json + +if (!$subscriptions) { + Write-Host "No subscriptions found for source repo '$normalizedSurceRepo' in channel '$ChannelId'" + return +} + +$subscriptionsToTrigger = New-Object System.Collections.Generic.List[string] +$failedTriggeredSubscription = $false + +# Get all enabled subscriptions that need dependency flow on 'everyBuild' +foreach ($subscription in $subscriptions) { + if ($subscription.enabled -and $subscription.policy.updateFrequency -like 'everyBuild' -and $subscription.channel.id -eq $ChannelId) { + Write-Host "$subscription.id" + [void]$subscriptionsToTrigger.Add($subscription.id) + } +} + +foreach ($subscriptionToTrigger in $subscriptionsToTrigger) { + try { + $triggerSubscriptionApiEndpoint = "$maestroEndpoint/api/subscriptions/$subscriptionToTrigger/trigger?api-version=$apiVersion" + $headers = Get-Headers 'application/json' $BarToken + + Write-Host "Triggering subscription '$subscriptionToTrigger'..." + + Invoke-WebRequest -Uri $triggerSubscriptionApiEndpoint -Headers $headers -Method Post + + Write-Host "Subscription '$subscriptionToTrigger' triggered!" + } + catch + { + Write-Host "There was an error while triggering subscription '$subscriptionToTrigger'" + Write-Host $_ + Write-Host $_.ScriptStackTrace + $failedTriggeredSubscription = $true + } +} + +if ($failedTriggeredSubscription) { + Write-Host "At least one subscription failed to be triggered..." + ExitWithExitCode 1 +} + +Write-Host "All subscriptions were triggered successfully!" diff --git a/eng/common/sdl/extract-artifact-packages.ps1 b/eng/common/sdl/extract-artifact-packages.ps1 new file mode 100644 index 00000000000..1fdbb14329c --- /dev/null +++ b/eng/common/sdl/extract-artifact-packages.ps1 @@ -0,0 +1,70 @@ +param( + [Parameter(Mandatory=$true)][string] $InputPath, # Full path to directory where artifact packages are stored + [Parameter(Mandatory=$true)][string] $ExtractPath # Full path to directory where the packages will be extracted +) + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version 2.0 +$ExtractPackage = { + param( + [string] $PackagePath # Full path to a NuGet package + ) + + if (!(Test-Path $PackagePath)) { + Write-PipelineTaskError "Input file does not exist: $PackagePath" + ExitWithExitCode 1 + } + + $RelevantExtensions = @(".dll", ".exe", ".pdb") + Write-Host -NoNewLine "Extracting" ([System.IO.Path]::GetFileName($PackagePath)) "... " + + $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath) + $ExtractPath = Join-Path -Path $using:ExtractPath -ChildPath $PackageId + + Add-Type -AssemblyName System.IO.Compression.FileSystem + + [System.IO.Directory]::CreateDirectory($ExtractPath); + + try { + $zip = [System.IO.Compression.ZipFile]::OpenRead($PackagePath) + + $zip.Entries | + Where-Object {$RelevantExtensions -contains [System.IO.Path]::GetExtension($_.Name)} | + ForEach-Object { + $TargetFile = Join-Path -Path $ExtractPath -ChildPath $_.Name + + [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $TargetFile, $true) + } + } + catch { + + } + finally { + $zip.Dispose() + } + } + function ExtractArtifacts { + if (!(Test-Path $InputPath)) { + Write-Host "Input Path does not exist: $InputPath" + ExitWithExitCode 0 + } + $Jobs = @() + Get-ChildItem "$InputPath\*.nupkg" | + ForEach-Object { + $Jobs += Start-Job -ScriptBlock $ExtractPackage -ArgumentList $_.FullName + } + + foreach ($Job in $Jobs) { + Wait-Job -Id $Job.Id | Receive-Job + } +} + +try { + Measure-Command { ExtractArtifacts } +} +catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + ExitWithExitCode 1 +} diff --git a/eng/common/sdl/packages.config b/eng/common/sdl/packages.config index b054737df13..fb9b7128637 100644 --- a/eng/common/sdl/packages.config +++ b/eng/common/sdl/packages.config @@ -1,4 +1,4 @@  - + diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml index acb4c55d735..5837f3d56d3 100644 --- a/eng/common/templates/job/execute-sdl.yml +++ b/eng/common/templates/job/execute-sdl.yml @@ -20,6 +20,16 @@ jobs: downloadType: specific files matchingPattern: "**" downloadPath: $(Build.SourcesDirectory)\artifacts + - powershell: eng/common/sdl/extract-artifact-packages.ps1 + -InputPath $(Build.SourcesDirectory)\artifacts\BlobArtifacts + -ExtractPath $(Build.SourcesDirectory)\artifacts\BlobArtifacts + displayName: Extract Blob Artifacts + continueOnError: ${{ parameters.continueOnError }} + - powershell: eng/common/sdl/extract-artifact-packages.ps1 + -InputPath $(Build.SourcesDirectory)\artifacts\PackageArtifacts + -ExtractPath $(Build.SourcesDirectory)\artifacts\PackageArtifacts + displayName: Extract Package Artifacts + continueOnError: ${{ parameters.continueOnError }} - task: NuGetToolInstaller@1 displayName: 'Install NuGet.exe' - task: NuGetCommand@2 @@ -36,7 +46,7 @@ jobs: continueOnError: ${{ parameters.continueOnError }} - ${{ if eq(parameters.overrideParameters, '') }}: - powershell: eng/common/sdl/execute-all-sdl-tools.ps1 - -GuardianPackageName Microsoft.Guardian.Cli.0.3.2 + -GuardianPackageName Microsoft.Guardian.Cli.0.6.0 -NugetPackageDirectory $(Build.SourcesDirectory)\.packages -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw) ${{ parameters.additionalParameters }} diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml index ff7346163f4..9e77ef1b54b 100644 --- a/eng/common/templates/job/publish-build-assets.yml +++ b/eng/common/templates/job/publish-build-assets.yml @@ -66,7 +66,6 @@ jobs: script: | Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(BARBuildId) Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value "$(DefaultChannels)" - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsInternalBuild) Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsStableBuild) - task: PublishBuildArtifacts@1 displayName: Publish ReleaseConfigs Artifact diff --git a/eng/common/templates/post-build/channels/internal-servicing.yml b/eng/common/templates/post-build/channels/internal-servicing.yml new file mode 100644 index 00000000000..808d46b17f2 --- /dev/null +++ b/eng/common/templates/post-build/channels/internal-servicing.yml @@ -0,0 +1,170 @@ +parameters: + enableSymbolValidation: true + +stages: +- stage: IS_Publish + dependsOn: validate + variables: + - template: ../common-variables.yml + displayName: Internal Servicing + jobs: + - template: ../setup-maestro-vars.yml + + - job: + displayName: Symbol Publishing + dependsOn: setupMaestroVars + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.InternalServicing_30_Channel_Id) + variables: + - group: DotNet-Symbol-Server-Pats + pool: + vmImage: 'windows-2019' + steps: + - task: DownloadBuildArtifacts@0 + displayName: Download Artifacts + inputs: + downloadType: specific files + matchingPattern: "*Artifacts*" + + - task: PowerShell@2 + displayName: Publish + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task PublishToSymbolServers -restore -msbuildEngine dotnet + /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat) + /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat) + /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/' + /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' + /p:Configuration=Release + + - job: publish_assets + displayName: Publish Assets + dependsOn: setupMaestroVars + variables: + - group: DotNet-Blob-Feed + - group: Publish-Build-Assets + - group: AzureDevOps-Artifact-Feeds-Pats + - name: BARBuildId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] + - name: IsStableBuild + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ] + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.InternalServicing_30_Channel_Id) + pool: + vmImage: 'windows-2019' + steps: + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: current + artifactName: PackageArtifacts + + - task: DownloadBuildArtifacts@0 + displayName: Download Blob Artifacts + inputs: + buildType: current + artifactName: BlobArtifacts + + - task: DownloadBuildArtifacts@0 + displayName: Download Asset Manifests + inputs: + buildType: current + artifactName: AssetManifests + + - task: PowerShell@2 + displayName: Add Assets Location + env: + AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw) + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet + /p:ChannelId=$(InternalServicing_30_Channel_Id) + /p:IsStableBuild=$(IsStableBuild) + /p:IsInternalBuild=$(IsInternalBuild) + /p:RepositoryName=$(Build.Repository.Name) + /p:CommitSha=$(Build.SourceVersion) + /p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe + /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' + /p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' + /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' + /p:BARBuildId=$(BARBuildId) + /p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com' + /p:BuildAssetRegistryToken='$(MaestroAccessToken)' + /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/' + /p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts' + /p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts' + /p:Configuration=Release + + - task: NuGetCommand@2 + displayName: Publish Packages to AzDO Feed + condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com') + inputs: + command: push + vstsFeed: $(AzDoFeedName) + packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg + publishVstsFeed: $(AzDoFeedName) + + - task: PowerShell@2 + displayName: Publish Blobs to AzDO Feed + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1 + arguments: -FeedName $(AzDoFeedName) + -SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/ + -PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw) + enabled: false + + - template: ../trigger-subscription.yml + parameters: + ChannelId: ${{ variables.InternalServicing_30_Channel_Id }} + +- stage: IS_PublishValidation + displayName: Publish Validation + variables: + - template: ../common-variables.yml + jobs: + - template: ../setup-maestro-vars.yml + + - ${{ if eq(parameters.enableSymbolValidation, 'true') }}: + - job: + displayName: Symbol Availability + dependsOn: setupMaestroVars + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.InternalServicing_30_Channel_Id) + pool: + vmImage: 'windows-2019' + steps: + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: current + artifactName: PackageArtifacts + + - task: PowerShell@2 + displayName: Check Symbol Availability + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1 + arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion) + + - job: + displayName: Gather Drop + dependsOn: setupMaestroVars + variables: + BARBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.InternalServicing_30_Channel_Id) + pool: + vmImage: 'windows-2019' + steps: + - task: PowerShell@2 + displayName: Setup Darc CLI + inputs: + targetType: filePath + filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1' + + - task: PowerShell@2 + displayName: Run Darc gather-drop + inputs: + targetType: inline + script: | + darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location + enabled: false + + - template: ../promote-build.yml + parameters: + ChannelId: ${{ variables.InternalServicing_30_Channel_Id }} \ No newline at end of file diff --git a/eng/common/templates/post-build/channels/public-dev-release.yml b/eng/common/templates/post-build/channels/public-dev-release.yml index c61eaa927d9..79c6822db72 100644 --- a/eng/common/templates/post-build/channels/public-dev-release.yml +++ b/eng/common/templates/post-build/channels/public-dev-release.yml @@ -20,17 +20,10 @@ stages: vmImage: 'windows-2019' steps: - task: DownloadBuildArtifacts@0 - displayName: Download PDB Artifacts + displayName: Download Artifacts inputs: - buildType: current - artifactName: PDBArtifacts - continueOnError: true - - - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - buildType: current - artifactName: BlobArtifacts + downloadType: specific files + matchingPattern: "*Artifacts*" - task: PowerShell@2 displayName: Publish @@ -44,13 +37,16 @@ stages: /p:Configuration=Release - job: - displayName: Publish to Static Feed + displayName: Publish Assets dependsOn: setupMaestroVars variables: - group: DotNet-Blob-Feed - group: Publish-Build-Assets + - group: AzureDevOps-Artifact-Feeds-Pats - name: BARBuildId value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] + - name: IsStableBuild + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ] condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicDevRelease_30_Channel_Id) pool: vmImage: 'windows-2019' @@ -74,22 +70,47 @@ stages: artifactName: AssetManifests - task: PowerShell@2 - displayName: Publish + displayName: Add Assets Location + env: + AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw) inputs: filePath: eng\common\sdk-task.ps1 - arguments: -task PublishToPackageFeed -restore -msbuildEngine dotnet - /p:AccountKeyToStaticFeed='$(dotnetfeed-storage-access-key-1)' + arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet + /p:ChannelId=$(PublicDevRelease_30_Channel_Id) + /p:IsStableBuild=$(IsStableBuild) + /p:IsInternalBuild=$(IsInternalBuild) + /p:RepositoryName=$(Build.Repository.Name) + /p:CommitSha=$(Build.SourceVersion) + /p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe + /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' + /p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' + /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' /p:BARBuildId=$(BARBuildId) /p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com' /p:BuildAssetRegistryToken='$(MaestroAccessToken)' /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/' /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/' - /p:ArtifactsCategory='$(_DotNetArtifactsCategory)' - /p:OverrideAssetsWithSameName=true - /p:PassIfExistingItemIdentical=true /p:Configuration=Release + - task: NuGetCommand@2 + displayName: Publish Packages to AzDO Feed + condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com') + inputs: + command: push + vstsFeed: $(AzDoFeedName) + packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg + publishVstsFeed: $(AzDoFeedName) + + - task: PowerShell@2 + displayName: Publish Blobs to AzDO Feed + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1 + arguments: -FeedName $(AzDoFeedName) + -SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/ + -PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw) + enabled: false + - stage: PublishValidation displayName: Publish Validation @@ -140,6 +161,6 @@ stages: script: | darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location - - template: ../promote-build.yml - parameters: + - template: ../promote-build.yml + parameters: ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }} diff --git a/eng/common/templates/post-build/channels/public-release.yml b/eng/common/templates/post-build/channels/public-release.yml new file mode 100644 index 00000000000..25923020df8 --- /dev/null +++ b/eng/common/templates/post-build/channels/public-release.yml @@ -0,0 +1,170 @@ +parameters: + enableSymbolValidation: true + +stages: +- stage: PubRel_Publish + dependsOn: validate + variables: + - template: ../common-variables.yml + displayName: Public Release + jobs: + - template: ../setup-maestro-vars.yml + + - job: + displayName: Symbol Publishing + dependsOn: setupMaestroVars + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicRelease_30_Channel_Id) + variables: + - group: DotNet-Symbol-Server-Pats + pool: + vmImage: 'windows-2019' + steps: + - task: DownloadBuildArtifacts@0 + displayName: Download Artifacts + inputs: + downloadType: specific files + matchingPattern: "*Artifacts*" + + - task: PowerShell@2 + displayName: Publish + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task PublishToSymbolServers -restore -msbuildEngine dotnet + /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat) + /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat) + /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/' + /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' + /p:Configuration=Release + + - job: publish_assets + displayName: Publish Assets + dependsOn: setupMaestroVars + variables: + - group: DotNet-Blob-Feed + - group: Publish-Build-Assets + - group: AzureDevOps-Artifact-Feeds-Pats + - name: BARBuildId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] + - name: IsStableBuild + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ] + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicRelease_30_Channel_Id) + pool: + vmImage: 'windows-2019' + steps: + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: current + artifactName: PackageArtifacts + + - task: DownloadBuildArtifacts@0 + displayName: Download Blob Artifacts + inputs: + buildType: current + artifactName: BlobArtifacts + + - task: DownloadBuildArtifacts@0 + displayName: Download Asset Manifests + inputs: + buildType: current + artifactName: AssetManifests + + - task: PowerShell@2 + displayName: Publish + env: + AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw) + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet + /p:ChannelId=$(PublicRelease_30_Channel_Id) + /p:IsStableBuild=$(IsStableBuild) + /p:IsInternalBuild=$(IsInternalBuild) + /p:RepositoryName=$(Build.Repository.Name) + /p:CommitSha=$(Build.SourceVersion) + /p:NugetPath=$(Agent.BuildDirectory)/Nuget/NuGet.exe + /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' + /p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' + /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' + /p:BARBuildId=$(BARBuildId) + /p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com' + /p:BuildAssetRegistryToken='$(MaestroAccessToken)' + /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/' + /p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts' + /p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts' + /p:Configuration=Release + + - task: NuGetCommand@2 + displayName: Publish Packages to AzDO Feed + condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com') + inputs: + command: push + vstsFeed: $(AzDoFeedName) + packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg + publishVstsFeed: $(AzDoFeedName) + + - task: PowerShell@2 + displayName: Publish Blobs to AzDO Feed + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1 + arguments: -FeedName $(AzDoFeedName) + -SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/ + -PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw) + enabled: false + + - template: ../trigger-subscription.yml + parameters: + ChannelId: ${{ variables.PublicRelease_30_Channel_Id }} + +- stage: PubRel_PublishValidation + displayName: Publish Validation + variables: + - template: ../common-variables.yml + jobs: + - template: ../setup-maestro-vars.yml + + - ${{ if eq(parameters.enableSymbolValidation, 'true') }}: + - job: + displayName: Symbol Availability + dependsOn: setupMaestroVars + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicRelease_30_Channel_Id) + pool: + vmImage: 'windows-2019' + steps: + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: current + artifactName: PackageArtifacts + + - task: PowerShell@2 + displayName: Check Symbol Availability + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1 + arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion) + + - job: + displayName: Gather Drop + dependsOn: setupMaestroVars + variables: + BARBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicRelease_30_Channel_Id) + pool: + vmImage: 'windows-2019' + steps: + - task: PowerShell@2 + displayName: Setup Darc CLI + inputs: + targetType: filePath + filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1' + + - task: PowerShell@2 + displayName: Run Darc gather-drop + inputs: + targetType: inline + script: | + darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location + enabled: false + + - template: ../promote-build.yml + parameters: + ChannelId: ${{ variables.PublicRelease_30_Channel_Id }} diff --git a/eng/common/templates/post-build/channels/public-validation-release.yml b/eng/common/templates/post-build/channels/public-validation-release.yml index 23725c6d620..114477d3adb 100644 --- a/eng/common/templates/post-build/channels/public-validation-release.yml +++ b/eng/common/templates/post-build/channels/public-validation-release.yml @@ -8,14 +8,17 @@ stages: - template: ../setup-maestro-vars.yml - job: - displayName: Publish to Static Feed + displayName: Publish Assets dependsOn: setupMaestroVars - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicValidationRelease_30_Channel_Id) variables: - group: DotNet-Blob-Feed - group: Publish-Build-Assets + - group: AzureDevOps-Artifact-Feeds-Pats - name: BARBuildId value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] + - name: IsStableBuild + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ] + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicValidationRelease_30_Channel_Id) pool: vmImage: 'windows-2019' steps: @@ -38,21 +41,46 @@ stages: artifactName: AssetManifests - task: PowerShell@2 - displayName: Publish + displayName: Add Assets Location + env: + AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw) inputs: filePath: eng\common\sdk-task.ps1 - arguments: -task PublishToPackageFeed -restore -msbuildEngine dotnet - /p:AccountKeyToStaticFeed='$(dotnetfeed-storage-access-key-1)' + arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet + /p:ChannelId=$(PublicValidationRelease_30_Channel_Id) + /p:IsStableBuild=$(IsStableBuild) + /p:IsInternalBuild=$(IsInternalBuild) + /p:RepositoryName=$(Build.Repository.Name) + /p:CommitSha=$(Build.SourceVersion) + /p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe + /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' + /p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' + /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' /p:BARBuildId=$(BARBuildId) /p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com' /p:BuildAssetRegistryToken='$(MaestroAccessToken)' /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/' - /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' - /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/' - /p:ArtifactsCategory='$(_DotNetArtifactsCategory)' - /p:OverrideAssetsWithSameName=true - /p:PassIfExistingItemIdentical=true + /p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts' + /p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts' /p:Configuration=Release + + - task: NuGetCommand@2 + displayName: Publish Packages to AzDO Feed + condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com') + inputs: + command: push + vstsFeed: $(AzDoFeedName) + packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg + publishVstsFeed: $(AzDoFeedName) + + - task: PowerShell@2 + displayName: Publish Blobs to AzDO Feed + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1 + arguments: -FeedName $(AzDoFeedName) + -SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/ + -PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw) + enabled: false - stage: PVR_PublishValidation @@ -86,6 +114,6 @@ stages: script: | darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com --password $(MaestroAccessToken) --latest-location - - template: ../promote-build.yml - parameters: + - template: ../promote-build.yml + parameters: ChannelId: ${{ variables.PublicValidationRelease_30_Channel_Id }} diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml index 97b48d97fec..82834673520 100644 --- a/eng/common/templates/post-build/common-variables.yml +++ b/eng/common/templates/post-build/common-variables.yml @@ -5,5 +5,14 @@ variables: # .NET Tools - Validation PublicValidationRelease_30_Channel_Id: 9 + # .NET Core 3.0 Internal Servicing + InternalServicing_30_Channel_Id: 184 + + # .NET Core 3.0 Release + PublicRelease_30_Channel_Id: 19 + + # Whether the build is internal or not + IsInternalBuild: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} + SourceLinkCLIVersion: 3.0.0 SymbolToolVersion: 1.0.1 diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index 2c411dd0098..daa799259c7 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -2,6 +2,7 @@ parameters: enableSourceLinkValidation: true enableSigningValidation: true enableSymbolValidation: true + enableNugetValidation: true SDLValidationParameters: enable: false params: '' @@ -11,6 +12,25 @@ stages: dependsOn: build displayName: Validate jobs: + - ${{ if eq(parameters.enableNugetValidation, 'true') }}: + - job: + displayName: NuGet Validation + pool: + vmImage: 'windows-2019' + steps: + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: current + artifactName: PackageArtifacts + + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 + arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ + -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ + - ${{ if eq(parameters.enableSigningValidation, 'true') }}: - job: displayName: Signing Validation @@ -65,3 +85,7 @@ stages: enableSymbolValidation: ${{ parameters.enableSymbolValidation }} - template: \eng\common\templates\post-build\channels\public-validation-release.yml + +- template: \eng\common\templates\post-build\channels\public-release.yml + +- template: \eng\common\templates\post-build\channels\internal-servicing.yml diff --git a/eng/common/templates/post-build/promote-build.yml b/eng/common/templates/post-build/promote-build.yml index d00317003b7..af48b0b339e 100644 --- a/eng/common/templates/post-build/promote-build.yml +++ b/eng/common/templates/post-build/promote-build.yml @@ -18,11 +18,7 @@ jobs: - task: PowerShell@2 displayName: Add Build to Channel inputs: - targetType: inline - script: | - $headers = @{ - "Accept" = "application/json" - "Authorization" = "Bearer $(MaestroAccessToken)" - } - Invoke-RestMethod -Method Post -Headers $headers -Uri https://maestro-prod.westus2.cloudapp.azure.com/api/channels/$(ChannelId)/builds/$(BARBuildId)?api-version=2019-01-16 - enabled: false + filePath: $(Build.SourcesDirectory)/eng/common/post-build/promote-build.ps1 + arguments: -BuildId $(BARBuildId) + -ChannelId $(ChannelId) + -BarToken $(MaestroAccessToken) diff --git a/eng/common/templates/post-build/setup-maestro-vars.yml b/eng/common/templates/post-build/setup-maestro-vars.yml index 0eddd6cd3b7..f6120dc1e1c 100644 --- a/eng/common/templates/post-build/setup-maestro-vars.yml +++ b/eng/common/templates/post-build/setup-maestro-vars.yml @@ -28,10 +28,8 @@ jobs: $Channels = "" $Content | Select -Index 1 | ForEach-Object { $Channels += "$_ ," } - $IsInternalBuild = $Content | Select -Index 2 - $IsStableBuild = $Content | Select -Index 3 + $IsStableBuild = $Content | Select -Index 2 Write-PipelineSetVariable -Name 'BARBuildId' -Value $BarId Write-PipelineSetVariable -Name 'InitialChannels' -Value "$Channels" - Write-PipelineSetVariable -Name 'IsInternalBuild' -Value $IsInternalBuild Write-PipelineSetVariable -Name 'IsStableBuild' -Value $IsStableBuild diff --git a/eng/common/templates/post-build/trigger-subscription.yml b/eng/common/templates/post-build/trigger-subscription.yml new file mode 100644 index 00000000000..65259d4e685 --- /dev/null +++ b/eng/common/templates/post-build/trigger-subscription.yml @@ -0,0 +1,11 @@ +parameters: + ChannelId: 0 + +steps: +- task: PowerShell@2 + displayName: Triggering subscriptions + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1 + arguments: -SourceRepo $(Build.Repository.Uri) + -ChannelId ${{ parameters.ChannelId }} + -BarToken $(MaestroAccessTokenInt) \ No newline at end of file diff --git a/global.json b/global.json index 1914bc1183d..81da5d7c133 100644 --- a/global.json +++ b/global.json @@ -12,6 +12,6 @@ "version": "3.0.100-preview6-012264" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19323.4" + "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19330.1" } } diff --git a/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilder.cs b/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilder.cs index 5faed428dab..f4df70c8389 100644 --- a/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilder.cs +++ b/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilder.cs @@ -104,6 +104,7 @@ public virtual ConventionSet CreateConventionSet() var databaseGeneratedAttributeConvention = new DatabaseGeneratedAttributeConvention(Dependencies); var requiredPropertyAttributeConvention = new RequiredPropertyAttributeConvention(Dependencies); var nonNullableReferencePropertyConvention = new NonNullableReferencePropertyConvention(Dependencies); + var nonNullableNavigationConvention = new NonNullableNavigationConvention(Dependencies); var maxLengthAttributeConvention = new MaxLengthAttributeConvention(Dependencies); var stringLengthAttributeConvention = new StringLengthAttributeConvention(Dependencies); var timestampAttributeConvention = new TimestampAttributeConvention(Dependencies); @@ -171,11 +172,14 @@ public virtual ConventionSet CreateConventionSet() conventionSet.ModelFinalizedConventions.Add(foreignKeyIndexConvention); conventionSet.ModelFinalizedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.ModelFinalizedConventions.Add(servicePropertyDiscoveryConvention); + conventionSet.ModelFinalizedConventions.Add(nonNullableReferencePropertyConvention); + conventionSet.ModelFinalizedConventions.Add(nonNullableNavigationConvention); conventionSet.ModelFinalizedConventions.Add(new ValidatingConvention(Dependencies)); + // Don't add any more conventions to ModelFinalizedConventions after ValidatingConvention conventionSet.NavigationAddedConventions.Add(backingFieldConvention); conventionSet.NavigationAddedConventions.Add(new RequiredNavigationAttributeConvention(Dependencies)); - conventionSet.NavigationAddedConventions.Add(new NonNullableNavigationConvention(Dependencies)); + conventionSet.NavigationAddedConventions.Add(nonNullableNavigationConvention); conventionSet.NavigationAddedConventions.Add(inversePropertyAttributeConvention); conventionSet.NavigationAddedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.NavigationAddedConventions.Add(relationshipDiscoveryConvention); diff --git a/src/EFCore/Metadata/Conventions/NonNullableConventionBase.cs b/src/EFCore/Metadata/Conventions/NonNullableConventionBase.cs index 832aca36cc1..b8910fa42c8 100644 --- a/src/EFCore/Metadata/Conventions/NonNullableConventionBase.cs +++ b/src/EFCore/Metadata/Conventions/NonNullableConventionBase.cs @@ -2,9 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; namespace Microsoft.EntityFrameworkCore.Metadata.Conventions @@ -13,11 +15,14 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions /// A base type for conventions that configure model aspects based on whether the member type /// is a non-nullable reference type. /// - public abstract class NonNullableConventionBase + public abstract class NonNullableConventionBase : IModelFinalizedConvention { + // For the interpretation of nullability metadata, see + // https://github.com/dotnet/roslyn/blob/master/docs/features/nullable-metadata.md + + private const string StateAnnotationName = "NonNullableConventionState"; private const string NullableAttributeFullName = "System.Runtime.CompilerServices.NullableAttribute"; - private Type _nullableAttrType; - private FieldInfo _nullableFlagsFieldInfo; + private const string NullableContextAttributeFullName = "System.Runtime.CompilerServices.NullableContextAttribute"; /// /// Creates a new instance of . @@ -33,40 +38,118 @@ protected NonNullableConventionBase([NotNull] ProviderConventionSetBuilderDepend /// protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } + private byte? GetNullabilityContextFlag(NonNullabilityConventionState state, Attribute[] attributes) + { + if (attributes.FirstOrDefault(a => a.GetType().FullName == NullableContextAttributeFullName) is Attribute attribute) + { + var attributeType = attribute.GetType(); + + if (attributeType != state.NullableContextAttrType) + { + state.NullableContextFlagFieldInfo = attributeType.GetField("Flag"); + state.NullableContextAttrType = attributeType; + } + + if (state.NullableContextFlagFieldInfo?.GetValue(attribute) is byte flag) + { + return flag; + } + } + + return null; + } + /// /// Returns a value indicating whether the member type is a non-nullable reference type. /// + /// The model builder used to build the model. /// The member info. /// true if the member type is a non-nullable reference type. - protected virtual bool IsNonNullable([NotNull] MemberInfo memberInfo) + protected virtual bool IsNonNullable( + [NotNull] IConventionModelBuilder modelBuilder, + [NotNull] MemberInfo memberInfo) { + var state = GetOrInitializeState(modelBuilder); + // For C# 8.0 nullable types, the C# currently synthesizes a NullableAttribute that expresses nullability into assemblies // it produces. If the model is spread across more than one assembly, there will be multiple versions of this attribute, // so look for it by name, caching to avoid reflection on every check. // Note that this may change - if https://github.com/dotnet/corefx/issues/36222 is done we can remove all of this. - if (!(Attribute.GetCustomAttributes(memberInfo, true) - .FirstOrDefault(a => a.GetType().FullName == NullableAttributeFullName) - is { } attribute)) + + // First look for NullableAttribute on the member itself + if (Attribute.GetCustomAttributes(memberInfo, true) + .FirstOrDefault(a => a.GetType().FullName == NullableAttributeFullName) is Attribute attribute) + { + var attributeType = attribute.GetType(); + + if (attributeType != state.NullableAttrType) + { + state.NullableFlagsFieldInfo = attributeType.GetField("NullableFlags"); + state.NullableAttrType = attributeType; + } + + if (state.NullableFlagsFieldInfo?.GetValue(attribute) is byte[] flags + && flags.FirstOrDefault() == 1) + { + return true; + } + } + + // No attribute on the member, try to find a NullableContextAttribute on the declaring type + var type = memberInfo.DeclaringType; + if (type != null) { - return false; + if (state.TypeNonNullabilityContextCache.TryGetValue(type, out var cachedTypeNonNullable)) + { + return cachedTypeNonNullable; + } + + var typeContextFlag = GetNullabilityContextFlag(state, Attribute.GetCustomAttributes(type)); + if (typeContextFlag.HasValue) + { + return state.TypeNonNullabilityContextCache[type] = typeContextFlag.Value == 1; + } } - var attributeType = attribute.GetType(); - if (attributeType != _nullableAttrType) + // Not found at the type level, try at the module level + var module = memberInfo.Module; + if (!state.ModuleNonNullabilityContextCache.TryGetValue(module, out var moduleNonNullable)) { - _nullableFlagsFieldInfo = attributeType.GetField("NullableFlags"); - _nullableAttrType = attributeType; + var moduleContextFlag = GetNullabilityContextFlag(state, Attribute.GetCustomAttributes(memberInfo.Module)); + moduleNonNullable = state.ModuleNonNullabilityContextCache[module] = + moduleContextFlag.HasValue && moduleContextFlag == 1; } - // For the interpretation of NullableFlags, see - // https://github.com/dotnet/roslyn/blob/master/docs/features/nullable-reference-types.md#annotations - if (_nullableFlagsFieldInfo?.GetValue(attribute) is byte[] flags - && flags.FirstOrDefault() == 1) + if (type != null) { - return true; + state.TypeNonNullabilityContextCache[type] = moduleNonNullable; } - return false; + return moduleNonNullable; + } + + private NonNullabilityConventionState GetOrInitializeState(IConventionModelBuilder modelBuilder) + => (NonNullabilityConventionState)( + modelBuilder.Metadata.FindAnnotation(StateAnnotationName) ?? + modelBuilder.Metadata.AddAnnotation(StateAnnotationName, new NonNullabilityConventionState()) + ).Value; + + /// + /// Called after a model is finalized. Removes the cached state annotation used by this convention. + /// + /// The builder for the model. + /// Additional information associated with convention execution. + public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext context) + => modelBuilder.Metadata.RemoveAnnotation(StateAnnotationName); + + private class NonNullabilityConventionState + { + public Type NullableAttrType; + public Type NullableContextAttrType; + public FieldInfo NullableFlagsFieldInfo; + public FieldInfo NullableContextFlagFieldInfo; + public Dictionary TypeNonNullabilityContextCache { get; } = new Dictionary(); + public Dictionary ModuleNonNullabilityContextCache { get; } = new Dictionary(); } } } diff --git a/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs b/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs index b3c90579715..7e104bbbb33 100644 --- a/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs +++ b/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs @@ -40,8 +40,9 @@ public virtual void ProcessNavigationAdded( Check.NotNull(relationshipBuilder, nameof(relationshipBuilder)); Check.NotNull(navigation, nameof(navigation)); - if (!IsNonNullable(navigation) - || navigation.IsCollection()) + var modelBuilder = relationshipBuilder.ModelBuilder; + + if (!IsNonNullable(modelBuilder, navigation) || navigation.IsCollection()) { return; } @@ -51,7 +52,7 @@ public virtual void ProcessNavigationAdded( var inverse = navigation.FindInverse(); if (inverse != null) { - if (IsNonNullable(inverse)) + if (IsNonNullable(modelBuilder, inverse)) { Dependencies.Logger.NonNullableReferenceOnBothNavigations(navigation, inverse); return; @@ -82,9 +83,9 @@ public virtual void ProcessNavigationAdded( context.StopProcessingIfChanged(relationshipBuilder.Metadata.DependentToPrincipal); } - private bool IsNonNullable(IConventionNavigation navigation) + private bool IsNonNullable(IConventionModelBuilder modelBuilder, IConventionNavigation navigation) => navigation.DeclaringEntityType.HasClrType() && navigation.DeclaringEntityType.GetRuntimeProperties().Find(navigation.Name) is PropertyInfo propertyInfo - && IsNonNullable(propertyInfo); + && IsNonNullable(modelBuilder, propertyInfo); } } diff --git a/src/EFCore/Metadata/Conventions/NonNullableReferencePropertyConvention.cs b/src/EFCore/Metadata/Conventions/NonNullableReferencePropertyConvention.cs index aa364b5d811..8fc712e8682 100644 --- a/src/EFCore/Metadata/Conventions/NonNullableReferencePropertyConvention.cs +++ b/src/EFCore/Metadata/Conventions/NonNullableReferencePropertyConvention.cs @@ -29,7 +29,7 @@ private void Process(IConventionPropertyBuilder propertyBuilder) // If the model is spread across multiple assemblies, it may contain different NullableAttribute types as // the compiler synthesizes them for each assembly. if (propertyBuilder.Metadata.GetIdentifyingMemberInfo() is MemberInfo memberInfo - && IsNonNullable(memberInfo)) + && IsNonNullable(propertyBuilder.ModelBuilder, memberInfo)) { propertyBuilder.IsRequired(true); }