From b6268e36505ece94d2ba5f8b4d2842ce59dedaae Mon Sep 17 00:00:00 2001 From: Jan Skovgaard <1932158+BatJan@users.noreply.github.com> Date: Tue, 14 Sep 2021 07:54:46 +0200 Subject: [PATCH 01/29] Bump version to 8.17.0-rc2 --- src/SolutionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 143df3dc46..e18eabbfc8 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -19,4 +19,4 @@ using System.Resources; // these are FYI and changed automatically [assembly: AssemblyFileVersion("8.17.0")] -[assembly: AssemblyInformationalVersion("8.17.0-rc")] +[assembly: AssemblyInformationalVersion("8.17.0-rc2")] From 74a232d9896336a00068a2eb6e9813003647858b Mon Sep 17 00:00:00 2001 From: Blake Irwin Date: Wed, 29 Sep 2021 23:44:40 +1300 Subject: [PATCH 02/29] Execute CopyUmbracoAssets @ BeforeBuild to prevent Rebuild failures --- build/NuSpecs/build/Umbraco.Cms.StaticAssets.targets | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build/NuSpecs/build/Umbraco.Cms.StaticAssets.targets b/build/NuSpecs/build/Umbraco.Cms.StaticAssets.targets index 0d712e083b..d271653e44 100644 --- a/build/NuSpecs/build/Umbraco.Cms.StaticAssets.targets +++ b/build/NuSpecs/build/Umbraco.Cms.StaticAssets.targets @@ -6,9 +6,8 @@ umbraco - + - From bceebea1588be2a1378aa99616ff99d3f716be15 Mon Sep 17 00:00:00 2001 From: Paul Johnson Date: Wed, 29 Sep 2021 11:51:28 +0100 Subject: [PATCH 03/29] V9 Move sln files to root (#11212) * Move sln files to root * Fix tests * Misc cleanup - remove unused helper * Document the esoteric nature of UmbracoWebApplicationFactory * Avoid unnecessary change to TestHelper WorkingDirectory --- build/azure-pipelines.yml | 2 +- build/build.ps1 | 4 +- .../Runtime/CoreRuntime.cs | 8 +- src/Umbraco.Tests.Common/TestHelperBase.cs | 16 +-- .../Implementations/TestHelper.cs | 38 ----- .../UmbracoTestServerTestBase.cs | 18 ++- .../Umbraco.Tests.Integration.csproj | 3 +- .../TestHelpers/TestHelper.cs | 9 -- src/Umbraco.Tests/TestHelpers/TestHelper.cs | 11 -- ...tcore-only.sln => umbraco-netcore-only.sln | 130 +++++++++--------- src/umbraco.sln => umbraco.sln | 122 ++++++++-------- ...sln.DotSettings => umbraco.sln.DotSettings | 2 +- 12 files changed, 155 insertions(+), 208 deletions(-) rename src/umbraco-netcore-only.sln => umbraco-netcore-only.sln (68%) rename src/umbraco.sln => umbraco.sln (71%) rename src/umbraco.sln.DotSettings => umbraco.sln.DotSettings (96%) diff --git a/build/azure-pipelines.yml b/build/azure-pipelines.yml index c9e29d84b1..9d931122d0 100644 --- a/build/azure-pipelines.yml +++ b/build/azure-pipelines.yml @@ -373,7 +373,7 @@ stages: - task: NuGetCommand@2 displayName: Restore NuGet Packages inputs: - restoreSolution: '*\src\umbraco.sln' + restoreSolution: 'umbraco.sln' feedsToUse: config - task: PowerShell@1 displayName: Update Version and Artifact Name diff --git a/build/build.ps1 b/build/build.ps1 index acc3351be7..02510d94ae 100644 --- a/build/build.ps1 +++ b/build/build.ps1 @@ -390,7 +390,7 @@ Write-Host "Restore NuGet" Write-Host "Logging to $($this.BuildTemp)\nuget.restore.log" $params = "-Source", $nugetsourceUmbraco - &$this.BuildEnv.NuGet restore "$($this.SolutionRoot)\src\umbraco-netcore-only.sln" > "$($this.BuildTemp)\nuget.restore.log" @params + &$this.BuildEnv.NuGet restore "$($this.SolutionRoot)\umbraco-netcore-only.sln" > "$($this.BuildTemp)\nuget.restore.log" @params if (-not $?) { throw "Failed to restore NuGet packages." } }) @@ -401,7 +401,7 @@ Write-Host "Create NuGet packages" - &dotnet pack "$($this.SolutionRoot)\src\umbraco-netcore-only.sln" ` + &dotnet pack "$($this.SolutionRoot)\umbraco-netcore-only.sln" ` --output "$($this.BuildOutput)" ` --verbosity detailed ` -c Release ` diff --git a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs index 86f4e070c2..ad35cbf30a 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs @@ -27,8 +27,6 @@ namespace Umbraco.Cms.Infrastructure.Runtime private readonly IMainDom _mainDom; private readonly IUmbracoDatabaseFactory _databaseFactory; private readonly IEventAggregator _eventAggregator; - private readonly IHostingEnvironment _hostingEnvironment; - private readonly IUmbracoVersion _umbracoVersion; private CancellationToken _cancellationToken; /// @@ -42,9 +40,7 @@ namespace Umbraco.Cms.Infrastructure.Runtime IProfilingLogger profilingLogger, IMainDom mainDom, IUmbracoDatabaseFactory databaseFactory, - IEventAggregator eventAggregator, - IHostingEnvironment hostingEnvironment, - IUmbracoVersion umbracoVersion) + IEventAggregator eventAggregator) { State = state; _loggerFactory = loggerFactory; @@ -54,8 +50,6 @@ namespace Umbraco.Cms.Infrastructure.Runtime _mainDom = mainDom; _databaseFactory = databaseFactory; _eventAggregator = eventAggregator; - _hostingEnvironment = hostingEnvironment; - _umbracoVersion = umbracoVersion; _logger = _loggerFactory.CreateLogger(); } diff --git a/src/Umbraco.Tests.Common/TestHelperBase.cs b/src/Umbraco.Tests.Common/TestHelperBase.cs index 5a7bd1abc7..5801e3291e 100644 --- a/src/Umbraco.Tests.Common/TestHelperBase.cs +++ b/src/Umbraco.Tests.Common/TestHelperBase.cs @@ -52,16 +52,10 @@ namespace Umbraco.Cms.Tests.Common public TypeLoader GetMockedTypeLoader() => new TypeLoader(Mock.Of(), new VaryingRuntimeHash(), Mock.Of(), new DirectoryInfo(GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of>(), Mock.Of()); - //// public Configs GetConfigs() => GetConfigsFactory().Create(); - - public abstract IBackOfficeInfo GetBackOfficeInfo(); - - //// public IConfigsFactory GetConfigsFactory() => new ConfigsFactory(); - /// /// Gets the working directory of the test project. /// - public virtual string WorkingDirectory + public string WorkingDirectory { get { @@ -70,11 +64,15 @@ namespace Umbraco.Cms.Tests.Common return _workingDir; } - var dir = Path.Combine(Assembly.GetExecutingAssembly().GetRootDirectorySafe(), "TEMP"); + // Azure DevOps can only store a database in certain locations so we will need to detect if we are running + // on a build server and if so we'll use the temp path. + var dir = string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("System_DefaultWorkingDirectory")) + ? Path.Combine(Assembly.GetExecutingAssembly().GetRootDirectorySafe(), "TEMP") + : Path.Combine(Path.GetTempPath(), "UmbracoTests", "TEMP"); if (!Directory.Exists(dir)) { - Directory.CreateDirectory(dir); + _ = Directory.CreateDirectory(dir); } _workingDir = dir; diff --git a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs index 832cf6257b..a9bed62993 100644 --- a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs +++ b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs @@ -79,32 +79,6 @@ namespace Umbraco.Cms.Tests.Integration.Implementations ProfilingLogger = new ProfilingLogger(ConsoleLoggerFactory.CreateLogger(), Profiler); } - public override string WorkingDirectory - { - get - { - // For Azure Devops we can only store a database in certain locations so we will need to detect if we are running - // on a build server and if so we'll use the %temp% path. - if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("System_DefaultWorkingDirectory"))) - { - // We are using Azure Devops! - if (_tempWorkingDir != null) - { - return _tempWorkingDir; - } - - string temp = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoTemp"); - Directory.CreateDirectory(temp); - _tempWorkingDir = temp; - return _tempWorkingDir; - } - else - { - return base.WorkingDirectory; - } - } - } - public IUmbracoBootPermissionChecker UmbracoBootPermissionChecker { get; } = new TestUmbracoBootPermissionChecker(); @@ -130,18 +104,6 @@ namespace Umbraco.Cms.Tests.Integration.Implementations public override IMarchal Marchal { get; } = new AspNetCoreMarchal(); - public override IBackOfficeInfo GetBackOfficeInfo() - { - if (_backOfficeInfo == null) - { - var globalSettings = new GlobalSettings(); - IOptionsMonitor mockedOptionsMonitorOfGlobalSettings = Mock.Of>(x => x.CurrentValue == globalSettings); - _backOfficeInfo = new AspNetCoreBackOfficeInfo(mockedOptionsMonitorOfGlobalSettings, GetHostingEnvironment()); - } - - return _backOfficeInfo; - } - public override IHostingEnvironment GetHostingEnvironment() => _hostingEnvironment ??= new TestHostingEnvironment( GetIOptionsMonitorOfHostingSettings(), diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs index 96681c67da..86f6a03216 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs @@ -24,6 +24,7 @@ using Umbraco.Cms.Tests.Integration.DependencyInjection; using Umbraco.Cms.Tests.Integration.Testing; using Umbraco.Cms.Web.BackOffice.Controllers; using Umbraco.Cms.Web.Common.Controllers; +using Umbraco.Cms.Web.UI; using Umbraco.Cms.Web.Website.Controllers; using Umbraco.Extensions; @@ -39,8 +40,19 @@ namespace Umbraco.Cms.Tests.Integration.TestServerTest InMemoryConfiguration["ConnectionStrings:" + Constants.System.UmbracoConnectionName] = null; InMemoryConfiguration["Umbraco:CMS:Hosting:Debug"] = "true"; - // create new WebApplicationFactory specifying 'this' as the IStartup instance - var factory = new UmbracoWebApplicationFactory(CreateHostBuilder, BeforeHostStart); + /* + * It's worth noting that our usage of WebApplicationFactory is non-standard, + * the intent is that your Startup.ConfigureServices is called just like + * when the app starts up, then replacements are registered in this class with + * builder.ConfigureServices (builder.ConfigureTestServices has hung around from before the + * generic host switchover). + * + * This is currently a pain to refactor towards due to UmbracoBuilder+TypeFinder+TypeLoader setup but + * we should get there one day. + * + * See https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests + */ + var factory = new UmbracoWebApplicationFactory(CreateHostBuilder, BeforeHostStart); // additional host configuration for web server integration tests Factory = factory.WithWebHostBuilder(builder => @@ -129,7 +141,7 @@ namespace Umbraco.Cms.Tests.Integration.TestServerTest protected LinkGenerator LinkGenerator { get; private set; } - protected WebApplicationFactory Factory { get; private set; } + protected WebApplicationFactory Factory { get; private set; } public override void ConfigureServices(IServiceCollection services) { diff --git a/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj index 401ff20539..b311766c8c 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj +++ b/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj @@ -1,4 +1,4 @@ - + net5.0 @@ -99,6 +99,7 @@ + diff --git a/src/Umbraco.Tests.UnitTests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests.UnitTests/TestHelpers/TestHelper.cs index 3a8949cff3..8dee7db12d 100644 --- a/src/Umbraco.Tests.UnitTests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests.UnitTests/TestHelpers/TestHelper.cs @@ -67,9 +67,6 @@ namespace Umbraco.Cms.Tests.UnitTests.TestHelpers public override IMarchal Marchal { get; } = Mock.Of(); - public override IBackOfficeInfo GetBackOfficeInfo() - => Mock.Of(); - public override IHostingEnvironment GetHostingEnvironment() { var testPath = TestContext.CurrentContext.TestDirectory.Split("bin")[0]; @@ -104,12 +101,6 @@ namespace Umbraco.Cms.Tests.UnitTests.TestHelpers public static MapperConfigurationStore CreateMaps() => new MapperConfigurationStore(); - //// public static Configs GetConfigs() => _testHelperInternal.GetConfigs(); - - public static IBackOfficeInfo GetBackOfficeInfo() => s_testHelperInternal.GetBackOfficeInfo(); - - //// public static IConfigsFactory GetConfigsFactory() => _testHelperInternal.GetConfigsFactory(); - /// /// Gets the working directory of the test project. /// diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index d311f48f2d..b8960c6b64 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -69,11 +69,6 @@ namespace Umbraco.Tests.TestHelpers public override IMarchal Marchal { get; } = new FrameworkMarchal(); - public override IBackOfficeInfo GetBackOfficeInfo() - => new AspNetBackOfficeInfo( - new GlobalSettings(), - TestHelper.IOHelper, Mock.Of>(), Options.Create(new WebRoutingSettings())); - public override IHostingEnvironment GetHostingEnvironment() => new AspNetHostingEnvironment(Options.Create(new HostingSettings())); @@ -88,12 +83,6 @@ namespace Umbraco.Tests.TestHelpers public static TypeLoader GetMockedTypeLoader() => _testHelperInternal.GetMockedTypeLoader(); - //public static Configs GetConfigs() => _testHelperInternal.GetConfigs(); - - public static IBackOfficeInfo GetBackOfficeInfo() => _testHelperInternal.GetBackOfficeInfo(); - - // public static IConfigsFactory GetConfigsFactory() => _testHelperInternal.GetConfigsFactory(); - /// /// Gets the working directory of the test project. /// diff --git a/src/umbraco-netcore-only.sln b/umbraco-netcore-only.sln similarity index 68% rename from src/umbraco-netcore-only.sln rename to umbraco-netcore-only.sln index 375c23208a..17591c8c55 100644 --- a/src/umbraco-netcore-only.sln +++ b/umbraco-netcore-only.sln @@ -3,43 +3,43 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29209.152 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.UI", "Umbraco.Web.UI\Umbraco.Web.UI.csproj", "{DCDFE97C-5630-4F6F-855D-8AEEB96556A5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.UI", "src\Umbraco.Web.UI\Umbraco.Web.UI.csproj", "{DCDFE97C-5630-4F6F-855D-8AEEB96556A5}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{2849E9D4-3B4E-40A3-A309-F3CB4F0E125F}" ProjectSection(SolutionItems) = preProject - ..\linting\.editorconfig = ..\linting\.editorconfig - ..\build\azure-pipelines.yml = ..\build\azure-pipelines.yml - ..\build\build-bootstrap.ps1 = ..\build\build-bootstrap.ps1 - ..\build\build.ps1 = ..\build\build.ps1 - ..\linting\codeanalysis.ruleset = ..\linting\codeanalysis.ruleset - ..\linting\codeanalysis.tests.ruleset = ..\linting\codeanalysis.tests.ruleset - ..\Directory.Build.props = ..\Directory.Build.props - ..\Directory.Build.targets = ..\Directory.Build.targets - ..\NuGet.Config = ..\NuGet.Config - ..\linting\stylecop.json = ..\linting\stylecop.json + linting\.editorconfig = linting\.editorconfig + build\azure-pipelines.yml = build\azure-pipelines.yml + build\build-bootstrap.ps1 = build\build-bootstrap.ps1 + build\build.ps1 = build\build.ps1 + linting\codeanalysis.ruleset = linting\codeanalysis.ruleset + linting\codeanalysis.tests.ruleset = linting\codeanalysis.tests.ruleset + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + NuGet.Config = NuGet.Config + linting\stylecop.json = linting\stylecop.json EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{FD962632-184C-4005-A5F3-E705D92FC645}" ProjectSection(SolutionItems) = preProject - ..\.github\BUILD.md = ..\.github\BUILD.md - ..\.github\CLEAR.md = ..\.github\CLEAR.md - ..\.github\CODE_OF_CONDUCT.md = ..\.github\CODE_OF_CONDUCT.md - ..\.github\CONTRIBUTING.md = ..\.github\CONTRIBUTING.md - ..\.github\CONTRIBUTING_DETAILED.md = ..\.github\CONTRIBUTING_DETAILED.md - ..\.github\CONTRIBUTION_GUIDELINES.md = ..\.github\CONTRIBUTION_GUIDELINES.md - ..\.github\PULL_REQUEST_TEMPLATE.md = ..\.github\PULL_REQUEST_TEMPLATE.md - ..\.github\README.md = ..\.github\README.md - ..\.github\REVIEW_PROCESS.md = ..\.github\REVIEW_PROCESS.md - ..\.github\V8_GETTING_STARTED.md = ..\.github\V8_GETTING_STARTED.md + .github\BUILD.md = .github\BUILD.md + .github\CLEAR.md = .github\CLEAR.md + .github\CODE_OF_CONDUCT.md = .github\CODE_OF_CONDUCT.md + .github\CONTRIBUTING.md = .github\CONTRIBUTING.md + .github\CONTRIBUTING_DETAILED.md = .github\CONTRIBUTING_DETAILED.md + .github\CONTRIBUTION_GUIDELINES.md = .github\CONTRIBUTION_GUIDELINES.md + .github\PULL_REQUEST_TEMPLATE.md = .github\PULL_REQUEST_TEMPLATE.md + .github\README.md = .github\README.md + .github\REVIEW_PROCESS.md = .github\REVIEW_PROCESS.md + .github\V8_GETTING_STARTED.md = .github\V8_GETTING_STARTED.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B5BD12C1-A454-435E-8A46-FF4A364C0382}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuSpecs", "NuSpecs", "{227C3B55-80E5-4E7E-A802-BE16C5128B9D}" ProjectSection(SolutionItems) = preProject - ..\build\NuSpecs\UmbracoCms.nuspec = ..\build\NuSpecs\UmbracoCms.nuspec - ..\build\NuSpecs\UmbracoCms.SqlCe.nuspec = ..\build\NuSpecs\UmbracoCms.SqlCe.nuspec - ..\build\NuSpecs\UmbracoCms.StaticAssets.nuspec = ..\build\NuSpecs\UmbracoCms.StaticAssets.nuspec + build\NuSpecs\UmbracoCms.nuspec = build\NuSpecs\UmbracoCms.nuspec + build\NuSpecs\UmbracoCms.SqlCe.nuspec = build\NuSpecs\UmbracoCms.SqlCe.nuspec + build\NuSpecs\UmbracoCms.StaticAssets.nuspec = build\NuSpecs\UmbracoCms.StaticAssets.nuspec EndProjectSection EndProject Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Web.UI.Client", "http://localhost:3961", "{3819A550-DCEC-4153-91B4-8BA9F7F0B9B4}" @@ -47,20 +47,20 @@ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Web.UI.Client", "ht UseIISExpress = "true" TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.5" Debug.AspNetCompiler.VirtualPath = "/localhost_3961" - Debug.AspNetCompiler.PhysicalPath = "Umbraco.Web.UI.Client\" + Debug.AspNetCompiler.PhysicalPath = "src\Umbraco.Web.UI.Client\" Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_3961\" Debug.AspNetCompiler.Updateable = "true" Debug.AspNetCompiler.ForceOverwrite = "true" Debug.AspNetCompiler.FixedNames = "false" Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.VirtualPath = "/localhost_3961" - Release.AspNetCompiler.PhysicalPath = "Umbraco.Web.UI.Client\" + Release.AspNetCompiler.PhysicalPath = "src\Umbraco.Web.UI.Client\" Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_3961\" Release.AspNetCompiler.Updateable = "true" Release.AspNetCompiler.ForceOverwrite = "true" Release.AspNetCompiler.FixedNames = "false" Release.AspNetCompiler.Debug = "False" - SlnRelativePath = "Umbraco.Web.UI.Client\" + SlnRelativePath = "src\Umbraco.Web.UI.Client\" DefaultWebSiteLanguage = "Visual C#" StartServerOnDebug = "false" EndProjectSection @@ -70,83 +70,83 @@ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Tests.AcceptanceTes UseIISExpress = "true" TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.5" Debug.AspNetCompiler.VirtualPath = "/localhost_62926" - Debug.AspNetCompiler.PhysicalPath = "Umbraco.Tests.AcceptanceTest\" + Debug.AspNetCompiler.PhysicalPath = "src\Umbraco.Tests.AcceptanceTest\" Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_62926\" Debug.AspNetCompiler.Updateable = "true" Debug.AspNetCompiler.ForceOverwrite = "true" Debug.AspNetCompiler.FixedNames = "false" Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.VirtualPath = "/localhost_62926" - Release.AspNetCompiler.PhysicalPath = "Umbraco.Tests.AcceptanceTest\" + Release.AspNetCompiler.PhysicalPath = "src\Umbraco.Tests.AcceptanceTest\" Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_62926\" Release.AspNetCompiler.Updateable = "true" Release.AspNetCompiler.ForceOverwrite = "true" Release.AspNetCompiler.FixedNames = "false" Release.AspNetCompiler.Debug = "False" - SlnRelativePath = "Umbraco.Tests.AcceptanceTest\" + SlnRelativePath = "src\Umbraco.Tests.AcceptanceTest\" DefaultWebSiteLanguage = "Visual C#" StartServerOnDebug = "false" EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{E3F9F378-AFE1-40A5-90BD-82833375DBFE}" ProjectSection(SolutionItems) = preProject - ..\build\NuSpecs\tools\applications.config.install.xdt = ..\build\NuSpecs\tools\applications.config.install.xdt - ..\build\NuSpecs\tools\ClientDependency.config.install.xdt = ..\build\NuSpecs\tools\ClientDependency.config.install.xdt - ..\build\NuSpecs\tools\install.ps1 = ..\build\NuSpecs\tools\install.ps1 - ..\build\NuSpecs\tools\Readme.txt = ..\build\NuSpecs\tools\Readme.txt - ..\build\NuSpecs\tools\ReadmeUpgrade.txt = ..\build\NuSpecs\tools\ReadmeUpgrade.txt - ..\build\NuSpecs\tools\serilog.config.install.xdt = ..\build\NuSpecs\tools\serilog.config.install.xdt - ..\build\NuSpecs\tools\Web.config.install.xdt = ..\build\NuSpecs\tools\Web.config.install.xdt + build\NuSpecs\tools\applications.config.install.xdt = build\NuSpecs\tools\applications.config.install.xdt + build\NuSpecs\tools\ClientDependency.config.install.xdt = build\NuSpecs\tools\ClientDependency.config.install.xdt + build\NuSpecs\tools\install.ps1 = build\NuSpecs\tools\install.ps1 + build\NuSpecs\tools\Readme.txt = build\NuSpecs\tools\Readme.txt + build\NuSpecs\tools\ReadmeUpgrade.txt = build\NuSpecs\tools\ReadmeUpgrade.txt + build\NuSpecs\tools\serilog.config.install.xdt = build\NuSpecs\tools\serilog.config.install.xdt + build\NuSpecs\tools\Web.config.install.xdt = build\NuSpecs\tools\Web.config.install.xdt EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{5B03EF4E-E0AC-4905-861B-8C3EC1A0D458}" ProjectSection(SolutionItems) = preProject - ..\build\NuSpecs\build\Umbraco.Cms.props = ..\build\NuSpecs\build\Umbraco.Cms.props - ..\build\NuSpecs\build\Umbraco.Cms.targets = ..\build\NuSpecs\build\Umbraco.Cms.targets + build\NuSpecs\build\Umbraco.Cms.props = build\NuSpecs\build\Umbraco.Cms.props + build\NuSpecs\build\Umbraco.Cms.targets = build\NuSpecs\build\Umbraco.Cms.targets EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DocTools", "DocTools", "{53594E5B-64A2-4545-8367-E3627D266AE8}" ProjectSection(SolutionItems) = preProject - ApiDocs\docfx.filter.yml = ApiDocs\docfx.filter.yml - ApiDocs\docfx.json = ApiDocs\docfx.json - ApiDocs\index.md = ApiDocs\index.md - ApiDocs\toc.yml = ApiDocs\toc.yml + src\ApiDocs\docfx.filter.yml = src\ApiDocs\docfx.filter.yml + src\ApiDocs\docfx.json = src\ApiDocs\docfx.json + src\ApiDocs\index.md = src\ApiDocs\index.md + src\ApiDocs\toc.yml = src\ApiDocs\toc.yml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IssueTemplates", "IssueTemplates", "{C7311C00-2184-409B-B506-52A5FAEA8736}" ProjectSection(SolutionItems) = preProject - ..\.github\ISSUE_TEMPLATE\1_Bug.md = ..\.github\ISSUE_TEMPLATE\1_Bug.md - ..\.github\ISSUE_TEMPLATE\2_Feature_request.md = ..\.github\ISSUE_TEMPLATE\2_Feature_request.md - ..\.github\ISSUE_TEMPLATE\3_Support_question.md = ..\.github\ISSUE_TEMPLATE\3_Support_question.md - ..\.github\ISSUE_TEMPLATE\4_Documentation_issue.md = ..\.github\ISSUE_TEMPLATE\4_Documentation_issue.md - ..\.github\ISSUE_TEMPLATE\5_Security_issue.md = ..\.github\ISSUE_TEMPLATE\5_Security_issue.md + .github\ISSUE_TEMPLATE\1_Bug.md = .github\ISSUE_TEMPLATE\1_Bug.md + .github\ISSUE_TEMPLATE\2_Feature_request.md = .github\ISSUE_TEMPLATE\2_Feature_request.md + .github\ISSUE_TEMPLATE\3_Support_question.md = .github\ISSUE_TEMPLATE\3_Support_question.md + .github\ISSUE_TEMPLATE\4_Documentation_issue.md = .github\ISSUE_TEMPLATE\4_Documentation_issue.md + .github\ISSUE_TEMPLATE\5_Security_issue.md = .github\ISSUE_TEMPLATE\5_Security_issue.md EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Core", "Umbraco.Core\Umbraco.Core.csproj", "{29AA69D9-B597-4395-8D42-43B1263C240A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Core", "src\Umbraco.Core\Umbraco.Core.csproj", "{29AA69D9-B597-4395-8D42-43B1263C240A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Infrastructure", "Umbraco.Infrastructure\Umbraco.Infrastructure.csproj", "{3AE7BF57-966B-45A5-910A-954D7C554441}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Infrastructure", "src\Umbraco.Infrastructure\Umbraco.Infrastructure.csproj", "{3AE7BF57-966B-45A5-910A-954D7C554441}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.PublishedCache.NuCache", "Umbraco.PublishedCache.NuCache\Umbraco.PublishedCache.NuCache.csproj", "{F6DE8DA0-07CC-4EF2-8A59-2BC81DBB3830}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.PublishedCache.NuCache", "src\Umbraco.PublishedCache.NuCache\Umbraco.PublishedCache.NuCache.csproj", "{F6DE8DA0-07CC-4EF2-8A59-2BC81DBB3830}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.BackOffice", "Umbraco.Web.BackOffice\Umbraco.Web.BackOffice.csproj", "{9B95EEF7-63FE-4432-8C63-166BE9C1A929}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.BackOffice", "src\Umbraco.Web.BackOffice\Umbraco.Web.BackOffice.csproj", "{9B95EEF7-63FE-4432-8C63-166BE9C1A929}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.Website", "Umbraco.Web.Website\Umbraco.Web.Website.csproj", "{5A246D54-3109-4D2B-BE7D-FC0787D126AE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.Website", "src\Umbraco.Web.Website\Umbraco.Web.Website.csproj", "{5A246D54-3109-4D2B-BE7D-FC0787D126AE}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Common", "Umbraco.Tests.Common\Umbraco.Tests.Common.csproj", "{A499779C-1B3B-48A8-B551-458E582E6E96}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Common", "src\Umbraco.Tests.Common\Umbraco.Tests.Common.csproj", "{A499779C-1B3B-48A8-B551-458E582E6E96}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.UnitTests", "Umbraco.Tests.UnitTests\Umbraco.Tests.UnitTests.csproj", "{9102ABDF-E537-4E46-B525-C9ED4833EED0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.UnitTests", "src\Umbraco.Tests.UnitTests\Umbraco.Tests.UnitTests.csproj", "{9102ABDF-E537-4E46-B525-C9ED4833EED0}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.Common", "Umbraco.Web.Common\Umbraco.Web.Common.csproj", "{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.Common", "src\Umbraco.Web.Common\Umbraco.Web.Common.csproj", "{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Integration", "Umbraco.Tests.Integration\Umbraco.Tests.Integration.csproj", "{1B885D2F-1599-4557-A4EC-474CC74DEB10}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Integration", "src\Umbraco.Tests.Integration\Umbraco.Tests.Integration.csproj", "{1B885D2F-1599-4557-A4EC-474CC74DEB10}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Tests.Integration.SqlCe", "Umbraco.Tests.Integration.SqlCe\Umbraco.Tests.Integration.SqlCe.csproj", "{7A58F7CB-786F-43D6-A946-7BFA1B70D0AA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Integration.SqlCe", "src\Umbraco.Tests.Integration.SqlCe\Umbraco.Tests.Integration.SqlCe.csproj", "{7A58F7CB-786F-43D6-A946-7BFA1B70D0AA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Examine.Lucene", "Umbraco.Examine.Lucene\Umbraco.Examine.Lucene.csproj", "{96EF355C-A7C8-460E-96D7-ABCE0D489762}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Examine.Lucene", "src\Umbraco.Examine.Lucene\Umbraco.Examine.Lucene.csproj", "{96EF355C-A7C8-460E-96D7-ABCE0D489762}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.TestData", "Umbraco.TestData\Umbraco.TestData.csproj", "{C44B4389-6E2A-441E-9A10-7CE818CA63A9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.TestData", "src\Umbraco.TestData\Umbraco.TestData.csproj", "{C44B4389-6E2A-441E-9A10-7CE818CA63A9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Tests.Benchmarks", "Umbraco.Tests.Benchmarks\Umbraco.Tests.Benchmarks.csproj", "{37B6264F-A279-42A6-AB83-CC3A3950C3E2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Benchmarks", "src\Umbraco.Tests.Benchmarks\Umbraco.Tests.Benchmarks.csproj", "{37B6264F-A279-42A6-AB83-CC3A3950C3E2}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -154,6 +154,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Release|Any CPU.Build.0 = Release|Any CPU {3819A550-DCEC-4153-91B4-8BA9F7F0B9B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3819A550-DCEC-4153-91B4-8BA9F7F0B9B4}.Release|Any CPU.ActiveCfg = Debug|Any CPU {9E4C8A12-FBE0-4673-8CE2-DF99D5D57817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -174,10 +178,6 @@ Global {9B95EEF7-63FE-4432-8C63-166BE9C1A929}.Debug|Any CPU.Build.0 = Debug|Any CPU {9B95EEF7-63FE-4432-8C63-166BE9C1A929}.Release|Any CPU.ActiveCfg = Release|Any CPU {9B95EEF7-63FE-4432-8C63-166BE9C1A929}.Release|Any CPU.Build.0 = Release|Any CPU - {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Release|Any CPU.Build.0 = Release|Any CPU {5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Debug|Any CPU.Build.0 = Debug|Any CPU {5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/src/umbraco.sln b/umbraco.sln similarity index 71% rename from src/umbraco.sln rename to umbraco.sln index fe2e8a5a44..98742a1ffb 100644 --- a/src/umbraco.sln +++ b/umbraco.sln @@ -3,43 +3,43 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29209.152 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.UI", "Umbraco.Web.UI\Umbraco.Web.UI.csproj", "{DCDFE97C-5630-4F6F-855D-8AEEB96556A5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.UI", "src\Umbraco.Web.UI\Umbraco.Web.UI.csproj", "{DCDFE97C-5630-4F6F-855D-8AEEB96556A5}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{2849E9D4-3B4E-40A3-A309-F3CB4F0E125F}" ProjectSection(SolutionItems) = preProject - ..\linting\.editorconfig = ..\linting\.editorconfig - ..\build\azure-pipelines.yml = ..\build\azure-pipelines.yml - ..\build\build-bootstrap.ps1 = ..\build\build-bootstrap.ps1 - ..\build\build.ps1 = ..\build\build.ps1 - ..\linting\codeanalysis.ruleset = ..\linting\codeanalysis.ruleset - ..\linting\codeanalysis.tests.ruleset = ..\linting\codeanalysis.tests.ruleset - ..\Directory.Build.props = ..\Directory.Build.props - ..\Directory.Build.targets = ..\Directory.Build.targets - ..\NuGet.Config = ..\NuGet.Config - ..\linting\stylecop.json = ..\linting\stylecop.json + linting\.editorconfig = linting\.editorconfig + build\azure-pipelines.yml = build\azure-pipelines.yml + build\build-bootstrap.ps1 = build\build-bootstrap.ps1 + build\build.ps1 = build\build.ps1 + linting\codeanalysis.ruleset = linting\codeanalysis.ruleset + linting\codeanalysis.tests.ruleset = linting\codeanalysis.tests.ruleset + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + NuGet.Config = NuGet.Config + linting\stylecop.json = linting\stylecop.json EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{FD962632-184C-4005-A5F3-E705D92FC645}" ProjectSection(SolutionItems) = preProject - ..\.github\BUILD.md = ..\.github\BUILD.md - ..\.github\CLEAR.md = ..\.github\CLEAR.md - ..\.github\CODE_OF_CONDUCT.md = ..\.github\CODE_OF_CONDUCT.md - ..\.github\CONTRIBUTING.md = ..\.github\CONTRIBUTING.md - ..\.github\CONTRIBUTING_DETAILED.md = ..\.github\CONTRIBUTING_DETAILED.md - ..\.github\CONTRIBUTION_GUIDELINES.md = ..\.github\CONTRIBUTION_GUIDELINES.md - ..\.github\PULL_REQUEST_TEMPLATE.md = ..\.github\PULL_REQUEST_TEMPLATE.md - ..\.github\README.md = ..\.github\README.md - ..\.github\REVIEW_PROCESS.md = ..\.github\REVIEW_PROCESS.md - ..\.github\V8_GETTING_STARTED.md = ..\.github\V8_GETTING_STARTED.md + .github\BUILD.md = .github\BUILD.md + .github\CLEAR.md = .github\CLEAR.md + .github\CODE_OF_CONDUCT.md = .github\CODE_OF_CONDUCT.md + .github\CONTRIBUTING.md = .github\CONTRIBUTING.md + .github\CONTRIBUTING_DETAILED.md = .github\CONTRIBUTING_DETAILED.md + .github\CONTRIBUTION_GUIDELINES.md = .github\CONTRIBUTION_GUIDELINES.md + .github\PULL_REQUEST_TEMPLATE.md = .github\PULL_REQUEST_TEMPLATE.md + .github\README.md = .github\README.md + .github\REVIEW_PROCESS.md = .github\REVIEW_PROCESS.md + .github\V8_GETTING_STARTED.md = .github\V8_GETTING_STARTED.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B5BD12C1-A454-435E-8A46-FF4A364C0382}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuSpecs", "NuSpecs", "{227C3B55-80E5-4E7E-A802-BE16C5128B9D}" ProjectSection(SolutionItems) = preProject - ..\build\NuSpecs\UmbracoCms.nuspec = ..\build\NuSpecs\UmbracoCms.nuspec - ..\build\NuSpecs\UmbracoCms.SqlCe.nuspec = ..\build\NuSpecs\UmbracoCms.SqlCe.nuspec - ..\build\NuSpecs\UmbracoCms.StaticAssets.nuspec = ..\build\NuSpecs\UmbracoCms.StaticAssets.nuspec + build\NuSpecs\UmbracoCms.nuspec = build\NuSpecs\UmbracoCms.nuspec + build\NuSpecs\UmbracoCms.SqlCe.nuspec = build\NuSpecs\UmbracoCms.SqlCe.nuspec + build\NuSpecs\UmbracoCms.StaticAssets.nuspec = build\NuSpecs\UmbracoCms.StaticAssets.nuspec EndProjectSection EndProject Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Web.UI.Client", "http://localhost:3961", "{3819A550-DCEC-4153-91B4-8BA9F7F0B9B4}" @@ -90,67 +90,67 @@ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Tests.AcceptanceTes EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{E3F9F378-AFE1-40A5-90BD-82833375DBFE}" ProjectSection(SolutionItems) = preProject - ..\build\NuSpecs\tools\applications.config.install.xdt = ..\build\NuSpecs\tools\applications.config.install.xdt - ..\build\NuSpecs\tools\ClientDependency.config.install.xdt = ..\build\NuSpecs\tools\ClientDependency.config.install.xdt - ..\build\NuSpecs\tools\install.ps1 = ..\build\NuSpecs\tools\install.ps1 - ..\build\NuSpecs\tools\Readme.txt = ..\build\NuSpecs\tools\Readme.txt - ..\build\NuSpecs\tools\ReadmeUpgrade.txt = ..\build\NuSpecs\tools\ReadmeUpgrade.txt - ..\build\NuSpecs\tools\serilog.config.install.xdt = ..\build\NuSpecs\tools\serilog.config.install.xdt - ..\build\NuSpecs\tools\Web.config.install.xdt = ..\build\NuSpecs\tools\Web.config.install.xdt + build\NuSpecs\tools\applications.config.install.xdt = build\NuSpecs\tools\applications.config.install.xdt + build\NuSpecs\tools\ClientDependency.config.install.xdt = build\NuSpecs\tools\ClientDependency.config.install.xdt + build\NuSpecs\tools\install.ps1 = build\NuSpecs\tools\install.ps1 + build\NuSpecs\tools\Readme.txt = build\NuSpecs\tools\Readme.txt + build\NuSpecs\tools\ReadmeUpgrade.txt = build\NuSpecs\tools\ReadmeUpgrade.txt + build\NuSpecs\tools\serilog.config.install.xdt = build\NuSpecs\tools\serilog.config.install.xdt + build\NuSpecs\tools\Web.config.install.xdt = build\NuSpecs\tools\Web.config.install.xdt EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{5B03EF4E-E0AC-4905-861B-8C3EC1A0D458}" ProjectSection(SolutionItems) = preProject - ..\build\NuSpecs\build\Umbraco.Cms.StaticAssets.props = ..\build\NuSpecs\build\Umbraco.Cms.StaticAssets.props - ..\build\NuSpecs\build\Umbraco.Cms.StaticAssets.targets = ..\build\NuSpecs\build\Umbraco.Cms.StaticAssets.targets + build\NuSpecs\build\Umbraco.Cms.StaticAssets.props = build\NuSpecs\build\Umbraco.Cms.StaticAssets.props + build\NuSpecs\build\Umbraco.Cms.StaticAssets.targets = build\NuSpecs\build\Umbraco.Cms.StaticAssets.targets EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DocTools", "DocTools", "{53594E5B-64A2-4545-8367-E3627D266AE8}" ProjectSection(SolutionItems) = preProject - ApiDocs\docfx.filter.yml = ApiDocs\docfx.filter.yml - ApiDocs\docfx.json = ApiDocs\docfx.json - ApiDocs\index.md = ApiDocs\index.md - ApiDocs\toc.yml = ApiDocs\toc.yml + src\ApiDocs\docfx.filter.yml = src\ApiDocs\docfx.filter.yml + src\ApiDocs\docfx.json = src\ApiDocs\docfx.json + src\ApiDocs\index.md = src\ApiDocs\index.md + src\ApiDocs\toc.yml = src\ApiDocs\toc.yml EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Benchmarks", "Umbraco.Tests.Benchmarks\Umbraco.Tests.Benchmarks.csproj", "{3A33ADC9-C6C0-4DB1-A613-A9AF0210DF3D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Benchmarks", "src\Umbraco.Tests.Benchmarks\Umbraco.Tests.Benchmarks.csproj", "{3A33ADC9-C6C0-4DB1-A613-A9AF0210DF3D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IssueTemplates", "IssueTemplates", "{C7311C00-2184-409B-B506-52A5FAEA8736}" ProjectSection(SolutionItems) = preProject - ..\.github\ISSUE_TEMPLATE\1_Bug.md = ..\.github\ISSUE_TEMPLATE\1_Bug.md - ..\.github\ISSUE_TEMPLATE\2_Feature_request.md = ..\.github\ISSUE_TEMPLATE\2_Feature_request.md - ..\.github\ISSUE_TEMPLATE\3_Support_question.md = ..\.github\ISSUE_TEMPLATE\3_Support_question.md - ..\.github\ISSUE_TEMPLATE\4_Documentation_issue.md = ..\.github\ISSUE_TEMPLATE\4_Documentation_issue.md - ..\.github\ISSUE_TEMPLATE\5_Security_issue.md = ..\.github\ISSUE_TEMPLATE\5_Security_issue.md + .github\ISSUE_TEMPLATE\1_Bug.md = .github\ISSUE_TEMPLATE\1_Bug.md + .github\ISSUE_TEMPLATE\2_Feature_request.md = .github\ISSUE_TEMPLATE\2_Feature_request.md + .github\ISSUE_TEMPLATE\3_Support_question.md = .github\ISSUE_TEMPLATE\3_Support_question.md + .github\ISSUE_TEMPLATE\4_Documentation_issue.md = .github\ISSUE_TEMPLATE\4_Documentation_issue.md + .github\ISSUE_TEMPLATE\5_Security_issue.md = .github\ISSUE_TEMPLATE\5_Security_issue.md EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Core", "Umbraco.Core\Umbraco.Core.csproj", "{29AA69D9-B597-4395-8D42-43B1263C240A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Core", "src\Umbraco.Core\Umbraco.Core.csproj", "{29AA69D9-B597-4395-8D42-43B1263C240A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Infrastructure", "Umbraco.Infrastructure\Umbraco.Infrastructure.csproj", "{3AE7BF57-966B-45A5-910A-954D7C554441}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Infrastructure", "src\Umbraco.Infrastructure\Umbraco.Infrastructure.csproj", "{3AE7BF57-966B-45A5-910A-954D7C554441}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Persistence.SqlCe", "Umbraco.Persistence.SqlCe\Umbraco.Persistence.SqlCe.csproj", "{33085570-9BF2-4065-A9B0-A29D920D13BA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Persistence.SqlCe", "src\Umbraco.Persistence.SqlCe\Umbraco.Persistence.SqlCe.csproj", "{33085570-9BF2-4065-A9B0-A29D920D13BA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.TestData", "Umbraco.TestData\Umbraco.TestData.csproj", "{FB5676ED-7A69-492C-B802-E7B24144C0FC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.TestData", "src\Umbraco.TestData\Umbraco.TestData.csproj", "{FB5676ED-7A69-492C-B802-E7B24144C0FC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.PublishedCache.NuCache", "Umbraco.PublishedCache.NuCache\Umbraco.PublishedCache.NuCache.csproj", "{F6DE8DA0-07CC-4EF2-8A59-2BC81DBB3830}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.PublishedCache.NuCache", "src\Umbraco.PublishedCache.NuCache\Umbraco.PublishedCache.NuCache.csproj", "{F6DE8DA0-07CC-4EF2-8A59-2BC81DBB3830}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Examine.Lucene", "Umbraco.Examine.Lucene\Umbraco.Examine.Lucene.csproj", "{0FAD7D2A-D7DD-45B1-91FD-488BB6CDACEA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Examine.Lucene", "src\Umbraco.Examine.Lucene\Umbraco.Examine.Lucene.csproj", "{0FAD7D2A-D7DD-45B1-91FD-488BB6CDACEA}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.BackOffice", "Umbraco.Web.BackOffice\Umbraco.Web.BackOffice.csproj", "{9B95EEF7-63FE-4432-8C63-166BE9C1A929}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.BackOffice", "src\Umbraco.Web.BackOffice\Umbraco.Web.BackOffice.csproj", "{9B95EEF7-63FE-4432-8C63-166BE9C1A929}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.Website", "Umbraco.Web.Website\Umbraco.Web.Website.csproj", "{5A246D54-3109-4D2B-BE7D-FC0787D126AE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.Website", "src\Umbraco.Web.Website\Umbraco.Web.Website.csproj", "{5A246D54-3109-4D2B-BE7D-FC0787D126AE}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Integration", "Umbraco.Tests.Integration\Umbraco.Tests.Integration.csproj", "{D6319409-777A-4BD0-93ED-B2DFD805B32C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Integration", "src\Umbraco.Tests.Integration\Umbraco.Tests.Integration.csproj", "{D6319409-777A-4BD0-93ED-B2DFD805B32C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Common", "Umbraco.Tests.Common\Umbraco.Tests.Common.csproj", "{A499779C-1B3B-48A8-B551-458E582E6E96}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Common", "src\Umbraco.Tests.Common\Umbraco.Tests.Common.csproj", "{A499779C-1B3B-48A8-B551-458E582E6E96}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.UnitTests", "Umbraco.Tests.UnitTests\Umbraco.Tests.UnitTests.csproj", "{9102ABDF-E537-4E46-B525-C9ED4833EED0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.UnitTests", "src\Umbraco.Tests.UnitTests\Umbraco.Tests.UnitTests.csproj", "{9102ABDF-E537-4E46-B525-C9ED4833EED0}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.Common", "Umbraco.Web.Common\Umbraco.Web.Common.csproj", "{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.Common", "src\Umbraco.Web.Common\Umbraco.Web.Common.csproj", "{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonSchema", "JsonSchema\JsonSchema.csproj", "{2A5027D9-F71D-4957-929E-F7A56AA1B95A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonSchema", "src\JsonSchema\JsonSchema.csproj", "{2A5027D9-F71D-4957-929E-F7A56AA1B95A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Tests.Integration.SqlCe", "Umbraco.Tests.Integration.SqlCe\Umbraco.Tests.Integration.SqlCe.csproj", "{1B28FC3E-3D5B-4A46-8961-5483835548D7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.Integration.SqlCe", "src\Umbraco.Tests.Integration.SqlCe\Umbraco.Tests.Integration.SqlCe.csproj", "{1B28FC3E-3D5B-4A46-8961-5483835548D7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -158,6 +158,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Release|Any CPU.Build.0 = Release|Any CPU {3819A550-DCEC-4153-91B4-8BA9F7F0B9B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3819A550-DCEC-4153-91B4-8BA9F7F0B9B4}.Release|Any CPU.ActiveCfg = Debug|Any CPU {9E4C8A12-FBE0-4673-8CE2-DF99D5D57817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -194,10 +198,6 @@ Global {9B95EEF7-63FE-4432-8C63-166BE9C1A929}.Debug|Any CPU.Build.0 = Debug|Any CPU {9B95EEF7-63FE-4432-8C63-166BE9C1A929}.Release|Any CPU.ActiveCfg = Release|Any CPU {9B95EEF7-63FE-4432-8C63-166BE9C1A929}.Release|Any CPU.Build.0 = Release|Any CPU - {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DCDFE97C-5630-4F6F-855D-8AEEB96556A5}.Release|Any CPU.Build.0 = Release|Any CPU {5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Debug|Any CPU.Build.0 = Debug|Any CPU {5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/src/umbraco.sln.DotSettings b/umbraco.sln.DotSettings similarity index 96% rename from src/umbraco.sln.DotSettings rename to umbraco.sln.DotSettings index 1394ee3884..65d49c5ff2 100644 --- a/src/umbraco.sln.DotSettings +++ b/umbraco.sln.DotSettings @@ -8,4 +8,4 @@ Default True True - True + True \ No newline at end of file From 5c0e42e1cbf60b06214a29afb27eb35baf873b7f Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 10 Sep 2021 10:31:38 -0600 Subject: [PATCH 04/29] Allows replacing MainDom with alternate DB There are some cases where there is a complex hosting strategy and folks want a readonly database and are hosting on Azure. In that case, it is not entirely possible to have a readonly Umbraco database because SqlMainDom is required and part of that requirement is to have read/write access to the umbraco key value table. This PR allows for the default MainDom to be replaced and to allow for an SqlMainDomLock to use an alternate connection string so that a separate read/write database can be used. (cherry picked from commit 9f48a9f940b9fee7a09fe4a2f2062c33f455eeb4) --- src/Umbraco.Core/Runtime/MainDom.cs | 2 +- src/Umbraco.Core/Runtime/SqlMainDomLock.cs | 6 +++--- src/Umbraco.Web/UmbracoApplication.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Core/Runtime/MainDom.cs b/src/Umbraco.Core/Runtime/MainDom.cs index d784560f2c..b5404c62b2 100644 --- a/src/Umbraco.Core/Runtime/MainDom.cs +++ b/src/Umbraco.Core/Runtime/MainDom.cs @@ -19,7 +19,7 @@ namespace Umbraco.Core.Runtime /// When an AppDomain starts, it tries to acquire the main domain status. /// When an AppDomain stops (eg the application is restarting) it should release the main domain status. /// - internal class MainDom : IMainDom, IRegisteredObject, IDisposable + public class MainDom : IMainDom, IRegisteredObject, IDisposable { #region Vars diff --git a/src/Umbraco.Core/Runtime/SqlMainDomLock.cs b/src/Umbraco.Core/Runtime/SqlMainDomLock.cs index 12359c96d1..8e38fa74c4 100644 --- a/src/Umbraco.Core/Runtime/SqlMainDomLock.cs +++ b/src/Umbraco.Core/Runtime/SqlMainDomLock.cs @@ -18,7 +18,7 @@ using MapperCollection = Umbraco.Core.Persistence.Mappers.MapperCollection; namespace Umbraco.Core.Runtime { - internal class SqlMainDomLock : IMainDomLock + public class SqlMainDomLock : IMainDomLock { private readonly TimeSpan _lockTimeout; private string _lockId; @@ -33,14 +33,14 @@ namespace Umbraco.Core.Runtime private object _locker = new object(); private bool _hasTable = false; - public SqlMainDomLock(ILogger logger) + public SqlMainDomLock(ILogger logger, string connectionStringName = Constants.System.UmbracoConnectionName) { // unique id for our appdomain, this is more unique than the appdomain id which is just an INT counter to its safer _lockId = Guid.NewGuid().ToString(); _logger = logger; _dbFactory = new UmbracoDatabaseFactory( - Constants.System.UmbracoConnectionName, + connectionStringName, _logger, new Lazy(() => new MapperCollection(Enumerable.Empty()))); diff --git a/src/Umbraco.Web/UmbracoApplication.cs b/src/Umbraco.Web/UmbracoApplication.cs index c96e21e348..563d553ac2 100644 --- a/src/Umbraco.Web/UmbracoApplication.cs +++ b/src/Umbraco.Web/UmbracoApplication.cs @@ -76,7 +76,7 @@ namespace Umbraco.Web /// /// Returns a new MainDom /// - protected IMainDom GetMainDom(ILogger logger) + protected virtual IMainDom GetMainDom(ILogger logger) { // Determine if we should use the sql main dom or the default var appSettingMainDomLock = ConfigurationManager.AppSettings[Constants.AppSettings.MainDomLock]; From 97ecb07be768a39946c7bfc24ebaba22d2e7f5dc Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 30 Sep 2021 10:07:05 +0200 Subject: [PATCH 05/29] Fixes #11206 (#11225) --- src/Umbraco.Core/Composing/CompositionExtensions/Services.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Core/Composing/CompositionExtensions/Services.cs b/src/Umbraco.Core/Composing/CompositionExtensions/Services.cs index d252c58730..d97845928d 100644 --- a/src/Umbraco.Core/Composing/CompositionExtensions/Services.cs +++ b/src/Umbraco.Core/Composing/CompositionExtensions/Services.cs @@ -52,6 +52,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions composition.RegisterUnique(); composition.RegisterUnique(); composition.RegisterUnique(); + composition.RegisterUnique(); composition.Register(SourcesFactory); composition.RegisterUnique(factory => new LocalizedTextService( factory.GetInstance>(), From 11ad3fc0827488d42ddb62ca639183cea6005054 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 30 Sep 2021 10:16:33 +0200 Subject: [PATCH 06/29] Bump version to 8.17.0 --- src/SolutionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index e18eabbfc8..cc6296de4a 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -19,4 +19,4 @@ using System.Resources; // these are FYI and changed automatically [assembly: AssemblyFileVersion("8.17.0")] -[assembly: AssemblyInformationalVersion("8.17.0-rc2")] +[assembly: AssemblyInformationalVersion("8.17.0")] From a3e687026f6409766342c96b2d81679e5e19eb39 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Fri, 1 Oct 2021 09:15:49 +0200 Subject: [PATCH 07/29] fix js projects in sln --- umbraco.sln | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/umbraco.sln b/umbraco.sln index 98742a1ffb..ae3c52d67b 100644 --- a/umbraco.sln +++ b/umbraco.sln @@ -47,20 +47,20 @@ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Web.UI.Client", "ht UseIISExpress = "true" TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.5" Debug.AspNetCompiler.VirtualPath = "/localhost_3961" - Debug.AspNetCompiler.PhysicalPath = "Umbraco.Web.UI.Client\" + Debug.AspNetCompiler.PhysicalPath = "src\Umbraco.Web.UI.Client\" Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_3961\" Debug.AspNetCompiler.Updateable = "true" Debug.AspNetCompiler.ForceOverwrite = "true" Debug.AspNetCompiler.FixedNames = "false" Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.VirtualPath = "/localhost_3961" - Release.AspNetCompiler.PhysicalPath = "Umbraco.Web.UI.Client\" + Release.AspNetCompiler.PhysicalPath = "src\Umbraco.Web.UI.Client\" Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_3961\" Release.AspNetCompiler.Updateable = "true" Release.AspNetCompiler.ForceOverwrite = "true" Release.AspNetCompiler.FixedNames = "false" Release.AspNetCompiler.Debug = "False" - SlnRelativePath = "Umbraco.Web.UI.Client\" + SlnRelativePath = "src\Umbraco.Web.UI.Client\" DefaultWebSiteLanguage = "Visual C#" StartServerOnDebug = "false" EndProjectSection @@ -70,20 +70,20 @@ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Tests.AcceptanceTes UseIISExpress = "true" TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.5" Debug.AspNetCompiler.VirtualPath = "/localhost_62926" - Debug.AspNetCompiler.PhysicalPath = "Umbraco.Tests.AcceptanceTest\" + Debug.AspNetCompiler.PhysicalPath = "src\Umbraco.Tests.AcceptanceTest\" Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_62926\" Debug.AspNetCompiler.Updateable = "true" Debug.AspNetCompiler.ForceOverwrite = "true" Debug.AspNetCompiler.FixedNames = "false" Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.VirtualPath = "/localhost_62926" - Release.AspNetCompiler.PhysicalPath = "Umbraco.Tests.AcceptanceTest\" + Release.AspNetCompiler.PhysicalPath = "src\Umbraco.Tests.AcceptanceTest\" Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_62926\" Release.AspNetCompiler.Updateable = "true" Release.AspNetCompiler.ForceOverwrite = "true" Release.AspNetCompiler.FixedNames = "false" Release.AspNetCompiler.Debug = "False" - SlnRelativePath = "Umbraco.Tests.AcceptanceTest\" + SlnRelativePath = "src\Umbraco.Tests.AcceptanceTest\" DefaultWebSiteLanguage = "Visual C#" StartServerOnDebug = "false" EndProjectSection From 82959816d8fb31a2143c447dedcd3472e3f030f7 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Fri, 1 Oct 2021 09:17:45 +0200 Subject: [PATCH 08/29] Bump to 9.1.0 --- .../UmbracoPackage/.template.config/template.json | 2 +- .../UmbracoProject/.template.config/template.json | 2 +- src/Directory.Build.props | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build/templates/UmbracoPackage/.template.config/template.json b/build/templates/UmbracoPackage/.template.config/template.json index ea2f65a37c..64785c0f59 100644 --- a/build/templates/UmbracoPackage/.template.config/template.json +++ b/build/templates/UmbracoPackage/.template.config/template.json @@ -24,7 +24,7 @@ "version": { "type": "parameter", "datatype": "string", - "defaultValue": "9.0.0", + "defaultValue": "9.1.0", "description": "The version of Umbraco to load using NuGet", "replaces": "UMBRACO_VERSION_FROM_TEMPLATE" }, diff --git a/build/templates/UmbracoProject/.template.config/template.json b/build/templates/UmbracoProject/.template.config/template.json index 587b8eb292..7e4e8afb27 100644 --- a/build/templates/UmbracoProject/.template.config/template.json +++ b/build/templates/UmbracoProject/.template.config/template.json @@ -57,7 +57,7 @@ "version": { "type": "parameter", "datatype": "string", - "defaultValue": "9.0.0", + "defaultValue": "9.1.0", "description": "The version of Umbraco to load using NuGet", "replaces": "UMBRACO_VERSION_FROM_TEMPLATE" }, diff --git a/src/Directory.Build.props b/src/Directory.Build.props index d51557b8ee..3bb1e71767 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,9 +1,9 @@  - 9.0.0 - 9.0.0 - 9.0.0 - 9.0.0 + 9.1.0 + 9.1.0 + 9.1.0 + 9.1.0 9.0 en-US Umbraco CMS From 213d8c00aa6655b2b5c1514c337221898b3c2ed9 Mon Sep 17 00:00:00 2001 From: Ronald Barendse Date: Mon, 4 Oct 2021 09:45:33 +0200 Subject: [PATCH 09/29] Remove inherited property group id/key when local properties are added (#11231) * Remove inherited property group id/key when local properties are added * Rebind saved content type values * Remove inherited from save group (cherry picked from commit 20b9db87d091e7d53f9f25d4d11744afcffa2584) --- .../services/contenttypehelper.service.js | 39 +++++++++++++++++ .../services/umbdataformatter.service.js | 40 +++++++++-------- .../views/documenttypes/edit.controller.js | 32 ++------------ .../src/views/mediatypes/edit.controller.js | 35 ++------------- .../src/views/membertypes/edit.controller.js | 43 +++---------------- 5 files changed, 73 insertions(+), 116 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js index d9157093a7..cceb67689f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js @@ -439,6 +439,45 @@ function contentTypeHelper(contentTypeResource, dataTypeResource, $filter, $inje array.push(placeholder); + }, + + rebindSavedContentType: function (contentType, savedContentType) { + // The saved content type might have updated values (eg. new IDs/keys), so make sure the view model is updated + contentType.ModelState = savedContentType.ModelState; + contentType.id = savedContentType.id; + contentType.groups.forEach(function (group) { + if (!group.alias) return; + + var k = 0; + while (k < savedContentType.groups.length && savedContentType.groups[k].alias != group.alias) + k++; + + if (k == savedContentType.groups.length) { + group.id = 0; + return; + } + + var savedGroup = savedContentType.groups[k]; + group.id = savedGroup.id; + group.key = savedGroup.key; + group.contentTypeId = savedGroup.contentTypeId; + + group.properties.forEach(function (property) { + if (property.id || !property.alias) return; + + k = 0; + while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias) + k++; + + if (k == savedGroup.properties.length) { + property.id = 0; + return; + } + + var savedProperty = savedGroup.properties[k]; + property.id = savedProperty.id; + }); + }); } }; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js b/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js index 226fabeae4..7270ae5bbf 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js @@ -37,7 +37,7 @@ return { - formatChangePasswordModel: function(model) { + formatChangePasswordModel: function (model) { if (!model) { return null; } @@ -59,26 +59,23 @@ }, formatContentTypePostData: function (displayModel, action) { - - //create the save model from the display model + // Create the save model from the display model var saveModel = _.pick(displayModel, 'compositeContentTypes', 'isContainer', 'allowAsRoot', 'allowedTemplates', 'allowedContentTypes', 'alias', 'description', 'thumbnail', 'name', 'id', 'icon', 'trashed', 'key', 'parentId', 'alias', 'path', 'allowCultureVariant', 'allowSegmentVariant', 'isElement'); - // TODO: Map these saveModel.allowedTemplates = _.map(displayModel.allowedTemplates, function (t) { return t.alias; }); saveModel.defaultTemplate = displayModel.defaultTemplate ? displayModel.defaultTemplate.alias : null; var realGroups = _.reject(displayModel.groups, function (g) { - //do not include these tabs + // Do not include groups with init state return g.tabState === "init"; }); saveModel.groups = _.map(realGroups, function (g) { - - var saveGroup = _.pick(g, 'inherited', 'id', 'sortOrder', 'name', 'key', 'alias', 'type'); + var saveGroup = _.pick(g, 'id', 'sortOrder', 'name', 'key', 'alias', 'type'); var realProperties = _.reject(g.properties, function (p) { - //do not include these properties + // Do not include properties with init state or inherited from a composition return p.propertyState === "init" || p.inherited === true; }); @@ -89,16 +86,21 @@ saveGroup.properties = saveProperties; - //if this is an inherited group and there are not non-inherited properties on it, then don't send up the data - if (saveGroup.inherited === true && saveProperties.length === 0) { - return null; + if (g.inherited === true) { + if (saveProperties.length === 0) { + // All properties are inherited from the compositions, no need to save this group + return null; + } else if (g.contentTypeId != saveModel.id) { + // We have local properties, but the group id is not local, ensure a new id/key is generated on save + saveGroup = _.omit(saveGroup, 'id', 'key'); + } } return saveGroup; }); - //we don't want any null groups saveModel.groups = _.reject(saveModel.groups, function (g) { + // Do not include empty/null groups return !g; }); @@ -127,17 +129,17 @@ }, /** formats the display model used to display the dictionary to the model used to save the dictionary */ - formatDictionaryPostData : function(dictionary, nameIsDirty) { + formatDictionaryPostData: function (dictionary, nameIsDirty) { var saveModel = { parentId: dictionary.parentId, id: dictionary.id, name: dictionary.name, nameIsDirty: nameIsDirty, translations: [], - key : dictionary.key + key: dictionary.key }; - for(var i = 0; i < dictionary.translations.length; i++) { + for (var i = 0; i < dictionary.translations.length; i++) { saveModel.translations.push({ isoCode: dictionary.translations[i].isoCode, languageId: dictionary.translations[i].languageId, @@ -362,7 +364,7 @@ parentId: displayModel.parentId, //set the action on the save model action: action, - variants: _.map(displayModel.variants, function(v) { + variants: _.map(displayModel.variants, function (v) { return { name: v.name || "", //if its null/empty,we must pass up an empty string else we get json converter errors properties: getContentProperties(v.tabs), @@ -392,7 +394,7 @@ * @param {} displayModel * @returns {} */ - formatContentGetData: function(displayModel) { + formatContentGetData: function (displayModel) { // We need to check for invariant properties among the variant variants, // as the value of an invariant property is shared between different variants. @@ -458,12 +460,12 @@ * Formats the display model used to display the relation type to a model used to save the relation type. * @param {Object} relationType */ - formatRelationTypePostData : function(relationType) { + formatRelationTypePostData: function (relationType) { var saveModel = { id: relationType.id, name: relationType.name, alias: relationType.alias, - key : relationType.key, + key: relationType.key, isBidirectional: relationType.isBidirectional, parentObjectType: relationType.parentObjectType, childObjectType: relationType.childObjectType diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js index 3672af900c..a5e49163f9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js @@ -324,35 +324,9 @@ scope: $scope, content: vm.contentType, infiniteMode: infiniteMode, - // we need to rebind... the IDs that have been created! - rebindCallback: function (origContentType, savedContentType) { - vm.contentType.ModelState = savedContentType.ModelState; - vm.contentType.id = savedContentType.id; - vm.contentType.groups.forEach(function (group) { - if (!group.name) return; - var k = 0; - while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name) - k++; - if (k == savedContentType.groups.length) { - group.id = 0; - return; - } - var savedGroup = savedContentType.groups[k]; - if (!group.id) group.id = savedGroup.id; - - group.properties.forEach(function (property) { - if (property.id || !property.alias) return; - k = 0; - while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias) - k++; - if (k == savedGroup.properties.length) { - property.id = 0; - return; - } - var savedProperty = savedGroup.properties[k]; - property.id = savedProperty.id; - }); - }); + rebindCallback: function (_, savedContentType) { + // we need to rebind... the IDs that have been created! + contentTypeHelper.rebindSavedContentType(vm.contentType, savedContentType); } }).then(function (data) { // allow UI to access server validation state diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.controller.js index ecf2aec30c..32fac36baa 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.controller.js @@ -295,38 +295,9 @@ saveMethod: mediaTypeResource.save, scope: $scope, content: vm.contentType, - // we need to rebind... the IDs that have been created! - rebindCallback: function (origContentType, savedContentType) { - vm.contentType.id = savedContentType.id; - vm.contentType.groups.forEach(function (group) { - if (!group.name) return; - - var k = 0; - while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name) - k++; - if (k == savedContentType.groups.length) { - group.id = 0; - return; - } - - var savedGroup = savedContentType.groups[k]; - if (!group.id) group.id = savedGroup.id; - - group.properties.forEach(function (property) { - if (property.id || !property.alias) return; - - k = 0; - while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias) - k++; - if (k == savedGroup.properties.length) { - property.id = 0; - return; - } - - var savedProperty = savedGroup.properties[k]; - property.id = savedProperty.id; - }); - }); + rebindCallback: function (_, savedContentType) { + // we need to rebind... the IDs that have been created! + contentTypeHelper.rebindSavedContentType(vm.contentType, savedContentType); } }).then(function (data) { //success diff --git a/src/Umbraco.Web.UI.Client/src/views/membertypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/membertypes/edit.controller.js index 53bb4adb9b..2eddc71924 100644 --- a/src/Umbraco.Web.UI.Client/src/views/membertypes/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/membertypes/edit.controller.js @@ -175,11 +175,11 @@ //we are creating so get an empty data type item memberTypeResource.getScaffold(memberTypeId) - .then(function (dt) { - init(dt); + .then(function (dt) { + init(dt); - vm.page.loading = false; - }); + vm.page.loading = false; + }); } else { loadMemberType(); @@ -215,38 +215,9 @@ saveMethod: memberTypeResource.save, scope: $scope, content: vm.contentType, - // we need to rebind... the IDs that have been created! - rebindCallback: function (origContentType, savedContentType) { - vm.contentType.id = savedContentType.id; - vm.contentType.groups.forEach(function (group) { - if (!group.name) return; - - var k = 0; - while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name) - k++; - if (k == savedContentType.groups.length) { - group.id = 0; - return; - } - - var savedGroup = savedContentType.groups[k]; - if (!group.id) group.id = savedGroup.id; - - group.properties.forEach(function (property) { - if (property.id || !property.alias) return; - - k = 0; - while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias) - k++; - if (k == savedGroup.properties.length) { - property.id = 0; - return; - } - - var savedProperty = savedGroup.properties[k]; - property.id = savedProperty.id; - }); - }); + rebindCallback: function (_, savedContentType) { + // we need to rebind... the IDs that have been created! + contentTypeHelper.rebindSavedContentType(vm.contentType, savedContentType); } }).then(function (data) { //success From 5a3efa72f95975833e281edd24092658080082aa Mon Sep 17 00:00:00 2001 From: Ronald Barendse Date: Mon, 4 Oct 2021 09:45:33 +0200 Subject: [PATCH 10/29] Remove inherited property group id/key when local properties are added (#11231) * Remove inherited property group id/key when local properties are added * Rebind saved content type values * Remove inherited from save group (cherry picked from commit 20b9db87d091e7d53f9f25d4d11744afcffa2584) --- .../services/contenttypehelper.service.js | 39 +++++++++++++++++ .../services/umbdataformatter.service.js | 40 +++++++++-------- .../views/documentTypes/edit.controller.js | 32 ++------------ .../src/views/mediaTypes/edit.controller.js | 35 ++------------- .../src/views/memberTypes/edit.controller.js | 43 +++---------------- 5 files changed, 73 insertions(+), 116 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js index 5198f5d9bd..c638841066 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js @@ -439,6 +439,45 @@ function contentTypeHelper(contentTypeResource, dataTypeResource, $filter, $inje array.push(placeholder); + }, + + rebindSavedContentType: function (contentType, savedContentType) { + // The saved content type might have updated values (eg. new IDs/keys), so make sure the view model is updated + contentType.ModelState = savedContentType.ModelState; + contentType.id = savedContentType.id; + contentType.groups.forEach(function (group) { + if (!group.alias) return; + + var k = 0; + while (k < savedContentType.groups.length && savedContentType.groups[k].alias != group.alias) + k++; + + if (k == savedContentType.groups.length) { + group.id = 0; + return; + } + + var savedGroup = savedContentType.groups[k]; + group.id = savedGroup.id; + group.key = savedGroup.key; + group.contentTypeId = savedGroup.contentTypeId; + + group.properties.forEach(function (property) { + if (property.id || !property.alias) return; + + k = 0; + while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias) + k++; + + if (k == savedGroup.properties.length) { + property.id = 0; + return; + } + + var savedProperty = savedGroup.properties[k]; + property.id = savedProperty.id; + }); + }); } }; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js b/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js index f6b24dd12b..40266f7ac5 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js @@ -37,7 +37,7 @@ return { - formatChangePasswordModel: function(model) { + formatChangePasswordModel: function (model) { if (!model) { return null; } @@ -59,26 +59,23 @@ }, formatContentTypePostData: function (displayModel, action) { - - //create the save model from the display model + // Create the save model from the display model var saveModel = _.pick(displayModel, 'compositeContentTypes', 'isContainer', 'allowAsRoot', 'allowedTemplates', 'allowedContentTypes', 'alias', 'description', 'thumbnail', 'name', 'id', 'icon', 'trashed', 'key', 'parentId', 'alias', 'path', 'allowCultureVariant', 'allowSegmentVariant', 'isElement'); - // TODO: Map these saveModel.allowedTemplates = _.map(displayModel.allowedTemplates, function (t) { return t.alias; }); saveModel.defaultTemplate = displayModel.defaultTemplate ? displayModel.defaultTemplate.alias : null; var realGroups = _.reject(displayModel.groups, function (g) { - //do not include these tabs + // Do not include groups with init state return g.tabState === "init"; }); saveModel.groups = _.map(realGroups, function (g) { - - var saveGroup = _.pick(g, 'inherited', 'id', 'sortOrder', 'name', 'key', 'alias', 'type'); + var saveGroup = _.pick(g, 'id', 'sortOrder', 'name', 'key', 'alias', 'type'); var realProperties = _.reject(g.properties, function (p) { - //do not include these properties + // Do not include properties with init state or inherited from a composition return p.propertyState === "init" || p.inherited === true; }); @@ -89,16 +86,21 @@ saveGroup.properties = saveProperties; - //if this is an inherited group and there are not non-inherited properties on it, then don't send up the data - if (saveGroup.inherited === true && saveProperties.length === 0) { - return null; + if (g.inherited === true) { + if (saveProperties.length === 0) { + // All properties are inherited from the compositions, no need to save this group + return null; + } else if (g.contentTypeId != saveModel.id) { + // We have local properties, but the group id is not local, ensure a new id/key is generated on save + saveGroup = _.omit(saveGroup, 'id', 'key'); + } } return saveGroup; }); - //we don't want any null groups saveModel.groups = _.reject(saveModel.groups, function (g) { + // Do not include empty/null groups return !g; }); @@ -127,17 +129,17 @@ }, /** formats the display model used to display the dictionary to the model used to save the dictionary */ - formatDictionaryPostData : function(dictionary, nameIsDirty) { + formatDictionaryPostData: function (dictionary, nameIsDirty) { var saveModel = { parentId: dictionary.parentId, id: dictionary.id, name: dictionary.name, nameIsDirty: nameIsDirty, translations: [], - key : dictionary.key + key: dictionary.key }; - for(var i = 0; i < dictionary.translations.length; i++) { + for (var i = 0; i < dictionary.translations.length; i++) { saveModel.translations.push({ isoCode: dictionary.translations[i].isoCode, languageId: dictionary.translations[i].languageId, @@ -335,7 +337,7 @@ parentId: displayModel.parentId, //set the action on the save model action: action, - variants: _.map(displayModel.variants, function(v) { + variants: _.map(displayModel.variants, function (v) { return { name: v.name || "", //if its null/empty,we must pass up an empty string else we get json converter errors properties: getContentProperties(v.tabs), @@ -365,7 +367,7 @@ * @param {} displayModel * @returns {} */ - formatContentGetData: function(displayModel) { + formatContentGetData: function (displayModel) { // We need to check for invariant properties among the variant variants, // as the value of an invariant property is shared between different variants. @@ -431,12 +433,12 @@ * Formats the display model used to display the relation type to a model used to save the relation type. * @param {Object} relationType */ - formatRelationTypePostData : function(relationType) { + formatRelationTypePostData: function (relationType) { var saveModel = { id: relationType.id, name: relationType.name, alias: relationType.alias, - key : relationType.key, + key: relationType.key, isBidirectional: relationType.isBidirectional, parentObjectType: relationType.parentObjectType, childObjectType: relationType.childObjectType diff --git a/src/Umbraco.Web.UI.Client/src/views/documentTypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/documentTypes/edit.controller.js index b8fdf7b89d..0e13657e68 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documentTypes/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/documentTypes/edit.controller.js @@ -324,35 +324,9 @@ scope: $scope, content: vm.contentType, infiniteMode: infiniteMode, - // we need to rebind... the IDs that have been created! - rebindCallback: function (origContentType, savedContentType) { - vm.contentType.ModelState = savedContentType.ModelState; - vm.contentType.id = savedContentType.id; - vm.contentType.groups.forEach(function (group) { - if (!group.name) return; - var k = 0; - while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name) - k++; - if (k == savedContentType.groups.length) { - group.id = 0; - return; - } - var savedGroup = savedContentType.groups[k]; - if (!group.id) group.id = savedGroup.id; - - group.properties.forEach(function (property) { - if (property.id || !property.alias) return; - k = 0; - while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias) - k++; - if (k == savedGroup.properties.length) { - property.id = 0; - return; - } - var savedProperty = savedGroup.properties[k]; - property.id = savedProperty.id; - }); - }); + rebindCallback: function (_, savedContentType) { + // we need to rebind... the IDs that have been created! + contentTypeHelper.rebindSavedContentType(vm.contentType, savedContentType); } }).then(function (data) { // allow UI to access server validation state diff --git a/src/Umbraco.Web.UI.Client/src/views/mediaTypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/mediaTypes/edit.controller.js index 6d23a525a5..8c0ce561d9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediaTypes/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/mediaTypes/edit.controller.js @@ -295,38 +295,9 @@ saveMethod: mediaTypeResource.save, scope: $scope, content: vm.contentType, - // we need to rebind... the IDs that have been created! - rebindCallback: function (origContentType, savedContentType) { - vm.contentType.id = savedContentType.id; - vm.contentType.groups.forEach(function (group) { - if (!group.name) return; - - var k = 0; - while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name) - k++; - if (k == savedContentType.groups.length) { - group.id = 0; - return; - } - - var savedGroup = savedContentType.groups[k]; - if (!group.id) group.id = savedGroup.id; - - group.properties.forEach(function (property) { - if (property.id || !property.alias) return; - - k = 0; - while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias) - k++; - if (k == savedGroup.properties.length) { - property.id = 0; - return; - } - - var savedProperty = savedGroup.properties[k]; - property.id = savedProperty.id; - }); - }); + rebindCallback: function (_, savedContentType) { + // we need to rebind... the IDs that have been created! + contentTypeHelper.rebindSavedContentType(vm.contentType, savedContentType); } }).then(function (data) { //success diff --git a/src/Umbraco.Web.UI.Client/src/views/memberTypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/memberTypes/edit.controller.js index 8854b960e7..f5658ad1df 100644 --- a/src/Umbraco.Web.UI.Client/src/views/memberTypes/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/memberTypes/edit.controller.js @@ -175,11 +175,11 @@ //we are creating so get an empty data type item memberTypeResource.getScaffold(memberTypeId) - .then(function (dt) { - init(dt); + .then(function (dt) { + init(dt); - vm.page.loading = false; - }); + vm.page.loading = false; + }); } else { loadMemberType(); @@ -215,38 +215,9 @@ saveMethod: memberTypeResource.save, scope: $scope, content: vm.contentType, - // we need to rebind... the IDs that have been created! - rebindCallback: function (origContentType, savedContentType) { - vm.contentType.id = savedContentType.id; - vm.contentType.groups.forEach(function (group) { - if (!group.name) return; - - var k = 0; - while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name) - k++; - if (k == savedContentType.groups.length) { - group.id = 0; - return; - } - - var savedGroup = savedContentType.groups[k]; - if (!group.id) group.id = savedGroup.id; - - group.properties.forEach(function (property) { - if (property.id || !property.alias) return; - - k = 0; - while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias) - k++; - if (k == savedGroup.properties.length) { - property.id = 0; - return; - } - - var savedProperty = savedGroup.properties[k]; - property.id = savedProperty.id; - }); - }); + rebindCallback: function (_, savedContentType) { + // we need to rebind... the IDs that have been created! + contentTypeHelper.rebindSavedContentType(vm.contentType, savedContentType); } }).then(function (data) { //success From 5300d74cdae3ecab9ef140ad71e464664030b820 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 4 Oct 2021 11:15:28 +0200 Subject: [PATCH 11/29] Bump version to 9.0.1 --- .../UmbracoPackage/.template.config/template.json | 2 +- .../UmbracoProject/.template.config/template.json | 2 +- src/Directory.Build.props | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build/templates/UmbracoPackage/.template.config/template.json b/build/templates/UmbracoPackage/.template.config/template.json index ea2f65a37c..9daa959f7c 100644 --- a/build/templates/UmbracoPackage/.template.config/template.json +++ b/build/templates/UmbracoPackage/.template.config/template.json @@ -24,7 +24,7 @@ "version": { "type": "parameter", "datatype": "string", - "defaultValue": "9.0.0", + "defaultValue": "9.0.1", "description": "The version of Umbraco to load using NuGet", "replaces": "UMBRACO_VERSION_FROM_TEMPLATE" }, diff --git a/build/templates/UmbracoProject/.template.config/template.json b/build/templates/UmbracoProject/.template.config/template.json index 587b8eb292..ca72873db0 100644 --- a/build/templates/UmbracoProject/.template.config/template.json +++ b/build/templates/UmbracoProject/.template.config/template.json @@ -57,7 +57,7 @@ "version": { "type": "parameter", "datatype": "string", - "defaultValue": "9.0.0", + "defaultValue": "9.0.1", "description": "The version of Umbraco to load using NuGet", "replaces": "UMBRACO_VERSION_FROM_TEMPLATE" }, diff --git a/src/Directory.Build.props b/src/Directory.Build.props index d51557b8ee..0461176c23 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,9 +1,9 @@  - 9.0.0 - 9.0.0 - 9.0.0 - 9.0.0 + 9.0.1 + 9.0.1 + 9.0.1 + 9.0.1 9.0 en-US Umbraco CMS From fed6eaa03d5cc63de21e5e16878390dd57bb0164 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 4 Oct 2021 11:47:03 +0200 Subject: [PATCH 12/29] Avoid breaking changes from merge. --- .../Persistence/UmbracoDatabaseFactory.cs | 69 ++++++++++++------- .../Runtime/SqlMainDomLock.cs | 14 +--- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs b/src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs index 299aff2caa..fd8bdc0269 100644 --- a/src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs +++ b/src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.Options; using NPoco; using NPoco.FluentMappings; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Infrastructure.Migrations.Install; using Umbraco.Cms.Infrastructure.Persistence.FaultHandling; @@ -72,6 +73,47 @@ namespace Umbraco.Cms.Infrastructure.Persistence #region Constructors + + /// + /// Initializes a new instance of the . + /// + /// Used by the other ctor and in tests. + internal UmbracoDatabaseFactory( + ILogger logger, + ILoggerFactory loggerFactory, + IOptions globalSettings, + IMapperCollection mappers, + IDbProviderFactoryCreator dbProviderFactoryCreator, + DatabaseSchemaCreatorFactory databaseSchemaCreatorFactory, + NPocoMapperCollection npocoMappers, + string connectionString) + { + _globalSettings = globalSettings; + _mappers = mappers ?? throw new ArgumentNullException(nameof(mappers)); + _dbProviderFactoryCreator = dbProviderFactoryCreator ?? throw new ArgumentNullException(nameof(dbProviderFactoryCreator)); + _databaseSchemaCreatorFactory = databaseSchemaCreatorFactory ?? throw new ArgumentNullException(nameof(databaseSchemaCreatorFactory)); + _npocoMappers = npocoMappers; + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _loggerFactory = loggerFactory; + + if (connectionString is null) + { + logger.LogDebug("Missing connection string, defer configuration."); + return; // not configured + } + + var configConnectionString = new ConfigConnectionString("Custom", connectionString); + // could as well be + // so need to test the values too + if (configConnectionString.IsConnectionStringConfigured() == false) + { + logger.LogDebug("Empty connection string or provider name, defer configuration."); + return; // not configured + } + + Configure(configConnectionString.ConnectionString, configConnectionString.ProviderName); + } + /// /// Initializes a new instance of the . /// @@ -84,33 +126,10 @@ namespace Umbraco.Cms.Infrastructure.Persistence IMapperCollection mappers, IDbProviderFactoryCreator dbProviderFactoryCreator, DatabaseSchemaCreatorFactory databaseSchemaCreatorFactory, - NPocoMapperCollection npocoMappers) + NPocoMapperCollection npocoMappers): + this(logger, loggerFactory, globalSettings, mappers, dbProviderFactoryCreator, databaseSchemaCreatorFactory, npocoMappers, connectionStrings?.CurrentValue?.UmbracoConnectionString?.ConnectionString) { - _globalSettings = globalSettings; - _mappers = mappers ?? throw new ArgumentNullException(nameof(mappers)); - _dbProviderFactoryCreator = dbProviderFactoryCreator ?? throw new ArgumentNullException(nameof(dbProviderFactoryCreator)); - _databaseSchemaCreatorFactory = databaseSchemaCreatorFactory ?? throw new ArgumentNullException(nameof(databaseSchemaCreatorFactory)); - _npocoMappers = npocoMappers; - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _loggerFactory = loggerFactory; - - var settings = connectionStrings.CurrentValue.UmbracoConnectionString; - if (settings == null) - { - logger.LogDebug("Missing connection string, defer configuration."); - return; // not configured - } - - // could as well be - // so need to test the values too - if (settings.IsConnectionStringConfigured() == false) - { - logger.LogDebug("Empty connection string or provider name, defer configuration."); - return; // not configured - } - - Configure(settings.ConnectionString, settings.ProviderName); } #endregion diff --git a/src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs b/src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs index 8dee49a07c..8d1c74b619 100644 --- a/src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs +++ b/src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs @@ -62,11 +62,11 @@ namespace Umbraco.Cms.Infrastructure.Runtime loggerFactory.CreateLogger(), loggerFactory, _globalSettings, - connectionStrings, new MapperCollection(() => Enumerable.Empty()), dbProviderFactoryCreator, databaseSchemaCreatorFactory, - npocoMappers); + npocoMappers, + connectionStringName); MainDomKey = MainDomKeyPrefix + "-" + (Environment.MachineName + MainDom.GetMainDomId(_hostingEnvironment)).GenerateHash(); } @@ -88,18 +88,10 @@ namespace Umbraco.Cms.Infrastructure.Runtime hostingEnvironment, databaseSchemaCreatorFactory, npocoMappers, - Constants.System.UmbracoConnectionName + connectionStrings.CurrentValue.UmbracoConnectionString.ConnectionString ) { - loggerFactory.CreateLogger(), - loggerFactory, - _globalSettings, - connectionStrings, - new MapperCollection(() => Enumerable.Empty()), - dbProviderFactoryCreator, - databaseSchemaCreatorFactory, - npocoMappers); } public async Task AcquireLockAsync(int millisecondsTimeout) From 2922871a730b62fa20b53dd252076ddf0e2a0165 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 4 Oct 2021 13:42:06 +0200 Subject: [PATCH 13/29] https://github.com/umbraco/Umbraco-CMS/issues/11227 Set culture from domain when internal redirecting due to public access --- src/Umbraco.Core/Routing/PublishedRouter.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Routing/PublishedRouter.cs b/src/Umbraco.Core/Routing/PublishedRouter.cs index 548387a675..590262946d 100644 --- a/src/Umbraco.Core/Routing/PublishedRouter.cs +++ b/src/Umbraco.Core/Routing/PublishedRouter.cs @@ -237,7 +237,7 @@ namespace Umbraco.Cms.Core.Routing // re-route await RouteRequestInternalAsync(builder); - + // return if we are redirect if (builder.IsRedirect()) { @@ -252,6 +252,11 @@ namespace Umbraco.Cms.Core.Routing builder.SetPublishedContent(content); } + if (!builder.HasDomain()) + { + FindDomain(builder); + } + return BuildRequest(builder); } From eaa0f4618fa3c82b85a335567720bc9b7486ce85 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Mon, 4 Oct 2021 18:44:14 +0200 Subject: [PATCH 14/29] Ensured order of Deploy artifact dependencies irrespective of ICU or NLS globalization settings. (#11265) --- src/Umbraco.Core/Udi.cs | 4 +-- .../Umbraco.Core/Deploy/ArtifactBaseTests.cs | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Udi.cs b/src/Umbraco.Core/Udi.cs index b861bcc68b..208ac536c1 100644 --- a/src/Umbraco.Core/Udi.cs +++ b/src/Umbraco.Core/Udi.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel; using System.Linq; @@ -44,7 +44,7 @@ namespace Umbraco.Cms.Core public int CompareTo(Udi other) { - return string.Compare(UriValue.ToString(), other.UriValue.ToString(), StringComparison.InvariantCultureIgnoreCase); + return string.Compare(UriValue.ToString(), other.UriValue.ToString(), StringComparison.OrdinalIgnoreCase); } public override string ToString() diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Deploy/ArtifactBaseTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Deploy/ArtifactBaseTests.cs index 1a2ffa8011..c4cd4f0c02 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Deploy/ArtifactBaseTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Deploy/ArtifactBaseTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using Newtonsoft.Json; using NUnit.Framework; using Umbraco.Cms.Core; @@ -29,6 +30,33 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Deploy Assert.AreEqual(expected, serialized); } + [Test] + public void Dependencies_Are_Correctly_Ordered() + { + // This test was introduced following: https://github.com/umbraco/Umbraco.Deploy.Issues/issues/72 to verify + // that consistent ordering rules are used across platforms. + var udi = new GuidUdi("test", Guid.Parse("3382d5433b5749d08919bc9961422a1f")); + var artifact = new TestArtifact(udi, new List()) + { + Name = "Test Name", + Alias = "testAlias", + }; + + var dependencies = new ArtifactDependencyCollection(); + + var dependencyUdi1 = new GuidUdi("template", Guid.Parse("d4651496fad24c1290a53ea4d55d945b")); + dependencies.Add(new ArtifactDependency(dependencyUdi1, true, ArtifactDependencyMode.Exist)); + + var dependencyUdi2 = new StringUdi(Constants.UdiEntityType.TemplateFile, "TestPage.cshtml"); + dependencies.Add(new ArtifactDependency(dependencyUdi2, true, ArtifactDependencyMode.Exist)); + + artifact.Dependencies = dependencies; + + Assert.AreEqual( + "umb://template-file/TestPage.cshtml,umb://template/d4651496fad24c1290a53ea4d55d945b", + string.Join(",", artifact.Dependencies.Select(x => x.Udi.ToString()))); + } + private class TestArtifact : ArtifactBase { public TestArtifact(GuidUdi udi, IEnumerable dependencies = null) : base(udi, dependencies) From f3f674437d101ebdd647dd21aa1bbba4b51b6229 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Mon, 4 Oct 2021 18:44:14 +0200 Subject: [PATCH 15/29] Ensured order of Deploy artifact dependencies irrespective of ICU or NLS globalization settings. (#11265) --- src/Umbraco.Core/Udi.cs | 4 +-- .../Umbraco.Core/Deploy/ArtifactBaseTests.cs | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Udi.cs b/src/Umbraco.Core/Udi.cs index b861bcc68b..208ac536c1 100644 --- a/src/Umbraco.Core/Udi.cs +++ b/src/Umbraco.Core/Udi.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel; using System.Linq; @@ -44,7 +44,7 @@ namespace Umbraco.Cms.Core public int CompareTo(Udi other) { - return string.Compare(UriValue.ToString(), other.UriValue.ToString(), StringComparison.InvariantCultureIgnoreCase); + return string.Compare(UriValue.ToString(), other.UriValue.ToString(), StringComparison.OrdinalIgnoreCase); } public override string ToString() diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Deploy/ArtifactBaseTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Deploy/ArtifactBaseTests.cs index 1a2ffa8011..c4cd4f0c02 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Deploy/ArtifactBaseTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Deploy/ArtifactBaseTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using Newtonsoft.Json; using NUnit.Framework; using Umbraco.Cms.Core; @@ -29,6 +30,33 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Deploy Assert.AreEqual(expected, serialized); } + [Test] + public void Dependencies_Are_Correctly_Ordered() + { + // This test was introduced following: https://github.com/umbraco/Umbraco.Deploy.Issues/issues/72 to verify + // that consistent ordering rules are used across platforms. + var udi = new GuidUdi("test", Guid.Parse("3382d5433b5749d08919bc9961422a1f")); + var artifact = new TestArtifact(udi, new List()) + { + Name = "Test Name", + Alias = "testAlias", + }; + + var dependencies = new ArtifactDependencyCollection(); + + var dependencyUdi1 = new GuidUdi("template", Guid.Parse("d4651496fad24c1290a53ea4d55d945b")); + dependencies.Add(new ArtifactDependency(dependencyUdi1, true, ArtifactDependencyMode.Exist)); + + var dependencyUdi2 = new StringUdi(Constants.UdiEntityType.TemplateFile, "TestPage.cshtml"); + dependencies.Add(new ArtifactDependency(dependencyUdi2, true, ArtifactDependencyMode.Exist)); + + artifact.Dependencies = dependencies; + + Assert.AreEqual( + "umb://template-file/TestPage.cshtml,umb://template/d4651496fad24c1290a53ea4d55d945b", + string.Join(",", artifact.Dependencies.Select(x => x.Udi.ToString()))); + } + private class TestArtifact : ArtifactBase { public TestArtifact(GuidUdi udi, IEnumerable dependencies = null) : base(udi, dependencies) From 02d89ce613a6153f721c75e97b4ef03251e01dc5 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 4 Oct 2021 19:40:32 +0200 Subject: [PATCH 16/29] https://github.com/umbraco/Umbraco-CMS/issues/11263 Fixes issue where we used the current users email when sending invite emails. Now we use the one from SMTP settings like in v8 --- src/Umbraco.Web.BackOffice/Controllers/UsersController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs index 7e62e514f7..672495c7eb 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs @@ -557,7 +557,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers // i.e. "Some Person" var toMailBoxAddress = new MailboxAddress(to.Name, to.Email); - var mailMessage = new EmailMessage(fromEmail, toMailBoxAddress.ToString(), emailSubject, emailBody, true); + var mailMessage = new EmailMessage(null /*use info from smtp settings*/, toMailBoxAddress.ToString(), emailSubject, emailBody, true); await _emailSender.SendAsync(mailMessage, Constants.Web.EmailTypes.UserInvite, true); } From c5ddc3d872d467b7ea234602d1915f3aca3bb97d Mon Sep 17 00:00:00 2001 From: Louis JR <17555062+louisjrdev@users.noreply.github.com> Date: Mon, 4 Oct 2021 18:48:52 +0100 Subject: [PATCH 17/29] Change template helper to use async partials (#11243) --- .../src/common/services/templatehelper.service.js | 2 +- .../test/unit/common/services/template-helper.spec.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/templatehelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/templatehelper.service.js index 1a2f0735ce..aa10d5bf2f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/templatehelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/templatehelper.service.js @@ -16,7 +16,7 @@ partialViewName = parentId + "/" + partialViewName; } - return "@Html.Partial(\"" + partialViewName + "\")"; + return "@await Html.PartialAsync(\"" + partialViewName + "\")"; } function getQuerySnippet(queryExpression) { diff --git a/src/Umbraco.Web.UI.Client/test/unit/common/services/template-helper.spec.js b/src/Umbraco.Web.UI.Client/test/unit/common/services/template-helper.spec.js index 316cfa7c59..69da0ce786 100644 --- a/src/Umbraco.Web.UI.Client/test/unit/common/services/template-helper.spec.js +++ b/src/Umbraco.Web.UI.Client/test/unit/common/services/template-helper.spec.js @@ -26,28 +26,28 @@ describe('service: templateHelper', function () { it('should return the snippet for inserting a partial from the root', function () { var parentId = ""; var nodeName = "Footer.cshtml"; - var snippet = '@Html.Partial("Footer")'; + var snippet = '@await Html.PartialAsync("Footer")'; expect(templateHelper.getInsertPartialSnippet(parentId, nodeName)).toBe(snippet); }); it('should return the snippet for inserting a partial from a folder', function () { var parentId = "Folder"; var nodeName = "Footer.cshtml"; - var snippet = '@Html.Partial("Folder/Footer")'; + var snippet = '@await Html.PartialAsync("Folder/Footer")'; expect(templateHelper.getInsertPartialSnippet(parentId, nodeName)).toBe(snippet); }); it('should return the snippet for inserting a partial from a nested folder', function () { var parentId = "Folder/NestedFolder"; var nodeName = "Footer.cshtml"; - var snippet = '@Html.Partial("Folder/NestedFolder/Footer")'; + var snippet = '@await Html.PartialAsync("Folder/NestedFolder/Footer")'; expect(templateHelper.getInsertPartialSnippet(parentId, nodeName)).toBe(snippet); }); it('should return the snippet for inserting a partial from a folder with spaces in its name', function () { var parentId = "Folder with spaces"; var nodeName = "Footer.cshtml"; - var snippet = '@Html.Partial("Folder with spaces/Footer")'; + var snippet = '@await Html.PartialAsync("Folder with spaces/Footer")'; expect(templateHelper.getInsertPartialSnippet(parentId, nodeName)).toBe(snippet); }); From 4d4fa4d0412b5c6f5172aaebedef6a135f9abf9d Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 4 Oct 2021 20:01:23 +0200 Subject: [PATCH 18/29] https://github.com/umbraco/Umbraco-CMS/issues/11188 Fixes Missing JSON Schema Property for RuntimeMinification:Version --- .../Configuration/Models/RuntimeMinificationSettings.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Umbraco.Core/Configuration/Models/RuntimeMinificationSettings.cs b/src/Umbraco.Core/Configuration/Models/RuntimeMinificationSettings.cs index b03528fd0a..fe999f7bc0 100644 --- a/src/Umbraco.Core/Configuration/Models/RuntimeMinificationSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/RuntimeMinificationSettings.cs @@ -7,6 +7,7 @@ namespace Umbraco.Cms.Core.Configuration.Models { internal const bool StaticUseInMemoryCache = false; internal const string StaticCacheBuster = "Version"; + internal const string StaticVersion = null; /// /// Use in memory cache @@ -19,5 +20,11 @@ namespace Umbraco.Cms.Core.Configuration.Models /// [DefaultValue(StaticCacheBuster)] public RuntimeMinificationCacheBuster CacheBuster { get; set; } = Enum.Parse(StaticCacheBuster); + + /// + /// The unique version string used if CacheBuster is 'Version'. + /// + [DefaultValue(StaticVersion)] + public string Version { get; set; } = StaticVersion; } } From 931e91760d9e4406d64c9b9b1acdfbebd02c0dbe Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 5 Oct 2021 12:34:39 +0200 Subject: [PATCH 19/29] Force ICU usage on windows. --- build/templates/UmbracoProject/UmbracoProject.csproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build/templates/UmbracoProject/UmbracoProject.csproj b/build/templates/UmbracoProject/UmbracoProject.csproj index 6b0f92858d..efc5425728 100644 --- a/build/templates/UmbracoProject/UmbracoProject.csproj +++ b/build/templates/UmbracoProject/UmbracoProject.csproj @@ -8,6 +8,12 @@ $(DefaultItemExcludes);wwwroot/media/**; + + + + + + From 62f2bdbafaebfdf74b0eaf77c6c7c58bdba296d7 Mon Sep 17 00:00:00 2001 From: Nikolaj Geisle Date: Tue, 5 Oct 2021 13:41:58 +0200 Subject: [PATCH 20/29] Removed obsolete method Signed-off-by: Nikolaj Geisle --- .../Persistence/UmbracoPocoDataBuilder.cs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/Umbraco.Infrastructure/Persistence/UmbracoPocoDataBuilder.cs b/src/Umbraco.Infrastructure/Persistence/UmbracoPocoDataBuilder.cs index 2e9fb6cebc..7bfb7c82ea 100644 --- a/src/Umbraco.Infrastructure/Persistence/UmbracoPocoDataBuilder.cs +++ b/src/Umbraco.Infrastructure/Persistence/UmbracoPocoDataBuilder.cs @@ -18,6 +18,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence /// So far, this is very manual. We don't try to be clever and figure out whether the /// columns exist already. We just ignore it. /// Beware, the application MUST restart when this class behavior changes. + /// You can override the GetColmunnInfo method to control which columns this includes /// internal class UmbracoPocoDataBuilder : PocoDataBuilder { @@ -28,19 +29,5 @@ namespace Umbraco.Cms.Infrastructure.Persistence { _upgrading = upgrading; } - - protected override ColumnInfo GetColumnInfo(MemberInfo mi, Type type) - { - var columnInfo = base.GetColumnInfo(mi, type); - - // TODO: Is this upgrade flag still relevant? It's a lot of hacking to just set this value - // including the interface method ConfigureForUpgrade for this one circumstance. - if (_upgrading) - { - if (type == typeof(UserDto) && mi.Name == "TourData") columnInfo.IgnoreColumn = true; - } - - return columnInfo; - } } } From 80c74968ef666b0e10d3b858701fe484e5af3b0d Mon Sep 17 00:00:00 2001 From: Nikolaj Geisle Date: Tue, 5 Oct 2021 13:48:42 +0200 Subject: [PATCH 21/29] Updated UmbracoPocoDataBuilder.cs Signed-off-by: Nikolaj Geisle --- .../Persistence/UmbracoPocoDataBuilder.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Umbraco.Infrastructure/Persistence/UmbracoPocoDataBuilder.cs b/src/Umbraco.Infrastructure/Persistence/UmbracoPocoDataBuilder.cs index 7bfb7c82ea..0b874a80c2 100644 --- a/src/Umbraco.Infrastructure/Persistence/UmbracoPocoDataBuilder.cs +++ b/src/Umbraco.Infrastructure/Persistence/UmbracoPocoDataBuilder.cs @@ -1,7 +1,5 @@ using System; -using System.Reflection; using NPoco; -using Umbraco.Cms.Infrastructure.Persistence.Dtos; namespace Umbraco.Cms.Infrastructure.Persistence { From 223e8661dcfc9a7136d6d33f28c272661e62e099 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 5 Oct 2021 21:25:15 +0200 Subject: [PATCH 22/29] Fixed bug where the wrong schema was signed in. --- src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs b/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs index 4817956ef8..4f03255fae 100644 --- a/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs +++ b/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs @@ -362,7 +362,7 @@ namespace Umbraco.Cms.Web.Common.Security { // Store the userId for use after two factor check var userId = await UserManager.GetUserIdAsync(user); - await Context.SignInAsync(IdentityConstants.TwoFactorUserIdScheme, StoreTwoFactorInfo(userId, loginProvider)); + await Context.SignInAsync(TwoFactorRememberMeAuthenticationType, StoreTwoFactorInfo(userId, loginProvider)); return SignInResult.TwoFactorRequired; } } @@ -372,7 +372,7 @@ namespace Umbraco.Cms.Web.Common.Security await Context.SignOutAsync(ExternalAuthenticationType); } if (loginProvider == null) - { + { await SignInWithClaimsAsync(user, isPersistent, new Claim[] { new Claim("amr", "pwd") }); } else From 9b6421947af7a123a49754c0a1db49b8bd55cd64 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 5 Oct 2021 21:57:02 +0200 Subject: [PATCH 23/29] Fixed to not use remember me type --- src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs b/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs index 4f03255fae..cc07b6bd28 100644 --- a/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs +++ b/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs @@ -362,7 +362,7 @@ namespace Umbraco.Cms.Web.Common.Security { // Store the userId for use after two factor check var userId = await UserManager.GetUserIdAsync(user); - await Context.SignInAsync(TwoFactorRememberMeAuthenticationType, StoreTwoFactorInfo(userId, loginProvider)); + await Context.SignInAsync(TwoFactorAuthenticationType, StoreTwoFactorInfo(userId, loginProvider)); return SignInResult.TwoFactorRequired; } } From a6492871e8084d9565e70a4ef947379b90d428a9 Mon Sep 17 00:00:00 2001 From: Jeavon Leopold Date: Fri, 1 Oct 2021 16:15:49 +0100 Subject: [PATCH 24/29] Remove all ImageSharp.Web Processors and the re-add in the correct order --- .../DependencyInjection/UmbracoBuilder.ImageSharp.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilder.ImageSharp.cs b/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilder.ImageSharp.cs index 62573cfc7b..6755159fc1 100644 --- a/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilder.ImageSharp.cs +++ b/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilder.ImageSharp.cs @@ -54,8 +54,14 @@ namespace Umbraco.Extensions .Configure(options => options.CacheFolder = builder.BuilderHostingEnvironment.MapPathContentRoot(imagingSettings.Cache.CacheFolder)) // We need to add CropWebProcessor before ResizeWebProcessor (until https://github.com/SixLabors/ImageSharp.Web/issues/182 is fixed) .RemoveProcessor() + .RemoveProcessor() + .RemoveProcessor() + .RemoveProcessor() .AddProcessor() - .AddProcessor(); + .AddProcessor() + .AddProcessor() + .AddProcessor() + .AddProcessor(); builder.Services.AddTransient, ImageSharpConfigurationOptions>(); From 114ab93a6a5ea3244c2afc3bd3ac7572f92b115f Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 6 Oct 2021 10:20:50 +0200 Subject: [PATCH 25/29] Moved endpoint to new controller to avoid issue with too hard access requirements (#11264) * Fixed https://github.com/umbraco/Umbraco-CMS/issues/11258 Moved endpoint and obsoleted the old one to avoid breaking changes.. The issue is the auth policies cannot be overridden.. You need all of them, and the controller requires you to have access to member types * Update src/Umbraco.Web.BackOffice/Controllers/MemberTypeQueryController.cs Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> --- .../Controllers/BackOfficeServerVariables.cs | 4 ++ .../Controllers/MemberTypeController.cs | 1 + .../Controllers/MemberTypeQueryController.cs | 42 +++++++++++++++++++ .../common/resources/membertype.resource.js | 4 +- 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/Umbraco.Web.BackOffice/Controllers/MemberTypeQueryController.cs diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs index a982ed1744..58f3622e67 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs @@ -279,6 +279,10 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers "memberTypeApiBaseUrl", _linkGenerator.GetUmbracoApiServiceBaseUrl( controller => controller.GetAllTypes()) }, + { + "memberTypeQueryApiBaseUrl", _linkGenerator.GetUmbracoApiServiceBaseUrl( + controller => controller.GetAllTypes()) + }, { "memberGroupApiBaseUrl", _linkGenerator.GetUmbracoApiServiceBaseUrl( controller => controller.GetAllGroups()) diff --git a/src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs b/src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs index 4af907bdfc..7c1f6f4187 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs @@ -182,6 +182,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers /// /// Returns all member types /// + [Obsolete("Use MemberTypeQueryController.GetAllTypes instead as it only requires AuthorizationPolicies.TreeAccessMembersOrMemberTypes and not both this and AuthorizationPolicies.TreeAccessMemberTypes")] [Authorize(Policy = AuthorizationPolicies.TreeAccessMembersOrMemberTypes)] public IEnumerable GetAllTypes() { diff --git a/src/Umbraco.Web.BackOffice/Controllers/MemberTypeQueryController.cs b/src/Umbraco.Web.BackOffice/Controllers/MemberTypeQueryController.cs new file mode 100644 index 0000000000..1d15a6448a --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Controllers/MemberTypeQueryController.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Authorization; +using Umbraco.Cms.Core.Mapping; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.ContentEditing; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Web.Common.Attributes; +using Umbraco.Cms.Web.Common.Authorization; +using Constants = Umbraco.Cms.Core.Constants; + +namespace Umbraco.Cms.Web.BackOffice.Controllers +{ + /// + /// An API controller used for dealing with member types + /// + [PluginController(Constants.Web.Mvc.BackOfficeApiArea)] + [Authorize(Policy = AuthorizationPolicies.TreeAccessMembersOrMemberTypes)] + public class MemberTypeQueryController : BackOfficeNotificationsController + { + private readonly IMemberTypeService _memberTypeService; + private readonly IUmbracoMapper _umbracoMapper; + + + public MemberTypeQueryController( + IMemberTypeService memberTypeService, + IUmbracoMapper umbracoMapper) + { + _memberTypeService = memberTypeService ?? throw new ArgumentNullException(nameof(memberTypeService)); + _umbracoMapper = umbracoMapper ?? throw new ArgumentNullException(nameof(umbracoMapper)); + } + + /// + /// Returns all member types + /// + public IEnumerable GetAllTypes() => + _memberTypeService.GetAll() + .Select(_umbracoMapper.Map); + + } +} diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/membertype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/membertype.resource.js index bf02d9618e..e1d0fbe8ac 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/membertype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/membertype.resource.js @@ -46,10 +46,10 @@ function memberTypeResource($q, $http, umbRequestHelper, umbDataFormatter, local return umbRequestHelper.resourcePromise( $http.get( umbRequestHelper.getApiUrl( - "memberTypeApiBaseUrl", + "memberTypeQueryApiBaseUrl", "GetAllTypes")), 'Failed to retrieve data for member types id'); - }, + }, getById: function (id) { From 1bd827cbba63f7c39b645ec48752fb9477654938 Mon Sep 17 00:00:00 2001 From: Blake Irwin Date: Wed, 29 Sep 2021 23:44:40 +1300 Subject: [PATCH 26/29] Execute CopyUmbracoAssets @ BeforeBuild to prevent Rebuild failures --- build/NuSpecs/build/Umbraco.Cms.StaticAssets.targets | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build/NuSpecs/build/Umbraco.Cms.StaticAssets.targets b/build/NuSpecs/build/Umbraco.Cms.StaticAssets.targets index 0d712e083b..d271653e44 100644 --- a/build/NuSpecs/build/Umbraco.Cms.StaticAssets.targets +++ b/build/NuSpecs/build/Umbraco.Cms.StaticAssets.targets @@ -6,9 +6,8 @@ umbraco - + - From 2a29cdc6c6598acb31fd5394e4157d75f124a82a Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 6 Oct 2021 11:13:59 +0200 Subject: [PATCH 27/29] Allow opt out of import embedded schema file (#11296) * Introduce an opt-out options from the import of embedded schema files. * Moved the initialization of the static service provider into CoreRuntime as this runs before the IStartupFilters, and otherwise the static service provider is not available in hosted services. E.g. for migrations * fix build * Minor code tidy and naming alignment. * Update src/Umbraco.Web.UI/Umbraco.Web.UI.csproj * Removed default installation of starter kit. Co-authored-by: Andy Butland --- src/JsonSchema/AppSettings.cs | 1 + .../Models/PackageMigrationSettings.cs | 40 +++++++++++++++++++ .../Models/UnattendedSettings.cs | 10 +++-- src/Umbraco.Core/Constants-Configuration.cs | 1 + .../StaticServiceProvider.cs | 8 ++-- .../UmbracoBuilder.Configuration.cs | 3 +- .../DependencyInjection/UmbracoBuilder.cs | 1 + .../Packaging/ImportPackageBuilder.cs | 9 +++-- .../ImportPackageBuilderExpression.cs | 17 +++++++- .../Packaging/PackageMigrationBase.cs | 37 +++++++++++++++-- .../Runtime/CoreRuntime.cs | 40 ++++++++++++++++++- .../UmbracoApplicationServicesCapture.cs | 20 ---------- .../UmbracoBuilderExtensions.cs | 4 -- .../Umbraco.Web.Common.csproj | 1 - 14 files changed, 148 insertions(+), 44 deletions(-) create mode 100644 src/Umbraco.Core/Configuration/Models/PackageMigrationSettings.cs rename src/{Umbraco.Web.Common => Umbraco.Core}/DependencyInjection/StaticServiceProvider.cs (64%) delete mode 100644 src/Umbraco.Web.Common/DependencyInjection/UmbracoApplicationServicesCapture.cs diff --git a/src/JsonSchema/AppSettings.cs b/src/JsonSchema/AppSettings.cs index 4045421eb1..1b7c6d46fc 100644 --- a/src/JsonSchema/AppSettings.cs +++ b/src/JsonSchema/AppSettings.cs @@ -47,6 +47,7 @@ namespace JsonSchema public RichTextEditorSettings RichTextEditor { get; set; } public RuntimeMinificationSettings RuntimeMinification { get; set; } public BasicAuthSettings BasicAuth { get; set; } + public PackageMigrationSettings PackageMigration { get; set; } } /// diff --git a/src/Umbraco.Core/Configuration/Models/PackageMigrationSettings.cs b/src/Umbraco.Core/Configuration/Models/PackageMigrationSettings.cs new file mode 100644 index 0000000000..27968fdcd2 --- /dev/null +++ b/src/Umbraco.Core/Configuration/Models/PackageMigrationSettings.cs @@ -0,0 +1,40 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.ComponentModel; + +namespace Umbraco.Cms.Core.Configuration.Models +{ + /// + /// Typed configuration options for package migration settings. + /// + [UmbracoOptions(Constants.Configuration.ConfigPackageMigration)] + public class PackageMigrationSettings + { + private const bool StaticRunSchemaAndContentMigrations = true; + private const bool StaticAllowComponentOverrideOfRunSchemaAndContentMigrations = true; + + /// + /// Gets or sets a value indicating whether package migration steps that install schema and content should run. + /// + /// + /// By default this is true and schema and content defined in a package migration are installed. + /// Using configuration, administrators can optionally switch this off in certain environments. + /// Deployment tools such as Umbraco Deploy can also configure this option to run or not run these migration + /// steps as is appropriate for normal use of the tool. + /// + [DefaultValue(StaticRunSchemaAndContentMigrations)] + public bool RunSchemaAndContentMigrations { get; set; } = StaticRunSchemaAndContentMigrations; + + /// + /// Gets or sets a value indicating whether components can override the configured value for . + /// + /// + /// By default this is true and components can override the configured setting for . + /// If an administrator wants explicit control over which environments migration steps installing schema and content can run, + /// they can set this to false. Components should respect this and not override the configuration. + /// + [DefaultValue(StaticAllowComponentOverrideOfRunSchemaAndContentMigrations)] + public bool AllowComponentOverrideOfRunSchemaAndContentMigrations { get; set; } = StaticAllowComponentOverrideOfRunSchemaAndContentMigrations; + } +} diff --git a/src/Umbraco.Core/Configuration/Models/UnattendedSettings.cs b/src/Umbraco.Core/Configuration/Models/UnattendedSettings.cs index 08020f6e89..7103a9534e 100644 --- a/src/Umbraco.Core/Configuration/Models/UnattendedSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/UnattendedSettings.cs @@ -1,17 +1,19 @@ -using System.ComponentModel; +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.ComponentModel; using System.ComponentModel.DataAnnotations; namespace Umbraco.Cms.Core.Configuration.Models { - /// /// Typed configuration options for unattended settings. /// [UmbracoOptions(Constants.Configuration.ConfigUnattended)] public class UnattendedSettings { - internal const bool StaticInstallUnattended = false; - internal const bool StaticUpgradeUnattended = false; + private const bool StaticInstallUnattended = false; + private const bool StaticUpgradeUnattended = false; /// /// Gets or sets a value indicating whether unattended installs are enabled. diff --git a/src/Umbraco.Core/Constants-Configuration.cs b/src/Umbraco.Core/Constants-Configuration.cs index 0c7657d07e..c36f5813ab 100644 --- a/src/Umbraco.Core/Constants-Configuration.cs +++ b/src/Umbraco.Core/Constants-Configuration.cs @@ -52,6 +52,7 @@ public const string ConfigWebRouting = ConfigPrefix + "WebRouting"; public const string ConfigUserPassword = ConfigPrefix + "Security:UserPassword"; public const string ConfigRichTextEditor = ConfigPrefix + "RichTextEditor"; + public const string ConfigPackageMigration = ConfigPrefix + "PackageMigration"; } } } diff --git a/src/Umbraco.Web.Common/DependencyInjection/StaticServiceProvider.cs b/src/Umbraco.Core/DependencyInjection/StaticServiceProvider.cs similarity index 64% rename from src/Umbraco.Web.Common/DependencyInjection/StaticServiceProvider.cs rename to src/Umbraco.Core/DependencyInjection/StaticServiceProvider.cs index c73685b41d..8d195c56f4 100644 --- a/src/Umbraco.Web.Common/DependencyInjection/StaticServiceProvider.cs +++ b/src/Umbraco.Core/DependencyInjection/StaticServiceProvider.cs @@ -4,22 +4,22 @@ using System.ComponentModel; namespace Umbraco.Cms.Web.Common.DependencyInjection { /// - /// INTERNAL Service locator. Should only be used if no other ways exist. + /// Service locator for internal (umbraco cms) only purposes. Should only be used if no other ways exist. /// /// /// It is created with only two goals in mind /// 1) Continue to have the same extension methods on IPublishedContent and IPublishedElement as in V8. To make migration easier. - /// 2) To have a tool to avoid breaking changes in minor versions. All methods using this should in theory be obsolete. + /// 2) To have a tool to avoid breaking changes in minor and patch versions. All methods using this should in theory be obsolete. /// /// Keep in mind, every time this is used, the code becomes basically untestable. /// [EditorBrowsable(EditorBrowsableState.Never)] - internal static class StaticServiceProvider + public static class StaticServiceProvider { /// /// The service locator. /// [EditorBrowsable(EditorBrowsableState.Never)] - internal static IServiceProvider Instance { get; set; } + public static IServiceProvider Instance { get; set; } } } diff --git a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs index 77902cc5c1..9b31ed7056 100644 --- a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs +++ b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs @@ -72,7 +72,8 @@ namespace Umbraco.Cms.Core.DependencyInjection .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() - .AddUmbracoOptions(); + .AddUmbracoOptions() + .AddUmbracoOptions(); return builder; } diff --git a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs index 6f6a53df66..bf3b3edaf9 100644 --- a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs +++ b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs @@ -38,6 +38,7 @@ using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Sync; using Umbraco.Cms.Core.Templates; using Umbraco.Cms.Core.Web; +using Umbraco.Cms.Web.Common.DependencyInjection; using Umbraco.Extensions; namespace Umbraco.Cms.Core.DependencyInjection diff --git a/src/Umbraco.Infrastructure/Packaging/ImportPackageBuilder.cs b/src/Umbraco.Infrastructure/Packaging/ImportPackageBuilder.cs index c14d3e5119..fef61a54c3 100644 --- a/src/Umbraco.Infrastructure/Packaging/ImportPackageBuilder.cs +++ b/src/Umbraco.Infrastructure/Packaging/ImportPackageBuilder.cs @@ -1,8 +1,9 @@ using System; using System.Xml.Linq; +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.PropertyEditors; -using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Strings; using Umbraco.Cms.Infrastructure.Migrations; @@ -20,7 +21,8 @@ namespace Umbraco.Cms.Infrastructure.Packaging MediaUrlGeneratorCollection mediaUrlGenerators, IShortStringHelper shortStringHelper, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, - IMigrationContext context) + IMigrationContext context, + IOptions options) : base(new ImportPackageBuilderExpression( packagingService, mediaService, @@ -28,7 +30,8 @@ namespace Umbraco.Cms.Infrastructure.Packaging mediaUrlGenerators, shortStringHelper, contentTypeBaseServiceProvider, - context)) + context, + options)) { } diff --git a/src/Umbraco.Infrastructure/Packaging/ImportPackageBuilderExpression.cs b/src/Umbraco.Infrastructure/Packaging/ImportPackageBuilderExpression.cs index 8eda0f0b45..838d59e14e 100644 --- a/src/Umbraco.Infrastructure/Packaging/ImportPackageBuilderExpression.cs +++ b/src/Umbraco.Infrastructure/Packaging/ImportPackageBuilderExpression.cs @@ -5,7 +5,9 @@ using System.Linq; using System.Xml.Linq; using System.Xml.XPath; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Packaging; @@ -25,7 +27,9 @@ namespace Umbraco.Cms.Infrastructure.Packaging private readonly MediaUrlGeneratorCollection _mediaUrlGenerators; private readonly IPackagingService _packagingService; private readonly IShortStringHelper _shortStringHelper; - private bool _executed; + private readonly PackageMigrationSettings _packageMigrationSettings; + + private bool _executed; public ImportPackageBuilderExpression( IPackagingService packagingService, @@ -34,7 +38,8 @@ namespace Umbraco.Cms.Infrastructure.Packaging MediaUrlGeneratorCollection mediaUrlGenerators, IShortStringHelper shortStringHelper, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, - IMigrationContext context) : base(context) + IMigrationContext context, + IOptions packageMigrationSettings) : base(context) { _packagingService = packagingService; _mediaService = mediaService; @@ -42,6 +47,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging _mediaUrlGenerators = mediaUrlGenerators; _shortStringHelper = shortStringHelper; _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; + _packageMigrationSettings = packageMigrationSettings.Value; } /// @@ -59,6 +65,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging } _executed = true; + Context.BuildingExpression = false; if (EmbeddedResourceMigrationType == null && PackageDataManifest == null) @@ -67,6 +74,12 @@ namespace Umbraco.Cms.Infrastructure.Packaging $"Nothing to execute, neither {nameof(EmbeddedResourceMigrationType)} or {nameof(PackageDataManifest)} has been set."); } + if (!_packageMigrationSettings.RunSchemaAndContentMigrations) + { + Logger.LogInformation("Skipping import of embedded schema file, due to configuration"); + return; + } + InstallationSummary installationSummary; if (EmbeddedResourceMigrationType != null) { diff --git a/src/Umbraco.Infrastructure/Packaging/PackageMigrationBase.cs b/src/Umbraco.Infrastructure/Packaging/PackageMigrationBase.cs index 3166cdbd4f..54b96955d4 100644 --- a/src/Umbraco.Infrastructure/Packaging/PackageMigrationBase.cs +++ b/src/Umbraco.Infrastructure/Packaging/PackageMigrationBase.cs @@ -1,12 +1,17 @@ +using System; +using System.ComponentModel; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Strings; using Umbraco.Cms.Infrastructure.Migrations; +using Umbraco.Cms.Web.Common.DependencyInjection; namespace Umbraco.Cms.Infrastructure.Packaging { - public abstract class PackageMigrationBase : MigrationBase { private readonly IPackagingService _packagingService; @@ -15,6 +20,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging private readonly MediaUrlGeneratorCollection _mediaUrlGenerators; private readonly IShortStringHelper _shortStringHelper; private readonly IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider; + private readonly IOptions _packageMigrationsSettings; public PackageMigrationBase( IPackagingService packagingService, @@ -23,7 +29,8 @@ namespace Umbraco.Cms.Infrastructure.Packaging MediaUrlGeneratorCollection mediaUrlGenerators, IShortStringHelper shortStringHelper, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, - IMigrationContext context) + IMigrationContext context, + IOptions packageMigrationsSettings) : base(context) { _packagingService = packagingService; @@ -32,6 +39,29 @@ namespace Umbraco.Cms.Infrastructure.Packaging _mediaUrlGenerators = mediaUrlGenerators; _shortStringHelper = shortStringHelper; _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; + _packageMigrationsSettings = packageMigrationsSettings; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("Use ctor with all params")] + public PackageMigrationBase( + IPackagingService packagingService, + IMediaService mediaService, + MediaFileManager mediaFileManager, + MediaUrlGeneratorCollection mediaUrlGenerators, + IShortStringHelper shortStringHelper, + IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, + IMigrationContext context) + : this( + packagingService, + mediaService, + mediaFileManager, + mediaUrlGenerators, + shortStringHelper, + contentTypeBaseServiceProvider, + context, + StaticServiceProvider.Instance.GetRequiredService>()) + { } public IImportPackageBuilder ImportPackage => BeginBuild( @@ -42,7 +72,8 @@ namespace Umbraco.Cms.Infrastructure.Packaging _mediaUrlGenerators, _shortStringHelper, _contentTypeBaseServiceProvider, - Context)); + Context, + _packageMigrationsSettings)); } } diff --git a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs index 86f4e070c2..4ec87dfde7 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs @@ -1,9 +1,9 @@ using System; +using System.ComponentModel; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Umbraco.Cms.Core; -using Umbraco.Cms.Core.Composing; using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Exceptions; @@ -13,7 +13,9 @@ using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Core.Runtime; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Infrastructure.Persistence; +using Umbraco.Cms.Web.Common.DependencyInjection; using Umbraco.Extensions; +using ComponentCollection = Umbraco.Cms.Core.Composing.ComponentCollection; namespace Umbraco.Cms.Infrastructure.Runtime { @@ -29,6 +31,7 @@ namespace Umbraco.Cms.Infrastructure.Runtime private readonly IEventAggregator _eventAggregator; private readonly IHostingEnvironment _hostingEnvironment; private readonly IUmbracoVersion _umbracoVersion; + private readonly IServiceProvider _serviceProvider; private CancellationToken _cancellationToken; /// @@ -44,7 +47,8 @@ namespace Umbraco.Cms.Infrastructure.Runtime IUmbracoDatabaseFactory databaseFactory, IEventAggregator eventAggregator, IHostingEnvironment hostingEnvironment, - IUmbracoVersion umbracoVersion) + IUmbracoVersion umbracoVersion, + IServiceProvider serviceProvider) { State = state; _loggerFactory = loggerFactory; @@ -56,9 +60,40 @@ namespace Umbraco.Cms.Infrastructure.Runtime _eventAggregator = eventAggregator; _hostingEnvironment = hostingEnvironment; _umbracoVersion = umbracoVersion; + _serviceProvider = serviceProvider; _logger = _loggerFactory.CreateLogger(); } + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete] + public CoreRuntime( + ILoggerFactory loggerFactory, + IRuntimeState state, + ComponentCollection components, + IApplicationShutdownRegistry applicationShutdownRegistry, + IProfilingLogger profilingLogger, + IMainDom mainDom, + IUmbracoDatabaseFactory databaseFactory, + IEventAggregator eventAggregator, + IHostingEnvironment hostingEnvironment, + IUmbracoVersion umbracoVersion + ):this( + loggerFactory, + state, + components, + applicationShutdownRegistry, + profilingLogger, + mainDom, + databaseFactory, + eventAggregator, + hostingEnvironment, + umbracoVersion, + null + ) + { + + } + /// /// Gets the state of the Umbraco runtime. /// @@ -76,6 +111,7 @@ namespace Umbraco.Cms.Infrastructure.Runtime { _cancellationToken = cancellationToken; StaticApplicationLogging.Initialize(_loggerFactory); + StaticServiceProvider.Instance = _serviceProvider; AppDomain.CurrentDomain.UnhandledException += (_, args) => { diff --git a/src/Umbraco.Web.Common/DependencyInjection/UmbracoApplicationServicesCapture.cs b/src/Umbraco.Web.Common/DependencyInjection/UmbracoApplicationServicesCapture.cs deleted file mode 100644 index fa5adf7aeb..0000000000 --- a/src/Umbraco.Web.Common/DependencyInjection/UmbracoApplicationServicesCapture.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; - -namespace Umbraco.Cms.Web.Common.DependencyInjection -{ - /// - /// A registered to automatically capture application services - /// - internal class UmbracoApplicationServicesCapture : IStartupFilter - { - /// - public Action Configure(Action next) => - app => - { - StaticServiceProvider.Instance = app.ApplicationServices; - next(app); - }; - } -} diff --git a/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs index ef98553ba2..2d584f198e 100644 --- a/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs @@ -123,10 +123,6 @@ namespace Umbraco.Extensions config, profiler); - // adds the umbraco startup filter which will call UseUmbraco early on before - // other start filters are applied (depending on the ordering of IStartupFilters in DI). - services.AddTransient(); - return new UmbracoBuilder(services, config, typeLoader, loggerFactory, profiler, appCaches, tempHostingEnvironment); } diff --git a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj index fcd62febf4..537df5aab4 100644 --- a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj +++ b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj @@ -48,5 +48,4 @@ <_Parameter1>Umbraco.Tests.UnitTests - From e786491a0c46047f4c602d44a2af918a2d027b38 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 6 Oct 2021 14:38:50 +0200 Subject: [PATCH 28/29] Added CopyRazorGenerateFilesToPublishDirectory to the template (#11301) --- build/templates/UmbracoProject/UmbracoProject.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/templates/UmbracoProject/UmbracoProject.csproj b/build/templates/UmbracoProject/UmbracoProject.csproj index efc5425728..99e72bae0f 100644 --- a/build/templates/UmbracoProject/UmbracoProject.csproj +++ b/build/templates/UmbracoProject/UmbracoProject.csproj @@ -36,6 +36,10 @@ + + true + + false From bef1ccedca45b16a1a51178c45c2bec3302caf53 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 6 Oct 2021 20:11:06 +0200 Subject: [PATCH 29/29] Exposes the entity containers (folders) created during a package installation in the summary available from the ImportedPackageNotification. (#11303) * Exposes the entity containers (folders) created during a package installation in the summary available from the ImportedPackageNotification. * Restored original constructors. * Refactored to use out parameters for tracking installed entity containers. * Removed unnecessary variable initialization. --- .../Packaging/InstallationSummary.cs | 2 + .../Packaging/PackageDataInstallation.cs | 80 ++++++++++++++++--- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Core/Packaging/InstallationSummary.cs b/src/Umbraco.Core/Packaging/InstallationSummary.cs index 2aa74474d1..42ac9f7ef0 100644 --- a/src/Umbraco.Core/Packaging/InstallationSummary.cs +++ b/src/Umbraco.Core/Packaging/InstallationSummary.cs @@ -32,6 +32,7 @@ namespace Umbraco.Cms.Core.Packaging public IEnumerable PartialViewsInstalled { get; set; } = Enumerable.Empty(); public IEnumerable ContentInstalled { get; set; } = Enumerable.Empty(); public IEnumerable MediaInstalled { get; set; } = Enumerable.Empty(); + public IEnumerable EntityContainersInstalled { get; set; } = Enumerable.Empty(); public override string ToString() { @@ -77,6 +78,7 @@ namespace Umbraco.Cms.Core.Packaging WriteCount("Stylesheets installed: ", StylesheetsInstalled); WriteCount("Scripts installed: ", ScriptsInstalled); WriteCount("Partial views installed: ", PartialViewsInstalled); + WriteCount("Entity containers installed: ", EntityContainersInstalled); WriteCount("Content items installed: ", ContentInstalled); WriteCount("Media items installed: ", MediaInstalled, false); diff --git a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs index c691b74a0c..5c9942f945 100644 --- a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs +++ b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs @@ -91,19 +91,25 @@ namespace Umbraco.Cms.Infrastructure.Packaging var installationSummary = new InstallationSummary(compiledPackage.Name) { Warnings = compiledPackage.Warnings, - DataTypesInstalled = ImportDataTypes(compiledPackage.DataTypes.ToList(), userId), + DataTypesInstalled = ImportDataTypes(compiledPackage.DataTypes.ToList(), userId, out IEnumerable dataTypeEntityContainersInstalled), LanguagesInstalled = ImportLanguages(compiledPackage.Languages, userId), DictionaryItemsInstalled = ImportDictionaryItems(compiledPackage.DictionaryItems, userId), MacrosInstalled = ImportMacros(compiledPackage.Macros, userId), MacroPartialViewsInstalled = ImportMacroPartialViews(compiledPackage.MacroPartialViews, userId), TemplatesInstalled = ImportTemplates(compiledPackage.Templates.ToList(), userId), - DocumentTypesInstalled = ImportDocumentTypes(compiledPackage.DocumentTypes, userId), - MediaTypesInstalled = ImportMediaTypes(compiledPackage.MediaTypes, userId), + DocumentTypesInstalled = ImportDocumentTypes(compiledPackage.DocumentTypes, userId, out IEnumerable documentTypeEntityContainersInstalled), + MediaTypesInstalled = ImportMediaTypes(compiledPackage.MediaTypes, userId, out IEnumerable mediaTypeEntityContainersInstalled), StylesheetsInstalled = ImportStylesheets(compiledPackage.Stylesheets, userId), ScriptsInstalled = ImportScripts(compiledPackage.Scripts, userId), PartialViewsInstalled = ImportPartialViews(compiledPackage.PartialViews, userId) }; + var entityContainersInstalled = new List(); + entityContainersInstalled.AddRange(dataTypeEntityContainersInstalled); + entityContainersInstalled.AddRange(documentTypeEntityContainersInstalled); + entityContainersInstalled.AddRange(mediaTypeEntityContainersInstalled); + installationSummary.EntityContainersInstalled = entityContainersInstalled; + // We need a reference to the imported doc types to continue var importedDocTypes = installationSummary.DocumentTypesInstalled.ToDictionary(x => x.Alias, x => x); var importedMediaTypes = installationSummary.MediaTypesInstalled.ToDictionary(x => x.Alias, x => x); @@ -116,6 +122,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging return installationSummary; } } + /// /// Imports and saves package xml as /// @@ -123,7 +130,17 @@ namespace Umbraco.Cms.Infrastructure.Packaging /// Optional id of the User performing the operation. Default is zero (admin). /// An enumerable list of generated ContentTypes public IReadOnlyList ImportMediaTypes(IEnumerable docTypeElements, int userId) - => ImportDocumentTypes(docTypeElements.ToList(), true, userId, _mediaTypeService); + => ImportMediaTypes(docTypeElements, userId, out _); + + /// + /// Imports and saves package xml as + /// + /// Xml to import + /// Optional id of the User performing the operation. Default is zero (admin). + /// Collection of entity containers installed by the package to be populated with those created in installing data types. + /// An enumerable list of generated ContentTypes + public IReadOnlyList ImportMediaTypes(IEnumerable docTypeElements, int userId, out IEnumerable entityContainersInstalled) + => ImportDocumentTypes(docTypeElements.ToList(), true, userId, _mediaTypeService, out entityContainersInstalled); #endregion @@ -408,7 +425,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging #region DocumentTypes public IReadOnlyList ImportDocumentType(XElement docTypeElement, int userId) - => ImportDocumentTypes(new[] { docTypeElement }, userId); + => ImportDocumentTypes(new[] { docTypeElement }, userId, out _); /// /// Imports and saves package xml as @@ -417,7 +434,17 @@ namespace Umbraco.Cms.Infrastructure.Packaging /// Optional id of the User performing the operation. Default is zero (admin). /// An enumerable list of generated ContentTypes public IReadOnlyList ImportDocumentTypes(IEnumerable docTypeElements, int userId) - => ImportDocumentTypes(docTypeElements.ToList(), true, userId, _contentTypeService); + => ImportDocumentTypes(docTypeElements.ToList(), true, userId, _contentTypeService, out _); + + /// + /// Imports and saves package xml as + /// + /// Xml to import + /// Optional id of the User performing the operation. Default is zero (admin). + /// Collection of entity containers installed by the package to be populated with those created in installing data types. + /// An enumerable list of generated ContentTypes + public IReadOnlyList ImportDocumentTypes(IEnumerable docTypeElements, int userId, out IEnumerable entityContainersInstalled) + => ImportDocumentTypes(docTypeElements.ToList(), true, userId, _contentTypeService, out entityContainersInstalled); /// /// Imports and saves package xml as @@ -428,6 +455,18 @@ namespace Umbraco.Cms.Infrastructure.Packaging /// An enumerable list of generated ContentTypes public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection unsortedDocumentTypes, bool importStructure, int userId, IContentTypeBaseService service) where T : class, IContentTypeComposition + => ImportDocumentTypes(unsortedDocumentTypes, importStructure, userId, service); + + /// + /// Imports and saves package xml as + /// + /// Xml to import + /// Boolean indicating whether or not to import the + /// Optional id of the User performing the operation. Default is zero (admin). + /// Collection of entity containers installed by the package to be populated with those created in installing data types. + /// An enumerable list of generated ContentTypes + public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection unsortedDocumentTypes, bool importStructure, int userId, IContentTypeBaseService service, out IEnumerable entityContainersInstalled) + where T : class, IContentTypeComposition { var importedContentTypes = new Dictionary(); @@ -436,7 +475,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging var graph = new TopoGraph>(x => x.Key, x => x.Dependencies); var isSingleDocTypeImport = unsortedDocumentTypes.Count == 1; - var importedFolders = CreateContentTypeFolderStructure(unsortedDocumentTypes); + var importedFolders = CreateContentTypeFolderStructure(unsortedDocumentTypes, out entityContainersInstalled); if (isSingleDocTypeImport == false) { @@ -532,9 +571,10 @@ namespace Umbraco.Cms.Infrastructure.Packaging return list; } - private Dictionary CreateContentTypeFolderStructure(IEnumerable unsortedDocumentTypes) + private Dictionary CreateContentTypeFolderStructure(IEnumerable unsortedDocumentTypes, out IEnumerable entityContainersInstalled) { var importedFolders = new Dictionary(); + var trackEntityContainersInstalled = new List(); foreach (var documentType in unsortedDocumentTypes) { var foldersAttribute = documentType.Attribute("Folders"); @@ -578,8 +618,10 @@ namespace Umbraco.Cms.Infrastructure.Packaging _logger.LogError(tryCreateFolder.Exception, "Could not create folder: {FolderName}", rootFolder); throw tryCreateFolder.Exception; } + var rootFolderId = tryCreateFolder.Result.Entity.Id; current = _contentTypeService.GetContainer(rootFolderId); + trackEntityContainersInstalled.Add(current); } importedFolders.Add(alias, current.Id); @@ -589,11 +631,13 @@ namespace Umbraco.Cms.Infrastructure.Packaging var folderName = WebUtility.UrlDecode(folders[i]); Guid? folderKey = (folderKeys.Length == folders.Length) ? folderKeys[i] : null; current = CreateContentTypeChildFolder(folderName, folderKey ?? Guid.NewGuid(), current); + trackEntityContainersInstalled.Add(current); importedFolders[alias] = current.Id; } } } + entityContainersInstalled = trackEntityContainersInstalled; return importedFolders; } @@ -1012,10 +1056,20 @@ namespace Umbraco.Cms.Infrastructure.Packaging /// Optional id of the user /// An enumerable list of generated DataTypeDefinitions public IReadOnlyList ImportDataTypes(IReadOnlyCollection dataTypeElements, int userId) + => ImportDataTypes(dataTypeElements, userId, out _); + + /// + /// Imports and saves package xml as + /// + /// Xml to import + /// Optional id of the user + /// Collection of entity containers installed by the package to be populated with those created in installing data types. + /// An enumerable list of generated DataTypeDefinitions + public IReadOnlyList ImportDataTypes(IReadOnlyCollection dataTypeElements, int userId, out IEnumerable entityContainersInstalled) { var dataTypes = new List(); - var importedFolders = CreateDataTypeFolderStructure(dataTypeElements); + var importedFolders = CreateDataTypeFolderStructure(dataTypeElements, out entityContainersInstalled); foreach (var dataTypeElement in dataTypeElements) { @@ -1072,9 +1126,10 @@ namespace Umbraco.Cms.Infrastructure.Packaging return dataTypes; } - private Dictionary CreateDataTypeFolderStructure(IEnumerable datatypeElements) + private Dictionary CreateDataTypeFolderStructure(IEnumerable datatypeElements, out IEnumerable entityContainersInstalled) { var importedFolders = new Dictionary(); + var trackEntityContainersInstalled = new List(); foreach (var datatypeElement in datatypeElements) { var foldersAttribute = datatypeElement.Attribute("Folders"); @@ -1103,7 +1158,9 @@ namespace Umbraco.Cms.Infrastructure.Packaging _logger.LogError(tryCreateFolder.Exception, "Could not create folder: {FolderName}", rootFolder); throw tryCreateFolder.Exception; } + current = _dataTypeService.GetContainer(tryCreateFolder.Result.Entity.Id); + trackEntityContainersInstalled.Add(current); } importedFolders.Add(name, current.Id); @@ -1113,11 +1170,12 @@ namespace Umbraco.Cms.Infrastructure.Packaging var folderName = WebUtility.UrlDecode(folders[i]); Guid? folderKey = (folderKeys.Length == folders.Length) ? folderKeys[i] : null; current = CreateDataTypeChildFolder(folderName, folderKey ?? Guid.NewGuid(), current); + trackEntityContainersInstalled.Add(current); importedFolders[name] = current.Id; } } } - + entityContainersInstalled = trackEntityContainersInstalled; return importedFolders; }