diff --git a/NuGet.config b/NuGet.config index 4c7c8ed53a1..4b9d18d31df 100644 --- a/NuGet.config +++ b/NuGet.config @@ -2,13 +2,10 @@ - - - - - - + + + diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b48194e7747..e386365e276 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -64,26 +64,6 @@ stages: - script: "echo ##vso[build.addbuildtag]release-candidate" condition: and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['IsFinalBuild'], 'true')) displayName: 'Set CI tags' - - powershell: | - SqlLocalDB stop MSSQLLocalDB -i - SqlLocalDB start MSSQLLocalDB - & "$env:ProgramFiles\Microsoft SQL Server\110\Tools\Binn\SQLCMD.EXE" -S '(localdb)\MSSQLLocalDB' -b -Q @' - DECLARE @name nvarchar(255); - DECLARE db CURSOR FOR SELECT Name FROM sysdatabases WHERE Name NOT IN ('master', 'tempdb', 'model', 'msdb'); - OPEN db; - FETCH NEXT FROM db INTO @name; - WHILE @@FETCH_STATUS = 0 - BEGIN - SET @name = REPLACE(@name, ']', ']]'); - PRINT 'Dropping database [' + @name + ']'; - SET @name = 'DROP DATABASE [' + @name + ']'; - EXEC (@name); - FETCH NEXT FROM db INTO @name; - END; - CLOSE db; - DEALLOCATE db; - '@ - displayName: Cleanup databases - script: eng\common\cibuild.cmd -configuration $(_BuildConfig) -prepareMachine $(_InternalBuildArgs) env: Test__Cosmos__DefaultConnection: $(_CosmosConnectionUrl) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3c2f5272e7e..39a41ae57c1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -11,35 +11,35 @@ https://github.com/aspnet/Extensions - 0b951c16de0f39e13cce8372e11c28eb90576662 + 6f84a4a3d89182f0a5007c40eb0880ebee489ca0 https://github.com/aspnet/Extensions - 0b951c16de0f39e13cce8372e11c28eb90576662 + 6f84a4a3d89182f0a5007c40eb0880ebee489ca0 https://github.com/aspnet/Extensions - 0b951c16de0f39e13cce8372e11c28eb90576662 + 6f84a4a3d89182f0a5007c40eb0880ebee489ca0 https://github.com/aspnet/Extensions - 0b951c16de0f39e13cce8372e11c28eb90576662 + 6f84a4a3d89182f0a5007c40eb0880ebee489ca0 https://github.com/aspnet/Extensions - 0b951c16de0f39e13cce8372e11c28eb90576662 + 6f84a4a3d89182f0a5007c40eb0880ebee489ca0 https://github.com/dotnet/core-setup 7d57652f33493fa022125b7f63aad0d70c52d810 - + https://github.com/aspnet/Extensions - 0b951c16de0f39e13cce8372e11c28eb90576662 + 6f84a4a3d89182f0a5007c40eb0880ebee489ca0 https://github.com/aspnet/Extensions - 0b951c16de0f39e13cce8372e11c28eb90576662 + 6f84a4a3d89182f0a5007c40eb0880ebee489ca0 https://github.com/dotnet/core-setup @@ -67,9 +67,9 @@ - + https://github.com/dotnet/arcade - 8eb29ba860a3cfcfe68f9a8256caa7efc1f1aaba + 0e9ffd6464aff37aef2dc41dc2162d258f266e32 https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index 80cd674d688..e0e9ab4e4e9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,12 +1,12 @@ - 3.0.0 - rc2 + 3.0.1 + servicing False - true + false release @@ -37,7 +37,7 @@ 3.0.0 3.0.0 3.0.0 - 3.0.0-rc2.19463.5 + 3.0.0-rc2.19475.1 3.0.0 diff --git a/eng/common/enable-cross-org-publishing.ps1 b/eng/common/enable-cross-org-publishing.ps1 new file mode 100644 index 00000000000..eccbf9f1b16 --- /dev/null +++ b/eng/common/enable-cross-org-publishing.ps1 @@ -0,0 +1,6 @@ +param( + [string] $token +) + +Write-Host "##vso[task.setvariable variable=VSS_NUGET_ACCESSTOKEN]$token" +Write-Host "##vso[task.setvariable variable=VSS_NUGET_URI_PREFIXES]https://dnceng.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/dnceng/;https://devdiv.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/devdiv/" diff --git a/eng/common/sdl/extract-artifact-packages.ps1 b/eng/common/sdl/extract-artifact-packages.ps1 index 1fdbb14329c..6e6825013bf 100644 --- a/eng/common/sdl/extract-artifact-packages.ps1 +++ b/eng/common/sdl/extract-artifact-packages.ps1 @@ -5,6 +5,13 @@ param( $ErrorActionPreference = "Stop" Set-StrictMode -Version 2.0 + +# `tools.ps1` checks $ci to perform some actions. Since the post-build +# scripts don't necessarily execute in the same agent that run the +# build.ps1/sh script this variable isn't automatically set. +$ci = $true +. $PSScriptRoot\..\tools.ps1 + $ExtractPackage = { param( [string] $PackagePath # Full path to a NuGet package diff --git a/eng/common/templates/post-build/channels/netcore-3-tools-validation.yml b/eng/common/templates/post-build/channels/netcore-3-tools-validation.yml new file mode 100644 index 00000000000..cdb74031fcf --- /dev/null +++ b/eng/common/templates/post-build/channels/netcore-3-tools-validation.yml @@ -0,0 +1,95 @@ +parameters: + artifactsPublishingAdditionalParameters: '' + publishInstallersAndChecksums: false + +stages: +- stage: NetCore_3_Tools_Validation_Publish + dependsOn: validate + variables: + - template: ../common-variables.yml + displayName: .NET 3 Tools - Validation Publishing + jobs: + - template: ../setup-maestro-vars.yml + + - job: publish_assets + displayName: Publish Assets + dependsOn: setupMaestroVars + variables: + - group: DotNet-Blob-Feed + - 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'], format('[{0}]', variables.NETCore_3_Tools_Validation_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: NuGetToolInstaller@1 + displayName: 'Install NuGet.exe' + + # This is necessary whenever we want to publish/restore to an AzDO private feed + - task: NuGetAuthenticate@0 + displayName: 'Authenticate to AzDO Feeds' + + - task: PowerShell@2 + displayName: Enable cross-org publishing + inputs: + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) + + - task: PowerShell@2 + displayName: Publish Assets + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet + /p:ArtifactsCategory=$(_DotNetValidationArtifactsCategory) + /p:IsStableBuild=$(IsStableBuild) + /p:IsInternalBuild=$(IsInternalBuild) + /p:RepositoryName=$(Build.Repository.Name) + /p:CommitSha=$(Build.SourceVersion) + /p:NugetPath=$(NuGetExeToolPath) + /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-packages-rw)' + /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' + /p:BARBuildId=$(BARBuildId) + /p:MaestroApiEndpoint='$(MaestroApiEndPoint)' + /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)' + /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/' + /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' + /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/' + /p:Configuration=Release + /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }} + /p:InstallersTargetStaticFeed=$(InstallersBlobFeedUrl) + /p:InstallersAzureAccountKey=$(dotnetcli-storage-key) + /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl) + /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key) + /p:PublishToAzureDevOpsNuGetFeeds=true + /p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' + /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' + /p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' + /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' + /p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' + /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' + ${{ parameters.artifactsPublishingAdditionalParameters }} + + - template: ../../steps/promote-build.yml + parameters: + ChannelId: ${{ variables.NETCore_3_Tools_Validation_Channel_Id }} diff --git a/eng/common/templates/post-build/channels/netcore-dev-30.yml b/eng/common/templates/post-build/channels/netcore-3-tools.yml similarity index 82% rename from eng/common/templates/post-build/channels/netcore-dev-30.yml rename to eng/common/templates/post-build/channels/netcore-3-tools.yml index 69f1a9013e0..70eec773e75 100644 --- a/eng/common/templates/post-build/channels/netcore-dev-30.yml +++ b/eng/common/templates/post-build/channels/netcore-3-tools.yml @@ -4,18 +4,18 @@ parameters: publishInstallersAndChecksums: false stages: -- stage: NetCore_Dev30_Publish +- stage: NetCore_3_Tools_Publish dependsOn: validate variables: - template: ../common-variables.yml - displayName: .NET Core 3.0 Dev Publishing + displayName: .NET 3 Tools Publishing jobs: - template: ../setup-maestro-vars.yml - job: displayName: Symbol Publishing dependsOn: setupMaestroVars - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicDevRelease_30_Channel_Id)) + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NetCore_3_Tools_Channel_Id)) variables: - group: DotNet-Symbol-Server-Pats pool: @@ -56,7 +56,7 @@ stages: value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] - name: IsStableBuild value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ] - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicDevRelease_30_Channel_Id)) + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NetCore_3_Tools_Channel_Id)) pool: vmImage: 'windows-2019' steps: @@ -85,42 +85,46 @@ stages: - task: NuGetAuthenticate@0 displayName: 'Authenticate to AzDO Feeds' + - task: PowerShell@2 + displayName: Enable cross-org publishing + inputs: + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) + - task: PowerShell@2 displayName: Publish Assets - env: - AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw) inputs: filePath: eng\common\sdk-task.ps1 - arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet + arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet /p:ArtifactsCategory=$(_DotNetArtifactsCategory) /p:IsStableBuild=$(IsStableBuild) /p:IsInternalBuild=$(IsInternalBuild) /p:RepositoryName=$(Build.Repository.Name) /p:CommitSha=$(Build.SourceVersion) /p:NugetPath=$(NuGetExeToolPath) - /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-packages-rw)' - /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' - /p:BARBuildId=$(BARBuildId) - /p:MaestroApiEndpoint='$(MaestroApiEndPoint)' - /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)' - /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/' - /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' - /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/' - /p:Configuration=Release + /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-packages-rw)' + /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' + /p:BARBuildId=$(BARBuildId) + /p:MaestroApiEndpoint='$(MaestroApiEndPoint)' + /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)' + /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/' + /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' + /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/' + /p:Configuration=Release /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }} /p:InstallersTargetStaticFeed=$(InstallersBlobFeedUrl) /p:InstallersAzureAccountKey=$(dotnetcli-storage-key) /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl) /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key) /p:PublishToAzureDevOpsNuGetFeeds=true - /p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3/nuget/v3/index.json' + /p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' - /p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-transport/nuget/v3/index.json' + /p:AzureDevOpsStaticTransportFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' - /p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-symbols/nuget/v3/index.json' + /p:AzureDevOpsStaticSymbolsFeed='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' ${{ parameters.artifactsPublishingAdditionalParameters }} - template: ../../steps/promote-build.yml parameters: - ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }} + ChannelId: ${{ variables.NetCore_3_Tools_Channel_Id }} \ No newline at end of file diff --git a/eng/common/templates/post-build/channels/netcore-dev-31.yml b/eng/common/templates/post-build/channels/netcore-dev-31.yml index 720a0ab08a2..db21254187d 100644 --- a/eng/common/templates/post-build/channels/netcore-dev-31.yml +++ b/eng/common/templates/post-build/channels/netcore-dev-31.yml @@ -85,10 +85,14 @@ stages: - task: NuGetAuthenticate@0 displayName: 'Authenticate to AzDO Feeds' + - task: PowerShell@2 + displayName: Enable cross-org publishing + inputs: + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) + - task: PowerShell@2 displayName: Publish Assets - env: - AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw) inputs: filePath: eng\common\sdk-task.ps1 arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet diff --git a/eng/common/templates/post-build/channels/netcore-dev-5.yml b/eng/common/templates/post-build/channels/netcore-dev-5.yml index 9c81e39e9cf..c4f5a16acb6 100644 --- a/eng/common/templates/post-build/channels/netcore-dev-5.yml +++ b/eng/common/templates/post-build/channels/netcore-dev-5.yml @@ -85,10 +85,14 @@ stages: - task: NuGetAuthenticate@0 displayName: 'Authenticate to AzDO Feeds' + - task: PowerShell@2 + displayName: Enable cross-org publishing + inputs: + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) + - task: PowerShell@2 displayName: Publish Assets - env: - AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw) inputs: filePath: eng\common\sdk-task.ps1 arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet diff --git a/eng/common/templates/post-build/channels/netcore-internal-30.yml b/eng/common/templates/post-build/channels/netcore-internal-30.yml index 594a1a9a78d..177b38df357 100644 --- a/eng/common/templates/post-build/channels/netcore-internal-30.yml +++ b/eng/common/templates/post-build/channels/netcore-internal-30.yml @@ -84,10 +84,14 @@ stages: - task: NuGetAuthenticate@0 displayName: 'Authenticate to AzDO Feeds' + - task: PowerShell@2 + displayName: Enable cross-org publishing + inputs: + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) + - task: PowerShell@2 displayName: Publish Assets - env: - AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw) inputs: filePath: eng\common\sdk-task.ps1 arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet @@ -107,9 +111,9 @@ stages: /p:Configuration=Release /p:PublishInstallersAndChecksums=true /p:ChecksumsTargetStaticFeed=$(InternalChecksumsBlobFeedUrl) - /p:ChecksumsTargetStaticFeedKey=$(InternalChecksumsBlobFeedKey) + /p:ChecksumsAzureAccountKey=$(InternalChecksumsBlobFeedKey) /p:InstallersTargetStaticFeed=$(InternalInstallersBlobFeedUrl) - /p:InstallersTargetStaticFeedKey=$(InternalInstallersBlobFeedKey) + /p:InstallersAzureAccountKey=$(InternalInstallersBlobFeedKey) /p:PublishToAzureDevOpsNuGetFeeds=true /p:AzureDevOpsStaticShippingFeed='https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal/nuget/v3/index.json' /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' @@ -121,4 +125,4 @@ stages: - template: ../../steps/promote-build.yml parameters: - ChannelId: ${{ variables.InternalServicing_30_Channel_Id }} \ No newline at end of file + ChannelId: ${{ variables.InternalServicing_30_Channel_Id }} diff --git a/eng/common/templates/post-build/channels/netcore-release-30.yml b/eng/common/templates/post-build/channels/netcore-release-30.yml index 8ba9237ffc0..16ade0db29d 100644 --- a/eng/common/templates/post-build/channels/netcore-release-30.yml +++ b/eng/common/templates/post-build/channels/netcore-release-30.yml @@ -85,10 +85,14 @@ stages: - task: NuGetAuthenticate@0 displayName: 'Authenticate to AzDO Feeds' + - task: PowerShell@2 + displayName: Enable cross-org publishing + inputs: + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) + - task: PowerShell@2 displayName: Publish Assets - env: - AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw) inputs: filePath: eng\common\sdk-task.ps1 arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet diff --git a/eng/common/templates/post-build/channels/netcore-release-31.yml b/eng/common/templates/post-build/channels/netcore-release-31.yml index d8270eadaea..01d56410c7d 100644 --- a/eng/common/templates/post-build/channels/netcore-release-31.yml +++ b/eng/common/templates/post-build/channels/netcore-release-31.yml @@ -85,10 +85,14 @@ stages: - task: NuGetAuthenticate@0 displayName: 'Authenticate to AzDO Feeds' + - task: PowerShell@2 + displayName: Enable cross-org publishing + inputs: + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) + - task: PowerShell@2 displayName: Publish Assets - env: - AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw) inputs: filePath: eng\common\sdk-task.ps1 arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet diff --git a/eng/common/templates/post-build/channels/netcore-tools-latest.yml b/eng/common/templates/post-build/channels/netcore-tools-latest.yml index c75d1867339..157d2d4b977 100644 --- a/eng/common/templates/post-build/channels/netcore-tools-latest.yml +++ b/eng/common/templates/post-build/channels/netcore-tools-latest.yml @@ -85,10 +85,14 @@ stages: - task: NuGetAuthenticate@0 displayName: 'Authenticate to AzDO Feeds' + - task: PowerShell@2 + displayName: Enable cross-org publishing + inputs: + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) + - task: PowerShell@2 displayName: Publish Assets - env: - AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw) inputs: filePath: eng\common\sdk-task.ps1 arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet diff --git a/eng/common/templates/post-build/channels/public-validation-release.yml b/eng/common/templates/post-build/channels/netcore-tools-validation.yml similarity index 90% rename from eng/common/templates/post-build/channels/public-validation-release.yml rename to eng/common/templates/post-build/channels/netcore-tools-validation.yml index fb2c23d0f4d..d8447e49af6 100644 --- a/eng/common/templates/post-build/channels/public-validation-release.yml +++ b/eng/common/templates/post-build/channels/netcore-tools-validation.yml @@ -21,7 +21,7 @@ stages: value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] - name: IsStableBuild value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ] - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.PublicValidationRelease_30_Channel_Id)) + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', variables.NetCore_Tools_Validation_Channel_Id)) pool: vmImage: 'windows-2019' steps: @@ -50,10 +50,14 @@ stages: - task: NuGetAuthenticate@0 displayName: 'Authenticate to AzDO Feeds' + - task: PowerShell@2 + displayName: Enable cross-org publishing + inputs: + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) + - task: PowerShell@2 displayName: Publish Assets - env: - AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-universal-packages-rw) inputs: filePath: eng\common\sdk-task.ps1 arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet @@ -88,4 +92,4 @@ stages: - template: ../../steps/promote-build.yml parameters: - ChannelId: ${{ variables.PublicValidationRelease_30_Channel_Id }} + ChannelId: ${{ variables.NetCore_Tools_Validation_Channel_Id }} diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml index adb2a854f20..b4eed6f186c 100644 --- a/eng/common/templates/post-build/common-variables.yml +++ b/eng/common/templates/post-build/common-variables.yml @@ -3,10 +3,6 @@ variables: - group: DotNet-DotNetCli-Storage - group: DotNet-MSRC-Storage - # .NET Core 3 Dev - - name: PublicDevRelease_30_Channel_Id - value: 3 - # .NET Core 3.1 Dev - name: PublicDevRelease_31_Channel_Id value: 128 @@ -16,13 +12,21 @@ variables: value: 131 # .NET Tools - Validation - - name: PublicValidationRelease_30_Channel_Id + - name: NetCore_Tools_Validation_Channel_Id value: 9 # .NET Tools - Latest - name: NetCore_Tools_Latest_Channel_Id value: 2 + # .NET 3 Tools - Validation + - name: NETCore_3_Tools_Validation_Channel_Id + value: 390 + + # .NET 3 Tools - Latest + - name: NetCore_3_Tools_Channel_Id + value: 344 + # .NET Core 3.0 Internal Servicing - name: InternalServicing_30_Channel_Id value: 184 diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index 5b9d0a5d99b..7ee82d9ff18 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -101,29 +101,34 @@ stages: artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} -- template: \eng\common\templates\post-build\channels\netcore-dev-30.yml +- template: \eng\common\templates\post-build\channels\netcore-dev-31.yml parameters: symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} -- template: \eng\common\templates\post-build\channels\netcore-dev-31.yml +- template: \eng\common\templates\post-build\channels\netcore-tools-latest.yml parameters: symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} -- template: \eng\common\templates\post-build\channels\netcore-tools-latest.yml +- template: \eng\common\templates\post-build\channels\netcore-tools-validation.yml parameters: - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} -- template: \eng\common\templates\post-build\channels\public-validation-release.yml +- template: \eng\common\templates\post-build\channels\netcore-3-tools-validation.yml parameters: artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} +- template: \eng\common\templates\post-build\channels\netcore-3-tools.yml + parameters: + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + - template: \eng\common\templates\post-build\channels\netcore-release-30.yml parameters: symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index bb5638930ab..91efea9405e 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -153,6 +153,16 @@ function InitializeDotNetCli([bool]$install) { # Make Sure that our bootstrapped dotnet cli is available in future steps of the Azure Pipelines build Write-PipelinePrependPath -Path $dotnetRoot + + # Work around issues with Azure Artifacts credential provider + # https://github.com/dotnet/arcade/issues/3932 + if ($ci) { + $env:NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS = 20 + $env:NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS = 20 + Write-PipelineSetVariable -Name 'NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS' -Value '20' + Write-PipelineSetVariable -Name 'NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS' -Value '20' + } + Write-PipelineSetVariable -Name 'DOTNET_MULTILEVEL_LOOKUP' -Value '0' Write-PipelineSetVariable -Name 'DOTNET_SKIP_FIRST_TIME_EXPERIENCE' -Value '1' @@ -365,7 +375,6 @@ function InitializeBuildTool() { Write-PipelineTelemetryError -Category "InitializeToolset" -Message "/global.json must specify 'tools.dotnet'." ExitWithExitCode 1 } - $buildTool = @{ Path = Join-Path $dotnetRoot "dotnet.exe"; Command = "msbuild"; Tool = "dotnet"; Framework = "netcoreapp2.1" } } elseif ($msbuildEngine -eq "vs") { try { @@ -490,6 +499,13 @@ function Stop-Processes() { function MSBuild() { if ($pipelinesLog) { $buildTool = InitializeBuildTool + + # Work around issues with Azure Artifacts credential provider + # https://github.com/dotnet/arcade/issues/3932 + if ($ci -and $buildTool.Tool -eq "dotnet") { + dotnet nuget locals http-cache -c + } + $toolsetBuildProject = InitializeToolset $path = Split-Path -parent $toolsetBuildProject $path = Join-Path $path (Join-Path $buildTool.Framework "Microsoft.DotNet.Arcade.Sdk.dll") diff --git a/eng/common/tools.sh b/eng/common/tools.sh index 94a1edd7d0b..757d5b9ea46 100755 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -152,6 +152,15 @@ function InitializeDotNetCli { # build steps from using anything other than what we've downloaded. Write-PipelinePrependPath -path "$dotnet_root" + # Work around issues with Azure Artifacts credential provider + # https://github.com/dotnet/arcade/issues/3932 + if [[ "$ci" == true ]]; then + export NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=20 + export NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=20 + Write-PipelineSetVariable -name "NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS" -value "20" + Write-PipelineSetVariable -name "NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS" -value "20" + fi + Write-PipelineSetVariable -name "DOTNET_MULTILEVEL_LOOKUP" -value "0" Write-PipelineSetVariable -name "DOTNET_SKIP_FIRST_TIME_EXPERIENCE" -value "1" @@ -328,6 +337,13 @@ function MSBuild { if [[ "$pipelines_log" == true ]]; then InitializeBuildTool InitializeToolset + + # Work around issues with Azure Artifacts credential provider + # https://github.com/dotnet/arcade/issues/3932 + if [[ "$ci" == true ]]; then + dotnet nuget locals http-cache -c + fi + local toolset_dir="${_InitializeToolset%/*}" local logger_path="$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.Arcade.Sdk.dll" args=( "${args[@]}" "-logger:$logger_path" ) diff --git a/global.json b/global.json index 2b51fa31f68..18cd03f616a 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "tools": { - "dotnet": "3.0.100-preview8-013656", + "dotnet": "3.0.100", "runtimes": { "dotnet": [ "2.0.9", @@ -9,9 +9,9 @@ } }, "sdk": { - "version": "3.0.100-preview8-013656" + "version": "3.0.100" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19461.7" + "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19474.3" } } diff --git a/test/EFCore.Cosmos.FunctionalTests/Internal/CosmosDatabaseCreatorTest.cs b/test/EFCore.Cosmos.FunctionalTests/Internal/CosmosDatabaseCreatorTest.cs index 95ea2f7dd16..beb6da2cc70 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Internal/CosmosDatabaseCreatorTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Internal/CosmosDatabaseCreatorTest.cs @@ -54,7 +54,7 @@ public async Task EnsureCreated_returns_false_when_database_and_collections_exis { await using (var testDatabase = CosmosTestStore.Create("EnsureCreatedReady")) { - testDatabase.Initialize(null, () => new BloggingContext(testDatabase), null); + testDatabase.Initialize(null, testStore => new BloggingContext((CosmosTestStore)testStore)); using (var context = new BloggingContext(testDatabase)) { diff --git a/test/EFCore.CrossStore.FunctionalTests/ConfigurationPatternsTest.cs b/test/EFCore.CrossStore.FunctionalTests/ConfigurationPatternsTest.cs index 71294832060..65843463ca3 100644 --- a/test/EFCore.CrossStore.FunctionalTests/ConfigurationPatternsTest.cs +++ b/test/EFCore.CrossStore.FunctionalTests/ConfigurationPatternsTest.cs @@ -4,19 +4,25 @@ using System; using System.Linq; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore.TestModels; using Microsoft.EntityFrameworkCore.TestUtilities; using Microsoft.EntityFrameworkCore.TestUtilities.Xunit; using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable UnusedMember.Local - // ReSharper disable InconsistentNaming namespace Microsoft.EntityFrameworkCore { [SqlServerConfiguredCondition] - public class ConfigurationPatternsTest + public class ConfigurationPatternsTest : IClassFixture { + public ConfigurationPatternsTest(CrossStoreFixture fixture) + { + Fixture = fixture; + ExistingTestStore = Fixture.CreateTestStore(SqlServerTestStoreFactory.Instance, StoreName, Seed); + } + [ConditionalFact] public void Can_register_multiple_context_types() { @@ -25,38 +31,32 @@ public void Can_register_multiple_context_types() .AddDbContext() .BuildServiceProvider(); - using (SqlServerTestStore.GetNorthwindStore()) + using (var context = serviceProvider.GetRequiredService()) { - using (var context = serviceProvider.GetRequiredService()) - { - Assert.True(context.Customers.Any()); - } + Assert.True(context.SimpleEntities.Any()); + } - using (var context = serviceProvider.GetRequiredService()) - { - Assert.False(context.Customers.Any()); - } + using (var context = serviceProvider.GetRequiredService()) + { + Assert.False(context.SimpleEntities.Any()); } } [ConditionalFact] public void Can_register_multiple_context_types_with_default_service_provider() { - using (SqlServerTestStore.GetNorthwindStore()) + using (var context = new MultipleContext1(new DbContextOptions())) { - using (var context = new MultipleContext1(new DbContextOptions())) - { - Assert.True(context.Customers.Any()); - } + Assert.True(context.SimpleEntities.Any()); + } - using (var context = new MultipleContext2(new DbContextOptions())) - { - Assert.False(context.Customers.Any()); - } + using (var context = new MultipleContext2(new DbContextOptions())) + { + Assert.False(context.SimpleEntities.Any()); } } - private class MultipleContext1 : NorthwindContextBase + private class MultipleContext1 : CrossStoreContext { private readonly DbContextOptions _options; @@ -70,13 +70,13 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { Assert.Same(_options, optionsBuilder.Options); - optionsBuilder.UseSqlServer(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString, b => b.ApplyConfiguration()); + optionsBuilder.UseSqlServer(SqlServerTestStore.CreateConnectionString(StoreName), b => b.ApplyConfiguration()); Assert.NotSame(_options, optionsBuilder.Options); } } - private class MultipleContext2 : NorthwindContextBase + private class MultipleContext2 : CrossStoreContext { private readonly DbContextOptions _options; @@ -90,7 +90,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { Assert.Same(_options, optionsBuilder.Options); - optionsBuilder.UseInMemoryDatabase(nameof(NorthwindContextBase)); + optionsBuilder.UseInMemoryDatabase(StoreName); Assert.NotSame(_options, optionsBuilder.Options); } @@ -105,94 +105,63 @@ var serviceProvider .AddDbContext() .BuildServiceProvider(); - using (SqlServerTestStore.GetNorthwindStore()) - { - MultipleProvidersContext context1; - MultipleProvidersContext context2; + MultipleProvidersContext context1; + MultipleProvidersContext context2; - using (var serviceScope = serviceProvider.GetRequiredService().CreateScope()) + using (var serviceScope = serviceProvider.GetRequiredService().CreateScope()) + { + using (context1 = serviceScope.ServiceProvider.GetRequiredService()) { - using (context1 = serviceScope.ServiceProvider.GetRequiredService()) - { - context1.UseSqlServer = true; - - Assert.True(context1.Customers.Any()); - } + context1.UseSqlServer = true; - using (var context1B = serviceScope.ServiceProvider.GetRequiredService()) - { - Assert.Same(context1, context1B); - } - - var someService = serviceScope.ServiceProvider.GetRequiredService(); - Assert.Same(context1, someService.Context); + Assert.True(context1.SimpleEntities.Any()); } - using (var serviceScope = serviceProvider.GetRequiredService().CreateScope()) + using (var context1B = serviceScope.ServiceProvider.GetRequiredService()) { - using (context2 = serviceScope.ServiceProvider.GetRequiredService()) - { - context2.UseSqlServer = false; - - Assert.False(context2.Customers.Any()); - } - - using (var context2B = serviceScope.ServiceProvider.GetRequiredService()) - { - Assert.Same(context2, context2B); - } - - var someService = serviceScope.ServiceProvider.GetRequiredService(); - Assert.Same(context2, someService.Context); + Assert.Same(context1, context1B); } - Assert.NotSame(context1, context2); + var someService = serviceScope.ServiceProvider.GetRequiredService(); + Assert.Same(context1, someService.Context); } - } - [ConditionalFact] - public void Can_select_appropriate_provider_when_multiple_registered_with_default_service_provider() - { - using (SqlServerTestStore.GetNorthwindStore()) + using (var serviceScope = serviceProvider.GetRequiredService().CreateScope()) { - using (var context = new MultipleProvidersContext()) + using (context2 = serviceScope.ServiceProvider.GetRequiredService()) { - context.UseSqlServer = true; + context2.UseSqlServer = false; - Assert.True(context.Customers.Any()); + Assert.False(context2.SimpleEntities.Any()); } - using (var context = new MultipleProvidersContext()) + using (var context2B = serviceScope.ServiceProvider.GetRequiredService()) { - context.UseSqlServer = false; - - Assert.False(context.Customers.Any()); + Assert.Same(context2, context2B); } + + var someService = serviceScope.ServiceProvider.GetRequiredService(); + Assert.Same(context2, someService.Context); } + + Assert.NotSame(context1, context2); } - private class NorthwindContextBase : DbContext + [ConditionalFact] + public void Can_select_appropriate_provider_when_multiple_registered_with_default_service_provider() { - protected NorthwindContextBase() + using (var context = new MultipleProvidersContext()) { - } + context.UseSqlServer = true; - protected NorthwindContextBase(DbContextOptions options) - : base(options) - { + Assert.True(context.SimpleEntities.Any()); } - // ReSharper disable once UnusedAutoPropertyAccessor.Local - public DbSet Customers { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) + using (var context = new MultipleProvidersContext()) { - modelBuilder.Entity( - b => - { - b.HasKey(c => c.CustomerID); - b.ToTable("Customers"); - }); + context.UseSqlServer = false; + + Assert.False(context.SimpleEntities.Any()); } } @@ -206,7 +175,7 @@ private class Customer public string Fax { get; set; } } - private class MultipleProvidersContext : NorthwindContextBase + private class MultipleProvidersContext : CrossStoreContext { // ReSharper disable once MemberCanBePrivate.Local public bool UseSqlServer { get; set; } @@ -215,11 +184,11 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (UseSqlServer) { - optionsBuilder.UseSqlServer(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString, b => b.ApplyConfiguration()); + optionsBuilder.UseSqlServer(SqlServerTestStore.CreateConnectionString(StoreName), b => b.ApplyConfiguration()); } else { - optionsBuilder.UseInMemoryDatabase(nameof(NorthwindContextBase)); + optionsBuilder.UseInMemoryDatabase(StoreName); } } } @@ -235,51 +204,57 @@ public SomeService(MultipleProvidersContext context) public MultipleProvidersContext Context { get; } } + private CrossStoreFixture Fixture { get; } + private TestStore ExistingTestStore { get; } + private static readonly string StoreName = "CrossStoreConfigurationPatternsTest"; + + private void Seed(CrossStoreContext context) + { + context.SimpleEntities.Add(new SimpleEntity { StringProperty = "Entity 1" }); + + context.SaveChanges(); + } + + public void Dispose() => ExistingTestStore.Dispose(); + [SqlServerConfiguredCondition] - public class NestedContextDifferentStores + public class NestedContextDifferentStores : IClassFixture { + public NestedContextDifferentStores(CrossStoreFixture fixture) + { + Fixture = fixture; + ExistingTestStore = Fixture.CreateTestStore(SqlServerTestStoreFactory.Instance, StoreName, Seed); + } + [ConditionalFact] public async Task Can_use_one_context_nested_inside_another_of_a_different_type() { - using (SqlServerTestStore.GetNorthwindStore()) - { - var inMemoryServiceProvider = InMemoryFixture.DefaultServiceProvider; - var sqlServerServiceProvider = SqlServerFixture.DefaultServiceProvider; + var inMemoryServiceProvider = InMemoryFixture.DefaultServiceProvider; + var sqlServerServiceProvider = SqlServerFixture.DefaultServiceProvider; - await NestedContextTest( - () => new BlogContext(inMemoryServiceProvider), - () => new NorthwindContext(sqlServerServiceProvider)); - } + await NestedContextTest( + () => new BlogContext(inMemoryServiceProvider), + () => new ExternalProviderContext(sqlServerServiceProvider)); } [ConditionalFact] - public async Task Can_use_one_context_nested_inside_another_of_a_different_type_with_implicit_services() - { - using (SqlServerTestStore.GetNorthwindStore()) - { - await NestedContextTest(() => new BlogContext(), () => new NorthwindContext()); - } - } + public Task Can_use_one_context_nested_inside_another_of_a_different_type_with_implicit_services() + => NestedContextTest(() => new BlogContext(), () => new ExternalProviderContext()); - private async Task NestedContextTest(Func createBlogContext, Func createNorthwindContext) + private async Task NestedContextTest(Func createBlogContext, Func createSimpleContext) { using (var context0 = createBlogContext()) { Assert.Equal(0, context0.ChangeTracker.Entries().Count()); - var blog0 = context0.Add( - new Blog - { - Id = 1, - Name = "Giddyup" - }).Entity; + var blog0 = context0.Add(new Blog { Id = 1, Name = "Giddyup" }).Entity; Assert.Same(blog0, context0.ChangeTracker.Entries().Select(e => e.Entity).Single()); await context0.SaveChangesAsync(); - using (var context1 = createNorthwindContext()) + using (var context1 = createSimpleContext()) { - var customers1 = await context1.Customers.ToListAsync(); - Assert.Equal(91, customers1.Count); - Assert.Equal(91, context1.ChangeTracker.Entries().Count()); + var customers1 = await context1.SimpleEntities.ToListAsync(); + Assert.Equal(1, customers1.Count); + Assert.Equal(1, context1.ChangeTracker.Entries().Count()); Assert.Same(blog0, context0.ChangeTracker.Entries().Select(e => e.Entity).Single()); using (var context2 = createBlogContext()) @@ -297,6 +272,19 @@ private async Task NestedContextTest(Func createBlogContext, Func ExistingTestStore.Dispose(); + private class BlogContext : DbContext { private readonly IServiceProvider _serviceProvider; @@ -324,22 +312,22 @@ private class Blog public string Name { get; set; } } - private class NorthwindContext : NorthwindContextBase + private class ExternalProviderContext : CrossStoreContext { private readonly IServiceProvider _serviceProvider; - public NorthwindContext() + public ExternalProviderContext() { } - public NorthwindContext(IServiceProvider serviceProvider) + public ExternalProviderContext(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder - .UseSqlServer(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString, b => b.ApplyConfiguration()) + .UseSqlServer(SqlServerTestStore.CreateConnectionString(StoreName), b => b.ApplyConfiguration()) .UseInternalServiceProvider(_serviceProvider); } } diff --git a/test/EFCore.CrossStore.FunctionalTests/CrossStoreFixture.cs b/test/EFCore.CrossStore.FunctionalTests/CrossStoreFixture.cs index 00513c04ef1..27a537f017b 100644 --- a/test/EFCore.CrossStore.FunctionalTests/CrossStoreFixture.cs +++ b/test/EFCore.CrossStore.FunctionalTests/CrossStoreFixture.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.EntityFrameworkCore.TestModels; using Microsoft.EntityFrameworkCore.TestUtilities; using Microsoft.Extensions.DependencyInjection; @@ -9,8 +10,6 @@ namespace Microsoft.EntityFrameworkCore { public class CrossStoreFixture : FixtureBase { - protected virtual string StoreName { get; } = "CrossStoreTest"; - public DbContextOptions CreateOptions(TestStore testStore) => AddOptions(testStore.AddProviderOptions(new DbContextOptionsBuilder())) .UseInternalServiceProvider(testStore.ServiceProvider) @@ -19,24 +18,11 @@ public DbContextOptions CreateOptions(TestStore testStore) public CrossStoreContext CreateContext(TestStore testStore) => new CrossStoreContext(CreateOptions(testStore)); - public TestStore CreateTestStore(ITestStoreFactory testStoreFactory) - { - return testStoreFactory.GetOrCreate(StoreName) + public TestStore CreateTestStore(ITestStoreFactory testStoreFactory, string storeName, Action seed = null) + => testStoreFactory.GetOrCreate(storeName) .Initialize( - AddServices(testStoreFactory.AddProviderServices(new ServiceCollection())) - .BuildServiceProvider(validateScopes: true), CreateContext, c => { }, null); - } - - protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) - { - modelBuilder.Entity( - eb => - { - eb.ToTable("RelationalSimpleEntity"); - eb.Property(typeof(string), SimpleEntity.ShadowPropertyName); - eb.HasKey(e => e.Id); - eb.Property(e => e.Id).UseIdentityColumn(); - }); - } + AddServices(testStoreFactory.AddProviderServices(new ServiceCollection())).BuildServiceProvider(validateScopes: true), + CreateContext, + seed); } } diff --git a/test/EFCore.CrossStore.FunctionalTests/DiscriminatorTest.cs b/test/EFCore.CrossStore.FunctionalTests/DiscriminatorTest.cs index e14f962e966..dd690a777a5 100644 --- a/test/EFCore.CrossStore.FunctionalTests/DiscriminatorTest.cs +++ b/test/EFCore.CrossStore.FunctionalTests/DiscriminatorTest.cs @@ -10,7 +10,7 @@ namespace Microsoft.EntityFrameworkCore { public class DiscriminatorTest { - [ConditionalFact(Skip = "Tasklist#21")] + [ConditionalFact] public void Can_save_entities_with_discriminators() { using (var context = new Context4285()) @@ -38,7 +38,7 @@ public void Can_save_entities_with_discriminators() } } - [ConditionalFact(Skip = "Tasklist#21")] + [ConditionalFact] public void Can_save_entities_with_int_discriminators() { using (var context = new Context4285()) @@ -66,7 +66,7 @@ public void Can_save_entities_with_int_discriminators() } } - private class BaseProduct + private abstract class BaseProduct { public Guid Id { get; set; } } @@ -81,7 +81,7 @@ private class SubProduct2 : BaseProduct public string SomeName2 { get; set; } } - private class BaseIntProduct + private abstract class BaseIntProduct { public Guid Id { get; set; } } diff --git a/test/EFCore.CrossStore.FunctionalTests/EFCore.CrossStore.FunctionalTests.csproj b/test/EFCore.CrossStore.FunctionalTests/EFCore.CrossStore.FunctionalTests.csproj index 73d1f45cfe2..4d1ba613b61 100644 --- a/test/EFCore.CrossStore.FunctionalTests/EFCore.CrossStore.FunctionalTests.csproj +++ b/test/EFCore.CrossStore.FunctionalTests/EFCore.CrossStore.FunctionalTests.csproj @@ -4,8 +4,6 @@ netcoreapp3.0 Microsoft.EntityFrameworkCore.CrossStore.FunctionalTests Microsoft.EntityFrameworkCore - - CrossStore.FunctionalTests ..\..\EFCore.ruleset diff --git a/test/EFCore.CrossStore.FunctionalTests/EndToEndTest.cs b/test/EFCore.CrossStore.FunctionalTests/EndToEndTest.cs index 717e17d82ad..379fc2629a0 100644 --- a/test/EFCore.CrossStore.FunctionalTests/EndToEndTest.cs +++ b/test/EFCore.CrossStore.FunctionalTests/EndToEndTest.cs @@ -16,7 +16,7 @@ public abstract class EndToEndTest : IDisposable protected EndToEndTest(CrossStoreFixture fixture) { Fixture = fixture; - TestStore = Fixture.CreateTestStore(TestStoreFactory); + TestStore = Fixture.CreateTestStore(TestStoreFactory, "CrossStoreTest"); } protected CrossStoreFixture Fixture { get; } diff --git a/test/EFCore.CrossStore.FunctionalTests/TestModels/CrossStoreContext.cs b/test/EFCore.CrossStore.FunctionalTests/TestModels/CrossStoreContext.cs index 3ca233a89a0..2ccd0631023 100644 --- a/test/EFCore.CrossStore.FunctionalTests/TestModels/CrossStoreContext.cs +++ b/test/EFCore.CrossStore.FunctionalTests/TestModels/CrossStoreContext.cs @@ -5,6 +5,11 @@ namespace Microsoft.EntityFrameworkCore.TestModels { public class CrossStoreContext : DbContext { + public CrossStoreContext() + : base() + { + } + public CrossStoreContext(DbContextOptions options) : base(options) { @@ -12,6 +17,18 @@ public CrossStoreContext(DbContextOptions options) public virtual DbSet SimpleEntities { get; set; } + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity( + eb => + { + eb.ToTable("RelationalSimpleEntity"); + eb.Property(typeof(string), SimpleEntity.ShadowPropertyName); + eb.HasKey(e => e.Id); + eb.Property(e => e.Id).UseIdentityColumn(); + }); + } + public static void RemoveAllEntities(CrossStoreContext context) => context.SimpleEntities.RemoveRange(context.SimpleEntities); } diff --git a/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalDatabaseCleaner.cs b/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalDatabaseCleaner.cs index 54c44f58a77..ec466a9d208 100644 --- a/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalDatabaseCleaner.cs +++ b/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalDatabaseCleaner.cs @@ -1,8 +1,11 @@ // Copyright (c) .NET Foundation. All rights reserved. // 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.Text; +using System.Text.RegularExpressions; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; @@ -83,9 +86,7 @@ public virtual void Clean(DatabaseFacade facade) var customSql = BuildCustomSql(databaseModel); if (!string.IsNullOrWhiteSpace(customSql)) { - sqlBuilder.Build(customSql).ExecuteNonQuery( - new RelationalCommandParameterObject( - connection,null, null,null)); + ExecuteScript(connection, sqlBuilder, customSql); } if (operations.Count > 0) @@ -97,8 +98,7 @@ public virtual void Clean(DatabaseFacade facade) customSql = BuildCustomEndingSql(databaseModel); if (!string.IsNullOrWhiteSpace(customSql)) { - sqlBuilder.Build(customSql).ExecuteNonQuery( - new RelationalCommandParameterObject(connection, null, null, null)); + ExecuteScript(connection, sqlBuilder, customSql); } } finally @@ -110,6 +110,31 @@ public virtual void Clean(DatabaseFacade facade) creator.CreateTables(); } + private static void ExecuteScript(IRelationalConnection connection, IRawSqlCommandBuilder sqlBuilder, string customSql) + { + var batches = Regex.Split( + Regex.Replace( + customSql, + @"\\\r?\n", + string.Empty, + default, + TimeSpan.FromMilliseconds(1000.0)), + @"^\s*(GO[ \t]+[0-9]+|GO)(?:\s+|$)", + RegexOptions.IgnoreCase | RegexOptions.Multiline, + TimeSpan.FromMilliseconds(1000.0)); + for (var i = 0; i < batches.Length; i++) + { + if (batches[i].StartsWith("GO", StringComparison.OrdinalIgnoreCase) + || string.IsNullOrWhiteSpace(batches[i])) + { + continue; + } + + sqlBuilder.Build(batches[i]) + .ExecuteNonQuery(new RelationalCommandParameterObject(connection, null, null, null)); + } + } + protected virtual MigrationOperation Drop(DatabaseSequence sequence) => new DropSequenceOperation { diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestStore.cs b/test/EFCore.Specification.Tests/TestUtilities/TestStore.cs index fb7e3448986..5b6e626dd5e 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestStore.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestStore.cs @@ -25,7 +25,10 @@ protected TestStore(string name, bool shared) public string Name { get; protected set; } public virtual TestStore Initialize( - IServiceProvider serviceProvider, Func createContext, Action seed = null, Action clean = null) + IServiceProvider serviceProvider, + Func createContext, + Action seed = null, + Action clean = null) { ServiceProvider = serviceProvider; if (createContext == null) @@ -45,10 +48,25 @@ public virtual TestStore Initialize( return this; } - public TestStore Initialize( - IServiceProvider serviceProvider, Func createContext, Action seed = null, Action clean = null) + public virtual TestStore Initialize( + IServiceProvider serviceProvider, + Func createContext, + Action seed = null, + Action clean = null) => Initialize(serviceProvider, () => createContext(this), seed, clean); + public virtual TestStore Initialize( + IServiceProvider serviceProvider, + Func createContext, + Action seed = null, + Action clean = null) + where TContext : DbContext + => Initialize( + serviceProvider, + createContext, + seed == null ? (Action)null : c => seed((TContext)c), + clean == null ? (Action)null : c => clean((TContext)c)); + protected virtual void Initialize(Func createContext, Action seed, Action clean) { using (var context = createContext()) diff --git a/test/EFCore.SqlServer.FunctionalTests/EFCore.SqlServer.FunctionalTests.csproj b/test/EFCore.SqlServer.FunctionalTests/EFCore.SqlServer.FunctionalTests.csproj index 9bd6d0e753d..3a0ceb7aa00 100644 --- a/test/EFCore.SqlServer.FunctionalTests/EFCore.SqlServer.FunctionalTests.csproj +++ b/test/EFCore.SqlServer.FunctionalTests/EFCore.SqlServer.FunctionalTests.csproj @@ -4,8 +4,6 @@ netcoreapp3.0 Microsoft.EntityFrameworkCore.SqlServer.FunctionalTests Microsoft.EntityFrameworkCore - - SqlServer.FunctionalTests ..\..\EFCore.ruleset True diff --git a/test/EFCore.SqlServer.FunctionalTests/MigrationsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/MigrationsSqlServerTest.cs index 971a4f20fcb..da255acf5e4 100644 --- a/test/EFCore.SqlServer.FunctionalTests/MigrationsSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/MigrationsSqlServerTest.cs @@ -20,7 +20,7 @@ // ReSharper disable InconsistentNaming namespace Microsoft.EntityFrameworkCore { - [SqlServerCondition(SqlServerCondition.IsNotSqlAzure)] + [SqlServerCondition(SqlServerCondition.IsNotSqlAzure | SqlServerCondition.IsNotCI)] public class MigrationsSqlServerTest : MigrationsTestBase { public MigrationsSqlServerTest(MigrationsSqlServerFixture fixture) diff --git a/test/EFCore.SqlServer.FunctionalTests/SequenceEndToEndTest.cs b/test/EFCore.SqlServer.FunctionalTests/SequenceEndToEndTest.cs index 1f126df4877..6a58d2b30b0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SequenceEndToEndTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SequenceEndToEndTest.cs @@ -75,7 +75,7 @@ private static void AddEntities(IServiceProvider serviceProvider, string name) } [ConditionalFact] - [PlatformSkipCondition(TestPlatform.Linux, SkipReason = "Test is flaky on CI.")] + [SqlServerCondition(SqlServerCondition.IsNotCI)] public void Can_use_sequence_end_to_end_on_multiple_databases() { var serviceProvider = new ServiceCollection() diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerDatabaseCreatorTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerDatabaseCreatorTest.cs index dac17aa6d86..479391e0147 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlServerDatabaseCreatorTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerDatabaseCreatorTest.cs @@ -55,17 +55,20 @@ private static async Task Returns_false_when_database_does_not_exist_test( { var creator = GetDatabaseCreator(context); - using (CreateTransactionScope(ambientTransaction)) + await context.Database.CreateExecutionStrategy().ExecuteAsync(async () => { - if (useCanConnect) - { - Assert.False(async ? await creator.CanConnectAsync() : creator.CanConnect()); - } - else + using (CreateTransactionScope(ambientTransaction)) { - Assert.False(async ? await creator.ExistsAsync() : creator.Exists()); + if (useCanConnect) + { + Assert.False(async ? await creator.CanConnectAsync() : creator.CanConnect()); + } + else + { + Assert.False(async ? await creator.ExistsAsync() : creator.Exists()); + } } - } + }); Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); } @@ -102,17 +105,21 @@ private static async Task Returns_true_when_database_exists_test(bool async, boo using (var context = new BloggingContext(testDatabase)) { var creator = GetDatabaseCreator(context); - using (CreateTransactionScope(ambientTransaction)) + + await context.Database.CreateExecutionStrategy().ExecuteAsync(async () => { - if (useCanConnect) - { - Assert.True(async ? await creator.CanConnectAsync() : creator.CanConnect()); - } - else + using (CreateTransactionScope(ambientTransaction)) { - Assert.True(async ? await creator.ExistsAsync() : creator.Exists()); + if (useCanConnect) + { + Assert.True(async ? await creator.CanConnectAsync() : creator.CanConnect()); + } + else + { + Assert.True(async ? await creator.ExistsAsync() : creator.Exists()); + } } - } + }); Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); } @@ -159,17 +166,20 @@ private static async Task Delete_database_test(bool async, bool open, bool ambie Assert.True(async ? await creator.ExistsAsync() : creator.Exists()); - using (CreateTransactionScope(ambientTransaction)) + await GetExecutionStrategy(testDatabase).ExecuteAsync(async () => { - if (async) + using (CreateTransactionScope(ambientTransaction)) { - Assert.True(await context.Database.EnsureDeletedAsync()); - } - else - { - Assert.True(context.Database.EnsureDeleted()); + if (async) + { + Assert.True(await context.Database.EnsureDeletedAsync()); + } + else + { + Assert.True(context.Database.EnsureDeleted()); + } } - } + }); Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); @@ -430,10 +440,14 @@ public async Task Returns_false_when_database_exists_but_has_no_tables(bool asyn using (var testDatabase = SqlServerTestStore.GetOrCreateInitialized("Empty")) { var creator = GetDatabaseCreator(testDatabase); - using (CreateTransactionScope(ambientTransaction)) + + await GetExecutionStrategy(testDatabase).ExecuteAsync(async () => { - Assert.False(async ? await creator.HasTablesAsyncBase() : creator.HasTablesBase()); - } + using (CreateTransactionScope(ambientTransaction)) + { + Assert.False(async ? await creator.HasTablesAsyncBase() : creator.HasTablesBase()); + } + }); } } @@ -446,10 +460,14 @@ public async Task Returns_true_when_database_exists_and_has_any_tables(bool asyn .InitializeSqlServer(null, t => new BloggingContext(t), null)) { var creator = GetDatabaseCreator(testDatabase); - using (CreateTransactionScope(ambientTransaction)) + + await GetExecutionStrategy(testDatabase).ExecuteAsync(async () => { - Assert.True(async ? await creator.HasTablesAsyncBase() : creator.HasTablesBase()); - } + using (CreateTransactionScope(ambientTransaction)) + { + Assert.True(async ? await creator.HasTablesAsyncBase() : creator.HasTablesBase()); + } + }); } } } @@ -646,17 +664,20 @@ public async Task Creates_physical_database_but_not_tables(bool async, bool ambi creator.EnsureDeleted(); - using (CreateTransactionScope(ambientTransaction)) + await GetExecutionStrategy(testDatabase).ExecuteAsync(async () => { - if (async) - { - await creator.CreateAsync(); - } - else + using (CreateTransactionScope(ambientTransaction)) { - creator.Create(); + if (async) + { + await creator.CreateAsync(); + } + else + { + creator.Create(); + } } - } + }); Assert.True(creator.Exists()); @@ -701,18 +722,21 @@ public async Task Throws_if_database_already_exists(bool async) [SqlServerCondition(SqlServerCondition.IsNotSqlAzure | SqlServerCondition.IsNotCI)] public class SqlServerDatabaseCreatorTest { - public static IDisposable CreateTransactionScope(bool useTransaction) + protected static IDisposable CreateTransactionScope(bool useTransaction) => TestStore.CreateTransactionScope(useTransaction); - public static TestDatabaseCreator GetDatabaseCreator(SqlServerTestStore testStore) + protected static TestDatabaseCreator GetDatabaseCreator(SqlServerTestStore testStore) => GetDatabaseCreator(testStore.ConnectionString); - public static TestDatabaseCreator GetDatabaseCreator(string connectionString) + protected static TestDatabaseCreator GetDatabaseCreator(string connectionString) => GetDatabaseCreator(new BloggingContext(connectionString)); - public static TestDatabaseCreator GetDatabaseCreator(BloggingContext context) + protected static TestDatabaseCreator GetDatabaseCreator(BloggingContext context) => (TestDatabaseCreator)context.GetService(); + protected static IExecutionStrategy GetExecutionStrategy(SqlServerTestStore testStore) + => new BloggingContext(testStore).GetService().Create(); + // ReSharper disable once ClassNeverInstantiated.Local private class TestSqlServerExecutionStrategyFactory : SqlServerExecutionStrategyFactory { diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/DbContextOptionsBuilderExtensions.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/DbContextOptionsBuilderExtensions.cs index 6b0af11d900..0c2c9b3190a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/DbContextOptionsBuilderExtensions.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/DbContextOptionsBuilderExtensions.cs @@ -21,10 +21,7 @@ public static SqlServerDbContextOptionsBuilder ApplyConfiguration(this SqlServer optionsBuilder.UseRowNumberForPaging(); } - if (TestEnvironment.IsSqlAzure) - { - optionsBuilder.ExecutionStrategy(c => new TestSqlServerRetryingExecutionStrategy(c)); - } + optionsBuilder.ExecutionStrategy(c => new TestSqlServerRetryingExecutionStrategy(c)); return optionsBuilder; } diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerDatabaseCleaner.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerDatabaseCleaner.cs index a80b8b4aee2..bb4d1f37c71 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerDatabaseCleaner.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerDatabaseCleaner.cs @@ -23,12 +23,13 @@ protected override IDatabaseModelFactory CreateDatabaseModelFactory(ILoggerFacto new DiagnosticListener("Fake"), new SqlServerLoggingDefinitions())); + protected override bool AcceptTable(DatabaseTable table) => !(table is DatabaseView); + protected override bool AcceptIndex(DatabaseIndex index) => false; - protected override string BuildCustomSql(DatabaseModel databaseModel) - => @" -DECLARE @name VARCHAR(MAX) = '__dummy__', @SQL VARCHAR(MAX); + private readonly string _dropViewsSql = @" +DECLARE @name VARCHAR(MAX) = '__dummy__', @SQL VARCHAR(MAX) = ''; WHILE @name IS NOT NULL BEGIN @@ -49,8 +50,13 @@ FROM sys.sql_expression_dependencies AS sed EXEC (@SQL) END"; + protected override string BuildCustomSql(DatabaseModel databaseModel) + => _dropViewsSql; + protected override string BuildCustomEndingSql(DatabaseModel databaseModel) - => @" + => _dropViewsSql + @" +GO + DECLARE @SQL VARCHAR(MAX) = ''; SELECT @SQL = @SQL + 'DROP FUNCTION ' + QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME) + ';' FROM [INFORMATION_SCHEMA].[ROUTINES] WHERE ROUTINE_TYPE = 'FUNCTION' AND ROUTINE_BODY = 'SQL'; diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerTestStore.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerTestStore.cs index e983f56c05c..3d149b329b3 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerTestStore.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerTestStore.cs @@ -109,7 +109,9 @@ private bool CreateDatabase(Action clean) { if (ExecuteScalar(master, $"SELECT COUNT(*) FROM sys.databases WHERE name = N'{Name}'") > 0) { - if (_scriptPath != null) + // Only reseed scripted databases during CI runs + if (_scriptPath != null + && !TestEnvironment.IsCI) { return false; }