Skip to content

Commit d512ec6

Browse files
author
Nicklas Kramer
committed
Merge branch 'refs/heads/main' into v16/feature/load-balancing-isolated-caches
# Conflicts: # src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs # src/Umbraco.Core/Persistence/Constants-DatabaseSchema.cs # src/Umbraco.Core/Persistence/Constants-Locks.cs # src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Repositories.cs # src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs # src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepository.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MediaTypeRepository.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberTypeRepository.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/UserRepository.cs # tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DocumentRepositoryTest.cs # tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MediaRepositoryTest.cs # tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MediaTypeRepositoryTest.cs # tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MemberTypeRepositoryTest.cs # tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/TemplateRepositoryTest.cs # tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/UserRepositoryTest.cs
2 parents b52461d + 44aa5dc commit d512ec6

File tree

873 files changed

+10077
-5539
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

873 files changed

+10077
-5539
lines changed

build/azure-pipelines.yml

Lines changed: 174 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -513,9 +513,9 @@ stages:
513513
UMBRACO__CMS__WEBROUTING__UMBRACOAPPLICATIONURL: https://localhost:44331/
514514
ASPNETCORE_URLS: https://localhost:44331
515515
jobs:
516-
# E2E Tests
516+
# E2E Smoke Tests
517517
- job:
518-
displayName: E2E Tests (SQLite)
518+
displayName: E2E Smoke Tests (SQLite)
519519
# currently disabled due to DB locks randomly occuring.
520520
condition: eq(${{parameters.sqliteAcceptanceTests}}, True)
521521
variables:
@@ -678,7 +678,7 @@ stages:
678678
testRunTitle: "$(Agent.JobName)"
679679

680680
- job:
681-
displayName: E2E Tests (SQL Server)
681+
displayName: E2E Smoke Tests (SQL Server)
682682
variables:
683683
# Connection string
684684
CONNECTIONSTRINGS__UMBRACODBDSN: Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Umbraco.mdf;Integrated Security=True
@@ -862,6 +862,176 @@ stages:
862862
searchFolder: "tests/Umbraco.Tests.AcceptanceTest/results"
863863
testRunTitle: "$(Agent.JobName)"
864864

865+
- job:
866+
displayName: E2E Release Tests (SQL Server)
867+
variables:
868+
# Connection string
869+
CONNECTIONSTRINGS__UMBRACODBDSN: Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Umbraco.mdf;Integrated Security=True
870+
CONNECTIONSTRINGS__UMBRACODBDSN_PROVIDERNAME: Microsoft.Data.SqlClient
871+
condition: eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True')
872+
strategy:
873+
matrix:
874+
WindowsPart1Of3:
875+
vmImage: "windows-latest"
876+
testCommand: "npm run releaseTest -- --shard=1/3"
877+
WindowsPart2Of3:
878+
vmImage: "windows-latest"
879+
testCommand: "npm run releaseTest -- --shard=2/3"
880+
WindowsPart3Of3:
881+
vmImage: "windows-latest"
882+
testCommand: "npm run releaseTest -- --shard=3/3"
883+
pool:
884+
vmImage: $(vmImage)
885+
steps:
886+
# Setup test environment
887+
- task: DownloadPipelineArtifact@2
888+
displayName: Download NuGet artifacts
889+
inputs:
890+
artifact: nupkg
891+
path: $(Agent.BuildDirectory)/app/nupkg
892+
893+
- task: NodeTool@0
894+
displayName: Use Node.js $(nodeVersion)
895+
inputs:
896+
versionSpec: $(nodeVersion)
897+
898+
- task: UseDotNet@2
899+
displayName: Use .NET SDK from global.json
900+
inputs:
901+
useGlobalJson: true
902+
903+
- pwsh: |
904+
"UMBRACO_USER_LOGIN=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL)
905+
UMBRACO_USER_PASSWORD=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
906+
URL=$(ASPNETCORE_URLS)
907+
STORAGE_STAGE_PATH=$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/playwright/.auth/user.json
908+
CONSOLE_ERRORS_PATH=$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/console-errors.json" | Out-File .env
909+
displayName: Generate .env
910+
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
911+
912+
# Cache and restore NPM packages
913+
- task: Cache@2
914+
displayName: Cache NPM packages
915+
inputs:
916+
key: 'npm_e2e | "$(Agent.OS)" | $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/package-lock.json'
917+
restoreKeys: |
918+
npm_e2e | "$(Agent.OS)"
919+
npm_e2e
920+
path: $(npm_config_cache)
921+
922+
- script: npm ci --no-fund --no-audit --prefer-offline
923+
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
924+
displayName: Restore NPM packages
925+
926+
# Build application
927+
- pwsh: |
928+
$cmsVersion = "$(Build.BuildNumber)" -replace "\+",".g"
929+
dotnet new nugetconfig
930+
dotnet nuget add source ./nupkg --name Local
931+
dotnet new install Umbraco.Templates::$cmsVersion
932+
dotnet new umbraco --name UmbracoProject --version $cmsVersion --exclude-gitignore --no-restore --no-update-check
933+
dotnet restore UmbracoProject
934+
cp $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/*.cs UmbracoProject
935+
dotnet build UmbracoProject --configuration $(buildConfiguration) --no-restore
936+
dotnet dev-certs https
937+
displayName: Build application
938+
workingDirectory: $(Agent.BuildDirectory)/app
939+
940+
# Start SQL Server
941+
- powershell: docker run --name mssql -d -p 1433:1433 -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=$(SA_PASSWORD)" mcr.microsoft.com/mssql/server:2022-latest
942+
displayName: Start SQL Server Docker image (Linux)
943+
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
944+
945+
- pwsh: SqlLocalDB start MSSQLLocalDB
946+
displayName: Start SQL Server LocalDB (Windows)
947+
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
948+
949+
# Run application
950+
- bash: |
951+
nohup dotnet run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile > $(Build.ArtifactStagingDirectory)/playwright.log 2>&1 &
952+
echo "##vso[task.setvariable variable=AcceptanceTestProcessId]$!"
953+
displayName: Run application (Linux)
954+
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
955+
workingDirectory: $(Agent.BuildDirectory)/app
956+
957+
- pwsh: |
958+
$process = Start-Process dotnet "run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile 2>&1" -PassThru -NoNewWindow -RedirectStandardOutput $(Build.ArtifactStagingDirectory)/playwright.log
959+
Write-Host "##vso[task.setvariable variable=AcceptanceTestProcessId]$($process.Id)"
960+
displayName: Run application (Windows)
961+
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
962+
workingDirectory: $(Agent.BuildDirectory)/app
963+
964+
# Wait for application to start responding to requests
965+
- pwsh: npx wait-on -v --interval 1000 --timeout 120000 $(ASPNETCORE_URLS)
966+
displayName: Wait for application
967+
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
968+
969+
# Install Playwright and dependencies
970+
- pwsh: npx playwright install chromium
971+
displayName: Install Playwright only with Chromium browser
972+
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
973+
974+
# Test
975+
- pwsh: $(testCommand)
976+
displayName: Run Playwright tests
977+
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
978+
env:
979+
CI: true
980+
CommitId: $(Build.SourceVersion)
981+
AgentOs: $(Agent.OS)
982+
983+
# Stop application
984+
- bash: kill -15 $(AcceptanceTestProcessId)
985+
displayName: Stop application (Linux)
986+
condition: and(ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Linux'))
987+
988+
- pwsh: Stop-Process -Id $(AcceptanceTestProcessId)
989+
displayName: Stop application (Windows)
990+
condition: and(ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Windows_NT'))
991+
992+
# Stop SQL Server
993+
- pwsh: docker stop mssql
994+
displayName: Stop SQL Server Docker image (Linux)
995+
condition: eq(variables['Agent.OS'], 'Linux')
996+
997+
- pwsh: SqlLocalDB stop MSSQLLocalDB
998+
displayName: Stop SQL Server LocalDB (Windows)
999+
condition: eq(variables['Agent.OS'], 'Windows_NT')
1000+
1001+
# Copy artifacts
1002+
- pwsh: |
1003+
if (Test-Path tests/Umbraco.Tests.AcceptanceTest/results/*) {
1004+
Copy-Item tests/Umbraco.Tests.AcceptanceTest/results/* $(Build.ArtifactStagingDirectory) -Recurse
1005+
}
1006+
displayName: Copy Playwright results
1007+
condition: succeededOrFailed()
1008+
1009+
# Copy console error log
1010+
- pwsh: |
1011+
if (Test-Path tests/Umbraco.Tests.AcceptanceTest/console-errors.json) {
1012+
Copy-Item tests/Umbraco.Tests.AcceptanceTest/console-errors.json $(Build.ArtifactStagingDirectory)
1013+
}
1014+
displayName: Copy console error log
1015+
condition: succeededOrFailed()
1016+
1017+
# Publish test artifacts
1018+
- task: PublishPipelineArtifact@1
1019+
displayName: Publish test artifacts
1020+
condition: succeededOrFailed()
1021+
inputs:
1022+
targetPath: $(Build.ArtifactStagingDirectory)
1023+
artifact: "Acceptance Test Results - $(Agent.JobName) - Attempt #$(System.JobAttempt)"
1024+
1025+
# Publish test results
1026+
- task: PublishTestResults@2
1027+
displayName: "Publish test results"
1028+
condition: succeededOrFailed()
1029+
inputs:
1030+
testResultsFormat: 'JUnit'
1031+
testResultsFiles: '*.xml'
1032+
searchFolder: "tests/Umbraco.Tests.AcceptanceTest/results"
1033+
testRunTitle: "$(Agent.JobName)"
1034+
8651035
###############################################
8661036
## Release
8671037
###############################################
@@ -1067,4 +1237,4 @@ stages:
10671237
storage: umbracoapidocs
10681238
ContainerName: "$web"
10691239
BlobPrefix: v$(umbracoMajorVersion)/ui-api
1070-
CleanTargetBeforeCopy: true
1240+
CleanTargetBeforeCopy: true

build/nightly-E2E-test-pipelines.yml

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ schedules:
99
branches:
1010
include:
1111
- v15/dev
12-
- release/16.0
1312
- main
1413

1514
parameters:
16-
# Skipped due to DB locks
15+
# Skipped due to DB locks
1716
- name: sqliteAcceptanceTests
1817
displayName: Run SQLite Acceptance Tests
1918
type: boolean
@@ -484,3 +483,51 @@ stages:
484483
testResultsFiles: '*.xml'
485484
searchFolder: "tests/Umbraco.Tests.AcceptanceTest/results"
486485
testRunTitle: "$(Agent.JobName)"
486+
487+
- stage: NotifySlackBot
488+
displayName: Notify Slack on Failure
489+
dependsOn: E2E
490+
# This stage will only run if the E2E tests fail or succeed with issues
491+
condition: or(
492+
eq(dependencies.E2E.result, 'failed'),
493+
eq(dependencies.E2E.result, 'succeededWithIssues'))
494+
jobs:
495+
- job: PostToSlack
496+
displayName: Send Slack Notification
497+
pool:
498+
vmImage: 'ubuntu-latest'
499+
steps:
500+
# We send a payload to the Slack webhook URL, which will post a message to a specific channel
501+
- bash: |
502+
PROJECT_NAME_ENCODED=$(echo -n "$SYSTEM_TEAMPROJECT" | jq -s -R -r @uri)
503+
PIPELINE_URL="${SYSTEM_TEAMFOUNDATIONCOLLECTIONURI}${PROJECT_NAME_ENCODED}/_build/results?buildId=${BUILD_BUILDID}&view=ms.vss-test-web.build-test-results-tab"
504+
505+
PAYLOAD="{
506+
\"attachments\": [
507+
{
508+
\"color\": \"#ff0000\",
509+
\"pretext\": \"Nightly E2E pipeline *${BUILD_DEFINITIONNAME}* (#${BUILD_BUILDNUMBER}) failed!\",
510+
\"title\": \"View Failed E2E Test Results\",
511+
\"title_link\": \"$PIPELINE_URL\",
512+
\"fields\": [
513+
{
514+
\"title\": \"Pipeline\",
515+
\"value\": \"${BUILD_DEFINITIONNAME}\",
516+
\"short\": true
517+
},
518+
{
519+
\"title\": \"Build ID\",
520+
\"value\": \"${BUILD_BUILDID}\",
521+
\"short\": true
522+
}
523+
]
524+
}
525+
]
526+
}"
527+
528+
echo "Sending Slack message to: $PIPELINE_URL"
529+
curl -X POST -H 'Content-type: application/json' \
530+
--data "$PAYLOAD" \
531+
"$SLACK_WEBHOOK_URL"
532+
env:
533+
SLACK_WEBHOOK_URL: $(E2ESLACKWEBHOOKURL)

src/Umbraco.Cms.Api.Common/Configuration/ConfigureOpenIddict.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace Umbraco.Cms.Api.Common.Configuration;
66

7-
internal class ConfigureOpenIddict : IConfigureOptions<OpenIddictServerAspNetCoreOptions>
7+
internal sealed class ConfigureOpenIddict : IConfigureOptions<OpenIddictServerAspNetCoreOptions>
88
{
99
private readonly IOptions<GlobalSettings> _globalSettings;
1010

src/Umbraco.Cms.Api.Common/DependencyInjection/ProcessRequestContextHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public ProcessRequestContextHandler(IHttpContextAccessor httpContextAccessor)
1818
var backOfficePathSegment = Constants.System.DefaultUmbracoPath.TrimStart(Constants.CharArrays.Tilde)
1919
.EnsureStartsWith('/')
2020
.EnsureEndsWith('/');
21-
_pathsToHandle = [backOfficePathSegment, "/.well-known/openid-configuration"];
21+
_pathsToHandle = [backOfficePathSegment, "/.well-known/openid-configuration", "/.well-known/jwks"];
2222
}
2323

2424
public ValueTask HandleAsync(OpenIddictServerEvents.ProcessRequestContext context)

src/Umbraco.Cms.Api.Common/Json/NamedSystemTextJsonInputFormatter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace Umbraco.Cms.Api.Common.Json;
66

7-
internal class NamedSystemTextJsonInputFormatter : SystemTextJsonInputFormatter
7+
internal sealed class NamedSystemTextJsonInputFormatter : SystemTextJsonInputFormatter
88
{
99
private readonly string _jsonOptionsName;
1010

src/Umbraco.Cms.Api.Common/Json/NamedSystemTextJsonOutputFormatter.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33

44
namespace Umbraco.Cms.Api.Common.Json;
55

6-
7-
internal class NamedSystemTextJsonOutputFormatter : SystemTextJsonOutputFormatter
6+
internal sealed class NamedSystemTextJsonOutputFormatter : SystemTextJsonOutputFormatter
87
{
98
private readonly string _jsonOptionsName;
109

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.ComponentModel.DataAnnotations;
2+
3+
namespace Umbraco.Cms.Api.Common.ViewModels.Pagination;
4+
5+
public class SubsetViewModel<T>
6+
{
7+
[Required]
8+
public long TotalBefore { get; set; }
9+
10+
[Required]
11+
public long TotalAfter { get; set; }
12+
13+
[Required]
14+
public IEnumerable<T> Items { get; set; } = Enumerable.Empty<T>();
15+
16+
public static SubsetViewModel<T> Empty() => new();
17+
}

src/Umbraco.Cms.Api.Delivery/Caching/DeliveryApiOutputCachePolicy.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ ValueTask IOutputCachePolicy.CacheRequestAsync(OutputCacheContext context, Cance
2323
.RequestServices
2424
.GetRequiredService<IRequestPreviewService>();
2525

26-
context.EnableOutputCaching = requestPreviewService.IsPreview() is false;
26+
IApiAccessService apiAccessService = context
27+
.HttpContext
28+
.RequestServices
29+
.GetRequiredService<IApiAccessService>();
30+
31+
context.EnableOutputCaching = requestPreviewService.IsPreview() is false && apiAccessService.HasPublicAccess();
2732
context.ResponseExpirationTimeSpan = _duration;
2833
context.CacheVaryByRules.HeaderNames = _varyByHeaderNames;
2934

src/Umbraco.Cms.Api.Delivery/Configuration/ConfigureUmbracoMemberAuthenticationDeliveryApiSwaggerGenOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public void Configure(SwaggerGenOptions options)
2626
options.OperationFilter<DeliveryApiSecurityFilter>();
2727
}
2828

29-
private class DeliveryApiSecurityFilter : SwaggerFilterBase<ContentApiControllerBase>, IOperationFilter, IDocumentFilter
29+
private sealed class DeliveryApiSecurityFilter : SwaggerFilterBase<ContentApiControllerBase>, IOperationFilter, IDocumentFilter
3030
{
3131
public void Apply(OpenApiOperation operation, OperationFilterContext context)
3232
{

src/Umbraco.Cms.Api.Delivery/Filters/ContextualizeFromAcceptHeadersAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public ContextualizeFromAcceptHeadersAttribute()
1313
{
1414
}
1515

16-
private class LocalizeFromAcceptLanguageHeaderAttributeFilter : IActionFilter
16+
private sealed class LocalizeFromAcceptLanguageHeaderAttributeFilter : IActionFilter
1717
{
1818
private readonly IRequestCultureService _requestCultureService;
1919
private readonly IRequestSegmmentService _requestSegmentService;

0 commit comments

Comments
 (0)