Skip to content

Commit 69ea4e6

Browse files
Merge pull request #22 from umbraco/hotfix/17.0.1
Hotfix v17.0.1: Add fallback entity lookup by alias/code in deploy connectors
2 parents b32e661 + 2941068 commit 69ea4e6

18 files changed

+153
-95
lines changed

src/Umbraco.Commerce.Deploy/Connectors/ServiceConnectors/UmbracoCommerceCountryServiceConnector.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Threading;
@@ -47,6 +47,9 @@ public override IAsyncEnumerable<CountryReadOnly> GetEntitiesAsync(
4747
CancellationToken cancellationToken = default)
4848
=> _umbracoCommerceApi.GetCountriesAsync(storeId).AsAsyncEnumerable();
4949

50+
public override Task<CountryReadOnly?> GetExistingEntityAsync(CountryArtifact artifact, CancellationToken cancellationToken = default)
51+
=> _umbracoCommerceApi.GetCountryAsync(artifact.StoreUdi.Guid, artifact.Code);
52+
5053
public override Task<CountryArtifact?> GetArtifactAsync(GuidUdi? udi, CountryReadOnly? entity, CancellationToken cancellationToken = default)
5154
{
5255
if (entity == null)
@@ -146,11 +149,11 @@ await _umbracoCommerceApi.Uow.ExecuteAsync(
146149
artifact.StoreUdi.EnsureType(UmbracoCommerceConstants.UdiEntityType.Store);
147150

148151
Country? entity = state.Entity != null ? await state.Entity.AsWritableAsync(uow) : await Country.CreateAsync(
149-
uow,
150-
artifact.Udi.Guid,
151-
artifact.StoreUdi.Guid,
152-
artifact.Code,
153-
artifact.Name);
152+
uow,
153+
artifact.Udi.Guid,
154+
artifact.StoreUdi.Guid,
155+
artifact.Code,
156+
artifact.Name);
154157

155158
await entity.SetNameAsync(artifact.Name)
156159
.SetCodeAsync(artifact.Code)

src/Umbraco.Commerce.Deploy/Connectors/ServiceConnectors/UmbracoCommerceCurrencyServiceConnector.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ public override IAsyncEnumerable<CurrencyReadOnly> GetEntitiesAsync(
4747
CancellationToken cancellationToken = default)
4848
=> _umbracoCommerceApi.GetCurrenciesAsync(storeId).AsAsyncEnumerable();
4949

50+
public override Task<CurrencyReadOnly?> GetExistingEntityAsync(CurrencyArtifact artifact, CancellationToken cancellationToken = default)
51+
=> _umbracoCommerceApi.GetCurrencyAsync(artifact.StoreUdi.Guid, artifact.Code);
52+
5053
public override Task<CurrencyArtifact?> GetArtifactAsync(GuidUdi? udi, CurrencyReadOnly? entity, CancellationToken cancellationToken = default)
5154
{
5255
if (entity == null)
@@ -118,12 +121,12 @@ await _umbracoCommerceApi.Uow.ExecuteAsync(
118121
artifact.StoreUdi.EnsureType(UmbracoCommerceConstants.UdiEntityType.Store);
119122

120123
Currency? entity = state.Entity != null ? await state.Entity.AsWritableAsync(uow) : await Currency.CreateAsync(
121-
uow,
122-
artifact.Udi.Guid,
123-
artifact.StoreUdi.Guid,
124-
artifact.Code,
125-
artifact.Name,
126-
artifact.CultureName);
124+
uow,
125+
artifact.Udi.Guid,
126+
artifact.StoreUdi.Guid,
127+
artifact.Code,
128+
artifact.Name,
129+
artifact.CultureName);
127130

128131
await entity.SetNameAsync(artifact.Name)
129132
.SetCodeAsync(artifact.Code)

src/Umbraco.Commerce.Deploy/Connectors/ServiceConnectors/UmbracoCommerceEmailTemplateServiceConnector.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Threading;
44
using System.Threading.Tasks;
@@ -44,6 +44,9 @@ public override string GetEntityName(EmailTemplateReadOnly entity)
4444
public override IAsyncEnumerable<EmailTemplateReadOnly> GetEntitiesAsync(Guid storeId, CancellationToken cancellationToken = default)
4545
=> _umbracoCommerceApi.GetEmailTemplatesAsync(storeId).AsAsyncEnumerable();
4646

47+
public override Task<EmailTemplateReadOnly?> GetExistingEntityAsync(EmailTemplateArtifact artifact, CancellationToken cancellationToken = default)
48+
=> _umbracoCommerceApi.GetEmailTemplateAsync(artifact.StoreUdi.Guid, artifact.Alias);
49+
4750
public override Task<EmailTemplateArtifact?> GetArtifactAsync(GuidUdi? udi, EmailTemplateReadOnly? entity, CancellationToken cancellationToken = default)
4851
{
4952
if (entity == null)
@@ -99,11 +102,11 @@ await _umbracoCommerceApi.Uow.ExecuteAsync(
99102
artifact.StoreUdi.EnsureType(UmbracoCommerceConstants.UdiEntityType.Store);
100103

101104
EmailTemplate? entity = state.Entity != null ? await state.Entity.AsWritableAsync(uow) : await EmailTemplate.CreateAsync(
102-
uow,
103-
artifact.Udi.Guid,
104-
artifact.StoreUdi.Guid,
105-
artifact.Alias,
106-
artifact.Name);
105+
uow,
106+
artifact.Udi.Guid,
107+
artifact.StoreUdi.Guid,
108+
artifact.Alias,
109+
artifact.Name);
107110

108111
await entity.SetNameAsync(artifact.Name, artifact.Alias)
109112
.SetCategoryAsync((TemplateCategory)artifact.Category)

src/Umbraco.Commerce.Deploy/Connectors/ServiceConnectors/UmbracoCommerceEntityServiceConnectorBase.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Runtime.CompilerServices;
44
using System.Threading;
@@ -35,6 +35,15 @@ public abstract class UmbracoCommerceEntityServiceConnectorBase<TArtifact, TEnti
3535

3636
public abstract Task<TArtifact?> GetArtifactAsync(GuidUdi? udi, TEntity? entity, CancellationToken cancellationToken = default);
3737

38+
/// <summary>
39+
/// Gets an existing entity by its identifying properties from the artifact (e.g., alias or code).
40+
/// Used as a fallback when the GUID lookup fails during deployment.
41+
/// </summary>
42+
/// <param name="artifact">The artifact containing identifying properties.</param>
43+
/// <param name="cancellationToken">The cancellation token.</param>
44+
/// <returns>The existing entity if found; otherwise, null.</returns>
45+
public abstract Task<TEntity?> GetExistingEntityAsync(TArtifact artifact, CancellationToken cancellationToken = default);
46+
3847
public override Task<TArtifact> GetArtifactAsync(
3948
TEntity entity,
4049
IContextCache contextCache,
@@ -153,8 +162,12 @@ public override async Task<ArtifactDeployState<TArtifact, TEntity>> ProcessInitA
153162
{
154163
EnsureType(artifact.Udi);
155164

165+
// First try to find by GUID
156166
TEntity? entity = await GetEntityAsync(artifact.Udi.Guid, cancellationToken).ConfigureAwait(false);
157167

168+
// Fallback: try to find by alias/code if GUID lookup failed (handles GUID mismatches during upgrades)
169+
entity ??= await GetExistingEntityAsync(artifact, cancellationToken).ConfigureAwait(false);
170+
158171
return ArtifactDeployState.Create(artifact, entity, this, ProcessPasses[0]);
159172
}
160173
}

src/Umbraco.Commerce.Deploy/Connectors/ServiceConnectors/UmbracoCommerceExportTemplateServiceConnector.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Threading;
44
using System.Threading.Tasks;
@@ -44,6 +44,9 @@ public override string GetEntityName(ExportTemplateReadOnly entity)
4444
public override IAsyncEnumerable<ExportTemplateReadOnly> GetEntitiesAsync(Guid storeId, CancellationToken cancellationToken = default)
4545
=> _umbracoCommerceApi.GetExportTemplatesAsync(storeId).AsAsyncEnumerable();
4646

47+
public override Task<ExportTemplateReadOnly?> GetExistingEntityAsync(ExportTemplateArtifact artifact, CancellationToken cancellationToken = default)
48+
=> _umbracoCommerceApi.GetExportTemplateAsync(artifact.StoreUdi.Guid, artifact.Alias);
49+
4750
public override Task<ExportTemplateArtifact?> GetArtifactAsync(GuidUdi? udi, ExportTemplateReadOnly? entity, CancellationToken cancellationToken = default)
4851
{
4952
if (entity == null)
@@ -95,11 +98,11 @@ await _umbracoCommerceApi.Uow.ExecuteAsync(
9598
artifact.StoreUdi.EnsureType(UmbracoCommerceConstants.UdiEntityType.Store);
9699

97100
ExportTemplate? entity = state.Entity != null ? await state.Entity.AsWritableAsync(uow) : await ExportTemplate.CreateAsync(
98-
uow,
99-
artifact.Udi.Guid,
100-
artifact.StoreUdi.Guid,
101-
artifact.Alias,
102-
artifact.Name);
101+
uow,
102+
artifact.Udi.Guid,
103+
artifact.StoreUdi.Guid,
104+
artifact.Alias,
105+
artifact.Name);
103106

104107
await entity.SetNameAsync(artifact.Name, artifact.Alias)
105108
.SetCategoryAsync((TemplateCategory)artifact.Category)

src/Umbraco.Commerce.Deploy/Connectors/ServiceConnectors/UmbracoCommerceLocationServiceConnector.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ public override string GetEntityName(LocationReadOnly entity)
4444
public override IAsyncEnumerable<LocationReadOnly> GetEntitiesAsync(Guid storeId, CancellationToken cancellationToken = default)
4545
=> _umbracoCommerceApi.GetLocationsAsync(storeId).AsAsyncEnumerable();
4646

47+
public override Task<LocationReadOnly?> GetExistingEntityAsync(LocationArtifact artifact, CancellationToken cancellationToken = default)
48+
=> _umbracoCommerceApi.GetLocationAsync(artifact.StoreUdi.Guid, artifact.Alias);
49+
4750
public override Task<LocationArtifact?> GetArtifactAsync(GuidUdi? udi, LocationReadOnly? entity, CancellationToken cancellationToken = default)
4851
{
4952
if (entity == null)
@@ -97,11 +100,11 @@ await _umbracoCommerceApi.Uow.ExecuteAsync(
97100
artifact.StoreUdi.EnsureType(UmbracoCommerceConstants.UdiEntityType.Store);
98101

99102
Location? entity = state.Entity != null ? await state.Entity.AsWritableAsync(uow) : await Location.CreateAsync(
100-
uow,
101-
artifact.Udi.Guid,
102-
artifact.StoreUdi.Guid,
103-
artifact.Alias,
104-
artifact.Name);
103+
uow,
104+
artifact.Udi.Guid,
105+
artifact.StoreUdi.Guid,
106+
artifact.Alias,
107+
artifact.Name);
105108

106109
await entity.SetNameAsync(artifact.Name, artifact.Alias)
107110
.SetTypeAsync((LocationType)artifact.Type)

src/Umbraco.Commerce.Deploy/Connectors/ServiceConnectors/UmbracoCommerceOrderStatusServiceConnector.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Threading;
44
using System.Threading.Tasks;
@@ -44,6 +44,9 @@ public override string GetEntityName(OrderStatusReadOnly entity)
4444
public override IAsyncEnumerable<OrderStatusReadOnly> GetEntitiesAsync(Guid storeId, CancellationToken cancellationToken = default)
4545
=> _umbracoCommerceApi.GetOrderStatusesAsync(storeId).AsAsyncEnumerable();
4646

47+
public override Task<OrderStatusReadOnly?> GetExistingEntityAsync(OrderStatusArtifact artifact, CancellationToken cancellationToken = default)
48+
=> _umbracoCommerceApi.GetOrderStatusAsync(artifact.StoreUdi.Guid, artifact.Alias);
49+
4750
public override Task<OrderStatusArtifact?> GetArtifactAsync(GuidUdi? udi, OrderStatusReadOnly? entity, CancellationToken cancellationToken = default)
4851
{
4952
if (entity == null)
@@ -91,11 +94,11 @@ await _umbracoCommerceApi.Uow.ExecuteAsync(
9194
artifact.StoreUdi.EnsureType(UmbracoCommerceConstants.UdiEntityType.Store);
9295

9396
OrderStatus? entity = state.Entity != null ? await state.Entity.AsWritableAsync(uow) : await OrderStatus.CreateAsync(
94-
uow,
95-
artifact.Udi.Guid,
96-
artifact.StoreUdi.Guid,
97-
artifact.Alias,
98-
artifact.Name);
97+
uow,
98+
artifact.Udi.Guid,
99+
artifact.StoreUdi.Guid,
100+
artifact.Alias,
101+
artifact.Name);
99102

100103
await entity.SetNameAsync(artifact.Name, artifact.Alias)
101104
.SetColorAsync(artifact.Color)

src/Umbraco.Commerce.Deploy/Connectors/ServiceConnectors/UmbracoCommercePaymentMethodServiceConnector.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ public override string GetEntityName(PaymentMethodReadOnly entity)
4747
public override IAsyncEnumerable<PaymentMethodReadOnly> GetEntitiesAsync(Guid storeId, CancellationToken cancellationToken = default)
4848
=> _umbracoCommerceApi.GetPaymentMethodsAsync(storeId).AsAsyncEnumerable();
4949

50+
public override Task<PaymentMethodReadOnly?> GetExistingEntityAsync(PaymentMethodArtifact artifact, CancellationToken cancellationToken = default)
51+
=> _umbracoCommerceApi.GetPaymentMethodAsync(artifact.StoreUdi.Guid, artifact.Alias);
52+
5053
public override Task<PaymentMethodArtifact?> GetArtifactAsync(GuidUdi? udi, PaymentMethodReadOnly? entity, CancellationToken cancellationToken = default)
5154
{
5255
if (entity == null)
@@ -200,12 +203,12 @@ await _umbracoCommerceApi.Uow.ExecuteAsync(
200203
artifact.StoreUdi.EnsureType(UmbracoCommerceConstants.UdiEntityType.Store);
201204

202205
PaymentMethod? entity = state.Entity != null ? await state.Entity.AsWritableAsync(uow) : await PaymentMethod.CreateAsync(
203-
uow,
204-
artifact.Udi.Guid,
205-
artifact.StoreUdi.Guid,
206-
artifact.Alias,
207-
artifact.Name,
208-
artifact.PaymentProviderAlias);
206+
uow,
207+
artifact.Udi.Guid,
208+
artifact.StoreUdi.Guid,
209+
artifact.Alias,
210+
artifact.Name,
211+
artifact.PaymentProviderAlias);
209212

210213
var settings = artifact.PaymentProviderSettings
211214
.Where(x => !StringExtensions.InvariantContains(_settingsAccessor.Settings.PaymentMethods.IgnoreSettings, x.Key)) // Ignore any settings that shouldn't be transferred

src/Umbraco.Commerce.Deploy/Connectors/ServiceConnectors/UmbracoCommercePrintTemplateServiceConnector.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Threading;
44
using System.Threading.Tasks;
@@ -45,6 +45,9 @@ public override string GetEntityName(PrintTemplateReadOnly entity)
4545
public override IAsyncEnumerable<PrintTemplateReadOnly> GetEntitiesAsync(Guid storeId, CancellationToken cancellationToken = default)
4646
=> _umbracoCommerceApi.GetPrintTemplatesAsync(storeId).AsAsyncEnumerable();
4747

48+
public override Task<PrintTemplateReadOnly?> GetExistingEntityAsync(PrintTemplateArtifact artifact, CancellationToken cancellationToken = default)
49+
=> _umbracoCommerceApi.GetPrintTemplateAsync(artifact.StoreUdi.Guid, artifact.Alias);
50+
4851
public override Task<PrintTemplateArtifact?> GetArtifactAsync(GuidUdi? udi, PrintTemplateReadOnly? entity, CancellationToken cancellationToken = default)
4952
{
5053
if (entity == null)
@@ -93,11 +96,11 @@ await _umbracoCommerceApi.Uow.ExecuteAsync(
9396
artifact.StoreUdi.EnsureType(UmbracoCommerceConstants.UdiEntityType.Store);
9497

9598
PrintTemplate? entity = state.Entity != null ? await state.Entity.AsWritableAsync(uow) : await PrintTemplate.CreateAsync(
96-
uow,
97-
artifact.Udi.Guid,
98-
artifact.StoreUdi.Guid,
99-
artifact.Alias,
100-
artifact.Name);
99+
uow,
100+
artifact.Udi.Guid,
101+
artifact.StoreUdi.Guid,
102+
artifact.Alias,
103+
artifact.Name);
101104

102105
await entity.SetNameAsync(artifact.Name, artifact.Alias)
103106
.SetCategoryAsync((TemplateCategory)artifact.Category)

src/Umbraco.Commerce.Deploy/Connectors/ServiceConnectors/UmbracoCommerceProductAttributePresetServiceConnector.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using Umbraco.Commerce.Core.Api;
44
using Umbraco.Commerce.Core.Models;
@@ -47,6 +47,9 @@ public override string GetEntityName(ProductAttributePresetReadOnly entity)
4747
public override IAsyncEnumerable<ProductAttributePresetReadOnly> GetEntitiesAsync(Guid storeId, CancellationToken cancellationToken = default)
4848
=> _umbracoCommerceApi.GetProductAttributePresetsAsync(storeId).AsAsyncEnumerable();
4949

50+
public override Task<ProductAttributePresetReadOnly?> GetExistingEntityAsync(ProductAttributePresetArtifact artifact, CancellationToken cancellationToken = default)
51+
=> _umbracoCommerceApi.GetProductAttributePresetAsync(artifact.StoreUdi.Guid, artifact.Alias);
52+
5053
public override async Task<ProductAttributePresetArtifact?> GetArtifactAsync(GuidUdi? udi, ProductAttributePresetReadOnly? entity, CancellationToken cancellationToken = default)
5154
{
5255
if (entity == null)
@@ -118,11 +121,11 @@ await _umbracoCommerceApi.Uow.ExecuteAsync(
118121
artifact.StoreUdi.EnsureType(UmbracoCommerceConstants.UdiEntityType.Store);
119122

120123
ProductAttributePreset? entity = state.Entity != null ? await state.Entity.AsWritableAsync(uow) : await ProductAttributePreset.CreateAsync(
121-
uow,
122-
artifact.Udi.Guid,
123-
artifact.StoreUdi.Guid,
124-
artifact.Alias,
125-
artifact.Name);
124+
uow,
125+
artifact.Udi.Guid,
126+
artifact.StoreUdi.Guid,
127+
artifact.Alias,
128+
artifact.Name);
126129

127130
await entity.SetAliasAsync(artifact.Alias)
128131
.SetNameAsync(artifact.Name)

0 commit comments

Comments
 (0)