Skip to content

Commit 24e872f

Browse files
committed
Merge remote-tracking branch 'origin/release/15.1' into v15/dev
2 parents 9ff67a3 + 34cad5f commit 24e872f

File tree

948 files changed

+3265
-1232
lines changed

Some content is hidden

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

948 files changed

+3265
-1232
lines changed

build/azure-pipelines.yml

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ stages:
8181
submodules: false
8282
lfs: false,
8383
fetchDepth: 500
84+
- template: templates/backoffice-install.yml
8485
- task: UseDotNet@2
8586
displayName: Use .NET SDK from global.json
8687
inputs:
@@ -299,29 +300,29 @@ stages:
299300
# vmImage: 'windows-latest'
300301
# We split the tests into 3 parts for each OS to reduce the time it takes to run them on the pipeline
301302
LinuxPart1Of3:
302-
vmImage: "ubuntu-24.04"
303+
vmImage: "ubuntu-latest"
303304
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
304-
testFilter: '(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)'
305+
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)"
305306
LinuxPart2Of3:
306-
vmImage: "ubuntu-24.04"
307+
vmImage: "ubuntu-latest"
307308
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
308-
testFilter: '(FullyQualifiedName~Umbraco.Infrastructure.Service)'
309+
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
309310
LinuxPart3Of3:
310-
vmImage: "ubuntu-24.04"
311+
vmImage: "ubuntu-latest"
311312
# Filter tests that are not part of the Umbraco.Infrastructure namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
312-
testFilter: '(FullyQualifiedName!~Umbraco.Infrastructure)'
313+
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure)"
313314
macOSPart1Of3:
314315
vmImage: "macOS-latest"
315316
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
316-
testFilter: '(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)'
317+
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)"
317318
macOSPart2Of3:
318319
vmImage: "macOS-latest"
319320
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
320-
testFilter: '(FullyQualifiedName~Umbraco.Infrastructure.Service)'
321+
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
321322
macOSPart3Of3:
322323
vmImage: "macOS-latest"
323324
# Filter tests that are not part of the Umbraco.Infrastructure namespace.
324-
testFilter: '(FullyQualifiedName!~Umbraco.Infrastructure)'
325+
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure)"
325326
pool:
326327
vmImage: $(vmImage)
327328
variables:
@@ -373,40 +374,40 @@ stages:
373374
Tests__Database__DatabaseType: LocalDb
374375
Tests__Database__SQLServerMasterConnectionString: N/A
375376
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
376-
testFilter: '(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)'
377+
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)"
377378
WindowsPart2Of3:
378379
vmImage: "windows-latest"
379380
Tests__Database__DatabaseType: LocalDb
380381
Tests__Database__SQLServerMasterConnectionString: N/A
381382
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
382-
testFilter: '(FullyQualifiedName~Umbraco.Infrastructure.Service)'
383+
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
383384
WindowsPart3Of3:
384385
vmImage: "windows-latest"
385386
Tests__Database__DatabaseType: LocalDb
386387
Tests__Database__SQLServerMasterConnectionString: N/A
387388
# Filter tests that are not part of the Umbraco.Infrastructure namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
388-
testFilter: '(FullyQualifiedName!~Umbraco.Infrastructure)'
389+
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure)"
389390
LinuxPart1Of3:
390391
vmImage: "ubuntu-latest"
391392
SA_PASSWORD: UmbracoIntegration123!
392393
Tests__Database__DatabaseType: SqlServer
393394
Tests__Database__SQLServerMasterConnectionString: "Server=(local);User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
394395
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
395-
testFilter: '(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)'
396+
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)"
396397
LinuxPart2Of3:
397398
vmImage: "ubuntu-latest"
398399
SA_PASSWORD: UmbracoIntegration123!
399400
Tests__Database__DatabaseType: SqlServer
400401
Tests__Database__SQLServerMasterConnectionString: "Server=(local);User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
401402
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
402-
testFilter: '(FullyQualifiedName~Umbraco.Infrastructure.Service)'
403+
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
403404
LinuxPart3Of3:
404405
vmImage: "ubuntu-latest"
405406
SA_PASSWORD: UmbracoIntegration123!
406407
Tests__Database__DatabaseType: SqlServer
407408
Tests__Database__SQLServerMasterConnectionString: "Server=(local);User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
408409
# Filter tests that are not part of the Umbraco.Infrastructure namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
409-
testFilter: '(FullyQualifiedName!~Umbraco.Infrastructure)'
410+
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure)"
410411
pool:
411412
vmImage: $(vmImage)
412413
steps:
@@ -492,22 +493,22 @@ stages:
492493
matrix:
493494
LinuxPart1Of3:
494495
vmImage: "ubuntu-latest"
495-
testCommand: "npx playwright test DefaultConfig --grep \"@smoke\"--shard=1/3"
496+
testCommand: 'npx playwright test DefaultConfig --grep "@smoke"--shard=1/3'
496497
LinuxPart2Of3:
497498
vmImage: "ubuntu-latest"
498-
testCommand: "npx playwright test DefaultConfig --grep \"@smoke\" --shard=2/3"
499+
testCommand: 'npx playwright test DefaultConfig --grep "@smoke" --shard=2/3'
499500
LinuxPart3Of3:
500501
vmImage: "ubuntu-latest"
501-
testCommand: "npx playwright test DefaultConfig --grep \"@smoke\" --shard=3/3"
502+
testCommand: 'npx playwright test DefaultConfig --grep "@smoke" --shard=3/3'
502503
WindowsPart1Of3:
503504
vmImage: "windows-latest"
504-
testCommand: "npx playwright test DefaultConfig --grep \"@smoke\" --shard=1/3"
505+
testCommand: 'npx playwright test DefaultConfig --grep "@smoke" --shard=1/3'
505506
WindowsPart2Of3:
506507
vmImage: "windows-latest"
507-
testCommand: "npx playwright test DefaultConfig --grep \"@smoke\" --shard=2/3"
508+
testCommand: 'npx playwright test DefaultConfig --grep "@smoke" --shard=2/3'
508509
WindowsPart3Of3:
509510
vmImage: "windows-latest"
510-
testCommand: "npx playwright test DefaultConfig --grep \"@smoke\" --shard=3/3"
511+
testCommand: 'npx playwright test DefaultConfig --grep "@smoke" --shard=3/3'
511512
pool:
512513
vmImage: $(vmImage)
513514
steps:
@@ -635,29 +636,29 @@ stages:
635636
matrix:
636637
${{ if eq(parameters.sqlServerLinuxAcceptanceTests, True) }}:
637638
LinuxPart1Of3:
638-
testCommand: "npx playwright test DefaultConfig --grep \"@smoke\" --grep-invert \"Users\" --shard=1/3"
639+
testCommand: 'npx playwright test DefaultConfig --grep "@smoke" --grep-invert "Users" --shard=1/3'
639640
vmImage: "ubuntu-latest"
640641
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
641642
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
642643
LinuxPart2Of3:
643-
testCommand: "npx playwright test DefaultConfig --grep \"@smoke\" --grep-invert \"Users\" --shard=2/3"
644+
testCommand: 'npx playwright test DefaultConfig --grep "@smoke" --grep-invert "Users" --shard=2/3'
644645
vmImage: "ubuntu-latest"
645646
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
646647
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
647648
LinuxPart3Of3:
648-
testCommand: "npx playwright test DefaultConfig --grep \"@smoke\" --grep-invert \"Users\" --shard=3/3"
649+
testCommand: 'npx playwright test DefaultConfig --grep "@smoke" --grep-invert "Users" --shard=3/3'
649650
vmImage: "ubuntu-latest"
650651
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
651652
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
652653
WindowsPart1Of3:
653654
vmImage: "windows-latest"
654-
testCommand: "npx playwright test DefaultConfig --grep \"@smoke\" --grep-invert \"Users\" --shard=1/3"
655+
testCommand: 'npx playwright test DefaultConfig --grep "@smoke" --grep-invert "Users" --shard=1/3'
655656
WindowsPart2Of3:
656657
vmImage: "windows-latest"
657-
testCommand: "npx playwright test DefaultConfig --grep \"@smoke\" --grep-invert \"Users\" --shard=2/3"
658+
testCommand: 'npx playwright test DefaultConfig --grep "@smoke" --grep-invert "Users" --shard=2/3'
658659
WindowsPart3Of3:
659660
vmImage: "windows-latest"
660-
testCommand: "npx playwright test DefaultConfig --grep \"@smoke\" --grep-invert \"Users\" --shard=3/3"
661+
testCommand: 'npx playwright test DefaultConfig --grep "@smoke" --grep-invert "Users" --shard=3/3'
661662
pool:
662663
vmImage: $(vmImage)
663664
steps:

src/Umbraco.PublishedCache.HybridCache/NotificationHandlers/CacheRefreshingNotificationHandler.cs

Lines changed: 11 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public CacheRefreshingNotificationHandler(
4545

4646
public async Task HandleAsync(ContentRefreshNotification notification, CancellationToken cancellationToken)
4747
{
48-
await RefreshElementsCacheAsync(notification.Entity);
48+
ClearElementsCache();
4949

5050
await _documentCacheService.RefreshContentAsync(notification.Entity);
5151
}
@@ -54,73 +54,36 @@ public async Task HandleAsync(ContentDeletedNotification notification, Cancellat
5454
{
5555
foreach (IContent deletedEntity in notification.DeletedEntities)
5656
{
57-
RemoveFromElementsCache(deletedEntity);
57+
ClearElementsCache();
5858
await _documentCacheService.DeleteItemAsync(deletedEntity);
5959
}
6060
}
6161

6262
public async Task HandleAsync(MediaRefreshNotification notification, CancellationToken cancellationToken)
6363
{
64-
await RefreshElementsCacheAsync(notification.Entity);
64+
ClearElementsCache();
6565
await _mediaCacheService.RefreshMediaAsync(notification.Entity);
6666
}
6767

6868
public async Task HandleAsync(MediaDeletedNotification notification, CancellationToken cancellationToken)
6969
{
7070
foreach (IMedia deletedEntity in notification.DeletedEntities)
7171
{
72-
RemoveFromElementsCache(deletedEntity);
72+
ClearElementsCache();
7373
await _mediaCacheService.DeleteItemAsync(deletedEntity);
7474
}
7575
}
7676

77-
private async Task RefreshElementsCacheAsync(IUmbracoEntity content)
77+
private void ClearElementsCache()
7878
{
79-
IEnumerable<IRelation> parentRelations = _relationService.GetByParent(content)!;
80-
IEnumerable<IRelation> childRelations = _relationService.GetByChild(content);
81-
82-
var ids = parentRelations.Select(x => x.ChildId).Concat(childRelations.Select(x => x.ParentId)).ToHashSet();
83-
// We need to add ourselves to the list of ids to clear
84-
ids.Add(content.Id);
85-
foreach (var id in ids)
86-
{
87-
if (await _documentCacheService.HasContentByIdAsync(id) is false)
88-
{
89-
continue;
90-
}
91-
92-
IPublishedContent? publishedContent = await _documentCacheService.GetByIdAsync(id);
93-
if (publishedContent is null)
94-
{
95-
continue;
96-
}
97-
98-
foreach (IPublishedProperty publishedProperty in publishedContent.Properties)
99-
{
100-
var property = (PublishedProperty) publishedProperty;
101-
if (property.ReferenceCacheLevel is PropertyCacheLevel.Elements
102-
|| property.PropertyType.DeliveryApiCacheLevel is PropertyCacheLevel.Elements
103-
|| property.PropertyType.DeliveryApiCacheLevelForExpansion is PropertyCacheLevel.Elements)
104-
{
105-
_elementsCache.ClearByKey(property.ValuesCacheKey);
106-
}
107-
}
108-
}
79+
// Ideally we'd like to not have to clear the entire cache here. However, this was the existing behavior in NuCache.
80+
// The reason for this is that we have no way to know which elements are affected by the changes. or what their keys are.
81+
// This is because currently published elements lives exclusively in a JSON blob in the umbracoPropertyData table.
82+
// This means that the only way to resolve these keys are to actually parse this data with a specific value converter, and for all cultures, which is not feasible.
83+
// If published elements become their own entities with relations, instead of just property data, we can revisit this,
84+
_elementsCache.Clear();
10985
}
11086

111-
private void RemoveFromElementsCache(IUmbracoEntity content)
112-
{
113-
// ClearByKey clears by "startsWith" so we'll clear by the cachekey prefix + contentKey
114-
// This will clear any and all properties for this content item, this is important because
115-
// we cannot resolve the PublishedContent for this entity since it and its content type is deleted.
116-
_elementsCache.ClearByKey(GetContentWideCacheKey(content.Key, true));
117-
_elementsCache.ClearByKey(GetContentWideCacheKey(content.Key, false));
118-
}
119-
120-
private string GetContentWideCacheKey(Guid contentKey, bool isPreviewing) => isPreviewing
121-
? CacheKeys.PreviewPropertyCacheKeyPrefix + contentKey
122-
: CacheKeys.PropertyCacheKeyPrefix + contentKey;
123-
12487
public Task HandleAsync(ContentTypeRefreshedNotification notification, CancellationToken cancellationToken)
12588
{
12689
const ContentTypeChangeTypes types // only for those that have been refreshed

0 commit comments

Comments
 (0)